codeigniter output cache doesn't work? - codeigniter

I'm using $this->output->cache(n) to cache webpage, but i cannot figure out how does it work.. I didn't find any cache files under system/cache folder...and also after I edit the page and show it again, the content changes, so it seems that the page is not really cached. Can anyone give a help? (i'm using phil's template lib)
my code:
function show(){
$this->output->cache(5);
$this->load->model('page_model');
$var = $this->uri->segment(3, 0); //get About page
$row = $this->page_model->getPage($var);
$this->template->title('about')
->set_layout('default')
->set_partial('styles', 'css')
->set('data', $row->body)
->build('about');
}
THANKS!

Two things, as outlined in the documentation:
Warning: Because of the way CodeIgniter stores content for output, caching will only work if you are generating display for your controller with a view.
Perhaps not using the "native" views is an issue?
Additionally:
Note: Before the cache files can be written you must set the file permissions on your application/cache folder such that it is writable.
Are you sure your application/cache directory has the correct permissions?

Debug this file and check it's actually writing the cache:
system/core/Output.php
// Do we need to write a cache file? Only if the controller does not have its
// own _output() method and we are not dealing with a cache file, which we
// can determine by the existence of the $CI object above
if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))
{
$this->_write_cache($output);
}
This works well for me:
function _output($content) {
// Load the base template with output content available as $content
$data['content'] = &$content;
$this->output->cache(600);
$output = $this->load->view('base', $data, true);
$this->output->_write_cache($output);
echo $output;
}

Are you sure your application/cache directory has the correct permissions?
you you to directories application/cache in cpanel , permissions become 777 is OK

Related

Downloading files which were stored using the storage facade in laravel 5.4

I've noticed that the method Storage::download($path) is not available until Laravel 5.6. I would rather not create symbolic links since this appears to me to defeat the purpose of using the storage facade, might as well save the file in the assets folder (not sure how correct I am in saying this).
My question is, how can I download a file that I have saved using the storage facade and not make the file publicly visible through a URL link?
I use this:
$path = "/path/to/file/";
$filename = "my_file.pdf"
return response(Storage::disk('local')->get($path.$filename), 200)
->header('Content-Type', Storage::disk('local')
->mimeType($path.$filename)
);
Edit:
If to store you use:
$path=$request->file('file')->store('file');
that's going to store the file in the storage/app/file folder, with a name created by laravel. For example:
storage/app/file/7K5gIZvRVWbdBedRXEyVm5X1Ubz61vJZguFmERlT.jpeg
(Make sure the file has been stored).
And in DB you must save (I do not know how you're doing this, but it's the 'file' folder and the file name created by laravel):
file/7K5gIZvRVWbdBedRXEyVm5X1Ubz61vJZguFmERlT.jpeg
So, to download you have to make a route:
Route::get('/download', 'DownloadController#downloadFile')->name('download-file');
And a Controller method:
public function downloadFile()
{
     $path = // get the DB field
     return response(Storage::get($path), 200)
         ->header( 'Content-Type', Storage::mimeType($path) );
}
And you can add a link in a view:
<a href="{!! route('download-file') !!}" download>Download the file</a>

Checking folder already existed and if not create a new folder by id in laravel

i want to store my image to a specific folder and the folder will named by page id. For example if Page id=1, the folder location should be public/pages/page_id/image_here.
If the folder are not existed yet the system will generate and named with their page id.
$id=1;
$directoryPath=public_path('pages/' . $id);
if(File::isDirectory($directoryPath)){
//Perform storing
} else {
Storage::makeDirectory($directoryPath);
//Perform storing
}
But i having error that "mkdir(): Invalid argument".
Can i know why it happen?
And after my research some people say the folder name should based with id+token so intruder cannot search image based on id, is there possible to achieve?
I had the same problem, but when I use File instead of Storage it works!
$id=1;
$directoryPath=public_path('pages/'.$id);
//check if the directory exists
if(!File::isDirectory($directoryPath)){
//make the directory because it doesn't exists
File::makeDirectory($directoryPath);
}
//Perform store of the file
Hope this works!
When you use Storage facade, it uses local disk as default which is configured to work with storage_path().
So, if you want to create directory in public directory, use File::makeDirectory which is just simple wrapper for mkdir() with additional options or use mkdir() directly:
File::makeDirectory($directoryPath);
mkdir($directoryPath);
For basic Laravel file system the syntax is :
At very top under namespace write:
use File;
Then in your method use:
$id=1;
$directoryPath=public_path('pages/' . $id);
if(File::isDirectory($directoryPath)){
//Perform storing
} else {
File::makeDirectory($directoryPath, 0777, true, true);
//Perform storing
}

Laravel s3 check if directory exists.

How would I check with Laravel storage if a directory exists?
In the documentation there is only documented how to check if a file exists.
Storage::disk('local')->exists('file.jpg');
https://laravel.com/docs/5.3/filesystem#retrieving-files
None of the answers here seems to answer specifically to check if a particular folder exists in S3. This is what I use and it works:
Storage::disk('s3')->exists('FOLDER_NAME')
The above will return a boolean. The above check works for both folders and filenames.
In Laravel 5.7 use:
The has() method is used to determine if a given file exists on the disk:
$exists = Storage::disk('s3')->has('file.jpg');
Try to get directories list in a parent directory and check if the directory you're looking for is in an array:
in_array('directoryYoureLookingFor', Storage::disk('s3')->directories('parentDirectory'));
I've just checked and this solution works in Laravel 5.3.
You can using isDirectory method:
if (File::isDirectory($filename))
{
echo "Yes. It's a directory.";
}
I have also faced same issue many time for check file is exists or not on S3 with Laravel. I am working on Laravel 7.* and exists() and has() functions not providing proper response when file is uploaded on sub directory of S3 bucket. I have write a function which is working perfectly for me.
public static function fileExistsS3($directoryOnS3, $image) {
$directoryOnS3 = Config::get('custom.AWS_PUBLIC_ENDPOINT').$directoryOnS3;
$exists = #getimagesize($directoryOnS3.$image);
if(isset($exists) && is_array($exists)) {
return true;
} else {
return false;
}
}
It will return true if file available on S3 else it will return false.
You can do the following thing i.e u can get the filename and compare it with the file name urtrying to upload if it exists give a maessage else u can insert
$file = Storage::disk('local')->get($filename);
if($file){
echo "file exist";
} else {
Storage::disk('local')->put($filename,FILE::get($file));
}

Use add_package_path for Code Igniter controllers

I am trying to use $this->load->add_package_path to add a new sub-application to my CI app. I can see how to use this for views and such: just put
$this->load->add_package_path("/mypackage");
in the controller ctor. Unfortunately, that doesn't help, because I want to find controllers from the package path: it seems like a chicken-and-egg problem. Is there somewhere else I can put a add_package_path call (such as index.php)?
Figured it out by tracing through CI. Turns out you can't do this. You can put your own controllers in a subdirectory of /application/controllers, but you cannot put them someplace else: in particular, as http://codeigniter.com/user_guide/libraries/loader.html implies,
These elements can be libraries (classes) View files, Helpers, Models, or your own files.
"Your own files" not including controllers. I ended up being able to get it to look to the ENVIRONMENT setting in addition to APPPATH by making changes to CodeIgniter.php and Router.php. I don't like making this kind of change, however, so I backed out the changes. I'll put this here in case somebody else can benefit from it.
Router.php change:
function _validate_request($segments)
{
...
// Does the requested controller exist in the root folder?
if (file_exists(APPPATH.'controllers/'.$segments[0].'.php')
|| file_exists(ENVIRONMENT.'/controllers/'.$segments[0].'.php')) // New bit here
{
return $segments;
}
....
}
CodeIgniter.php change, 'round about line 246:
if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'))
{
// New bit here
if ( ! file_exists(ENVIRONMENT.'/controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'))
{
show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
}
include(ENVIRONMENT.'/controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
} else {
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
}

View files via links in Zend MVC

In my app I have a module named "client". I wish to create a sub directory "statements" and below that "accounts" then "account_123" and within this directory the pdfs representing statements for clint 123.
Structure client then statements then accounts then acount_XXX and the pdf files.
The problem
statement_1.pdf?
Being MVC I am making little progess.
I moved the structure to public and it almost wotk except I could not retrieve dynamically the hostname i.r. www.hostnam.com/client/statement....
I know this is a security issue so I have moved the directory back yo below the client module.
Any help will be appreciayed.
TIA Ephraim
As far as I know you can't place a direct link to a file placed under 'application' director (because of security issues as you already wrote), so one of possible solution is to make an action which read the content of a file and return it in a response object.
When user click a link to this action user get a window to open/save provided file.
Example:
public function exampleAction() {
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
/* ... */
$file = "FILENAME WITH_PATH";
$response = $this->getResponse();
$response->setHeader('Cache-Control', 'public', true);
$response->setHeader('Content-Description', 'public', true);
$response->setHeader('Content-Disposition', 'attachment; filename=' . FILENAME, true);
$response->setHeader('Content-Type', FILETYPE, true);
$response->setHeader('Content-Transfer-Encoding', 'binary', true);
$response->setHeader('Content-Length', filesize($file), true);
$response->setBody(file_get_contents($file));
}
I put in above code some constants because its values depends on your application.

Resources