How to clear compiled view for specific blade template - laravel-5

PHP artisan view:clear command clears whole compiled views in an application.
How to clear compiled output for specific view.

Simple answer: Write your own command.
How do i start?
First of all, You must know that compiled views have different names than the original blade views.
What names do they have?
Laravel calls sha1() in the full file path. So for example. The compiled file name of layouts/app.blade.php (comes with default installation).
in versions less than 5.2 md5() is used instead of sha1(),
5.2, 5.3 => sha1()
5.1, 5.0, 4.2, 4.1, 4.0 => md5()
Assuming your version is >= 5.2
sha1('C:\xampp\htdocs\myapp\resources\views/layouts/app.blade.php');
So file name will be 9407584f16494299da8c41f4ed65dcb99af82ae2.php
How do i do that then?
Create new command that takes filename as an argument.
Add views path for filename in fire() function. As i showed you before C:\xampp\htdocs\myapp\resources\views (view full path) + /layouts/app.blade.php (filename)
$path = 'C:\xampp\htdocs\myapp\resources\views' . '/layouts/app.blade.php';
$path = sha1($path) . '.php'; To get the compiled filename.
Check if filename exists in compiled views dir
Delete file if exists
The command you'll have something like,
Note: If you have different view paths (Changed defaults), You must
make changes on my code below.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use RuntimeException;
class RemoveCompiled extends Command
{
protected $signature = 'view:clearOne {file}';
protected $description = 'Remove one compiled view!';
public function handle()
{
$path = sha1($this->laravel['config']['view.paths'][0] . '/' . $this->argument('file'));
$f = $this->laravel['config']['view.compiled'] . '\\'. $path . '.php';
if(!file_exists($f))
return; //do whatever you want
if(unlink($f))
echo "File deleted!";
}
}
Calling: php artisan view:clearOne layouts/app.blade.php

Related

Laravel putFileAs with External URL not working

Trying to save an external URL image, to my s3.
But when I use code below, it returns error.
$contents = file_get_contents($url);
$filename = Str::slug($findproduct->title)."-".uniqid().".".$extension;
Storage::disk('s3')->putFileAs('product', $contents, $filename, ['visibility' => 'public']);
Here's error:
fopen() expects parameter 1 to be a valid path, string given
fopen() is the first function called by putFileAs API Docs.
It attempts to open the File supplied as parameter 2 to putFileAs(), in your case this is $contents. (FWIW, newer versions of Laravel also accept a string as a file path here)
It expects this to be either a File or UploadedFile object.
file_get_contents() returns a string instead.
Try using this instead:
$contents = new File($url);

How to minify view HTML in Codeigniter 4 (CI 4)

I know we can minify HTML in CI3 through the hook but in CI 4
I have done it by adding a minify function before return on every method.
minifyHTML(view('admin/template/template',$this->data));
Any other way I can do it without using the minify function everywhere?
I also figure out another solution which is to add a template function in BaseConroller which renders all the views. but I have already used view() in many places in the project and its not feasible for me but can be work for others.
In CodeIgniter4 You can use Events to Minify the output (Instead of using Hooks like what we did in CodeIgniter3) , by adding the following code inti app/Config/Events.php file
//minify html output on codeigniter 4 in production environment
Events::on('post_controller_constructor', function () {
if (ENVIRONMENT !== 'testing') {
while (ob_get_level() > 0)
{
ob_end_flush();
}
ob_start(function ($buffer) {
$search = array(
'/\n/', // replace end of line by a <del>space</del> nothing , if you want space make it down ' ' instead of ''
'/\>[^\S ]+/s', // strip whitespaces after tags, except space
'/[^\S ]+\</s', // strip whitespaces before tags, except space
'/(\s)+/s', // shorten multiple whitespace sequences
'/<!--(.|\s)*?-->/' //remove HTML comments
);
$replace = array(
'',
'>',
'<',
'\\1',
''
);
$buffer = preg_replace($search, $replace, $buffer);
return $buffer;
});
}
});
see https://gitlab.irbidnet.com/-/snippets/3
You need the extend your core system classes to be able to do that in a system wide scope.
Every time CodeIgniter runs there are several base classes that are initialized automatically as part of the core framework. It is possible, however, to swap any of the core system classes with your own version or even just extend the core versions.
Two of the classes that you can extend are these two:
CodeIgniter\View\View
CodeIgniter\View\Escaper
For example, if you have a new App\Libraries\View class that you would like to use in place of the core system class, you would create your class like this:
The class declaration must extend the parent class.
<?php namespace App\Libraries;
use CodeIgniter\View\View as View;
class View implements View
{
public function __construct()
{
parent::__construct();
}
}
Any functions in your class that are named identically to the methods in the parent class will be used instead of the native ones (this is known as “method overriding”). This allows you to substantially alter the CodeIgniter core.
So in this case you can look at your system view class and just change it to return the output already compressed.
In your case You might even add an extra param so that the view function can return the output either compressed or not.
For more information about extending core classes in CodeIgniter 4 read this:
https://codeigniter.com/user_guide/extending/core_classes.html#extending-core-classes
In CodeIgniter 4, you can minify the HTML output of your views by using the built-in output compression library.
First, you need to enable output compression in your application's configuration file, which is located at app/Config/App.php.
Then, you need to set the compression level. You can set the compression level by changing the value of compress_output option. The possible values are:
0 : Off (Do not compress the output)
1 : On (Compress output, but do
not remove whitespace)
2 : On (Compress output, and remove
whitespace)
Finally, you need to load the Output Library in your controller, before the output is sent to the browser. You can load it using the following line of code:
$this->load->library('output');

How can my command pass through optional arguments to another Artisan command?

(Updated question to show that it's not like the linked questions)
I wrote a Laravel command (shown in its entirety below) that basically is a wrapper for Dusk so that I can be sure to call certain other functions beforehand. (Otherwise, I inevitably would forget to reset my testing environment.)
It works perfectly when I run php artisan mydusk.
namespace App\Console\Commands;
class DuskCommand extends BaseCommand {
protected $signature = 'mydusk {file?} {--filter=?}';
protected $description = 'refreshAndSeedTestingDb, then run Dusk suite of tests';
public function handle() {
$this->consoleOutput($this->description);
$resetTestingEnv = new ResetTestingEnv();
$resetTestingEnv->refreshAndSeedTestingDb();
$this->consoleOutput('refreshAndSeedTestingDb finished. Now will run Dusk...');
$file = $this->argument('file');//What to do with this?
return \Artisan::call('dusk', ['--filter' => $this->option('filter')]);
}
}
As you can see, I've already read these docs and understand how to write the $signature to accept optional arguments.
My goal is to be able to sometimes run php artisan mydusk and also be able to optionally add arguments such as when I might want to call something like php artisan mydusk tests/Browser/MailcheckTest.php --filter testBasicValidCaseButtonClick (which would pass the tests/Browser/MailcheckTest.php --filter testBasicValidCaseButtonClick arguments through to the normal dusk command).
How can I edit the last 2 lines of my handle() function so that $file gets passed to dusk?
You can have a look at these links too it might help you.
Stack Answer 1
Stack Answer 2
I was surprised to learn from my experiments that my original function actually works as I desired, and I can remove the inert line ($file = $this->argument('file');).
Passing the file argument through \Artisan::call() actually does not seem to be necessary at all.
#fubar's answer seems to have made the same mistaken assumptions as I originally did.
As #Jonas Staudenmeir hinted in a comment, Laravel\Dusk\Console\DuskCommand uses arguments from $_SERVER['argv'].
Use signature without '--' to provide arguments
return \Artisan::call('dusk', ['file' => $file , '--filter' => $this->option('filter')]);
The documentation does give an example but it is not stated clearly (it assumes you followed all the statements in the sections above)
For the signature below
protected $signature = 'email:send {user} {--queue}';
It gives (on very far below) this example as calling an Artisan command from other commands
public function handle()
{
$this->call('email:send', [
'user' => 1, '--queue' => 'default'
]);
}
https://laravel.com/docs/5.6/artisan#calling-commands-from-other-commands

Codeigniter set_output function not working with image

I am trying to get the image as output, but it seems like set_output() function is not working properly with content type jpeg
My Code is given below...
$image = file_get_contents('assets/images/ThinkstockPhotos-145054512_small.jpg');
$this->output->set_content_type('jpeg')->set_output($image);
When I replace the image with a plain text file, in that case, it shows me the correct output
$file = file_get_contents('assets/images/test.txt');
$this->output->set_content_type('text')->set_output($file);
I have change content type from set_content_type('jpeg') to set_content_type('jpg') and set_content_type('gif') but stil it does not work and not show me on output.
What output I am getting now is shown in screenshot given below.
I was able to replicate the issue on my localhost setup only when I provided file_get_contents either a (1) bad path or (2) a non-existent image. I think you need to provide a full path to the image as with any directory/file related operation.
Try using FCPATH that is where you index.php lies and I assume your assets/ folder as well.
public function index() {
$file = FCPATH . 'assets/images/ThinkstockPhotos-145054512_small.jpg';
if (!is_file($file)) {
exit('File not found!');
}
$image = file_get_contents($file);
$this->output->set_content_type('jpeg')->set_output($image);
}
Note: if you get File not found! then assure that the file exists in /htdocs/assets/... where /htdocs/index.php is your main CI file

Laravel move uploaded file

It is working good for full path like this
$file=$request->file('file');
$file->move('C:\xampp\htdocs\modo\images',$file->getClientOriginalName());
But i cant understand why it doesnt for root folder path :
$file->move('\modo\images',$file->getClientOriginalName());
You need to use base_path() method. This method returns the fully qualified path to the project root:
So in your case try the below code:
$file = $request->file('file');
$file->move(base_path('\modo\images'), $file->getClientOriginalName());
and if you want to return the public directory then use:
$path = public_path();
For more info read Laravel helper functions
You need to do it this way:
$file->move(base_path('\modo\images'),$file->getClientOriginalName());

Resources