I am using CakePHP 1.3 and trying to enable cache for view pages, cache system works fine and caches all pages. But when we add a new post (insert new record to database) or edit an old one (update a record of the table) CakePHP deletes all cached pages, not just the edited page!
app/config/core.php :
Cache::config('default', array('engine' => 'File','duration' => 8640000));
app/controllers/articles_controller.php :
var $helpers = array('Cache');
var $cacheAction = array(
'view' => array('duration' => 8640000),
'latest' => array('duration' => 8640000),
);
How can I tell Cake to delete just the cached version of changed page and not all cached pages?
This it actually pretty hard, so I can't just give you a piece of code to solve this. You need to edit the actual cake files in the lib folder that manage caching. Note: this is super not recommended by the cake people. However the lib/Cake/Cache/Engine/FileEngine.php is the file that has the operations of the file engine. You seem interested in the delete function:
/**
* Delete a key from the cache
*
* #param string $key Identifier for the data
* #return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/
public function delete($key) {
if ($this->_setKey($key) === false || !$this->_init) {
return false;
}
$path = $this->_File->getRealPath();
$this->_File = null;
//#codingStandardsIgnoreStart
return #unlink($path);
//#codingStandardsIgnoreEnd
}
Also, instead of editing the core cake files you could add your own file engine and use parted of the cake engine by moving the code and just extending the code there (that's totally cool in open source).
Its also possible that by reading the code used to implement the file caching engine you will find your actual solution. Good Luck.
Related
I understand that we can cache an action or view page in CakePHP 2.0. Refer to this link http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html.
class PostsController extends AppController {
public $helpers = array('Cache');
}
public $cacheAction = array(
'view' => 36000,
'index' => 48000
);
However, it seems that CakePHP 3.0 has removed helper(http://book.cakephp.org/3.0/en/core-libraries/caching.html). Is there any other way in CakePHP 3.0 I can cache the view page. For example, I have a index view/action. And I would like to cache that page. Thanks.
Is there any other way in CakePHP 3.0 I can cache the view page.
Not without developing something yourself. Like for example saving the rendered content to a file in callback for Dispatcher.afterDispatch event and then checking for the file in callback for Dispatcher.beforeDispatch event and returning the cached response.
Better to use you something like Varnish which is more suited for the job.
I am using CakePHP 3 in my project. I am still learning new things as I go. Today I had a requirement to use CakePHP cache to cache data that I retrieve from the database. Every time I load a page that returns data from the database, takes around 30 to 40 seconds.
So I went ahead and configured cache in my controller, which significantly improved page loading from 30 sec to less then 4 seconds.
Now, what I want to do is set duration of the cache to clear itself after 1 hour to refresh new data that is stored in the database.
This is my code that does the caching:
if (!($custstoredata = Cache::read('custstoredata'))) {
# Code logic
Cache::write('custstoredata', $customers);
$this->set('data',$customers);
} else {
$this->set('data', Cache::read('custstoredata'));
}
After doing some research online, I found that I can use Cache::set to configure duration so I went a ahead and added Cache::set(array('duration' => '+1 hour')); in my if statement, but when I load the page in browser, I get this error:
Error: Call to undefined method Cake\Cache\Cache::set()
I am not sure what is the right way to set caching duration in controller real time when cache is written to a file.
I think I answered my own question.
I added below cache config in app.php file:
'reports_seconds' => [
'className' => 'File',
'path' => CACHE,
'serialize' => true,
'duration' => '+60 seconds',
]
Once I added above code, I modified my if statement with below code that fixed the problem.
if (!($custstoredata = Cache::read('custstoredata'))) {
# Code logic
Cache::write('custstoredata', $customers, $config = 'reports_seconds');
$this->set('data',$customers);
} else {
$this->set('data', Cache::read('custstoredata'));
}
I have numerous sites and its becoming a nuisance keeping them all up to date, so I would ideally like to compile a list where I can display the version of each website automatically. So I can see at the drop of a hat which ones needs updated and so on.
I have remote access to all off their databases, I had thought about querying the wp_options table for the DB Version but that isn't specific enough when it comes to smaller version updates as far as I am aware.
Any thoughts?
Here's a demo plugin
<?php
/** Plugin Name: My JSON data **/
add_filter( 'query_vars', function( $qv ){
$qv[] = 'mydata';
return $qv;
});
add_action( 'template_redirect', function(){
$input = get_query_var( 'mydata' );
$secret = 'abcdefg'; // Edit this
if( ! empty( $input ) )
{
if( $secret === $input )
{
$data = array(
'version' => $GLOBALS['wp_version'],
'foo' => 'bar',
);
wp_send_json_success( $data );
}
else
{
wp_send_json_error();
}
}
} );
where example.com/?mydata=abcdefg gives
{"success":true,"data":{"version":"3.8.1","foo":"bar"}}
and example.com/?mydata=wrong shows:
{"success":false}
I wouldn't recommend trying to bridge a system to check WordPress, espiecally since the WordPress core since 3.7.1 comes with this functionality.
WordPress 3.7.1+ Auto Updates, so it would be best to upgrade all your WordPress sites - this would also be a great idea for security purposes.
What you might want to consider is removing any redundant plugins and have a plan for updating those plugins every few months too.
3rd-party plugins are usually the reason a site is vulnerable, more so than the core of WordPress. Fight the fire before it becomes a fire in the first place! Use less plugins or keep on top of them.
I'm using CakePHP's Media view to force file downloads. My code is pretty much exactly like the example provided in the cookbook, which I'll paste here for your convenience:
<?php
class ExampleController extends AppController {
public function download () {
$this->viewClass = 'Media';
// Download app/outside_webroot_dir/example.zip
$params = array(
'id' => 'example.zip',
'name' => 'example',
'download' => true,
'extension' => 'zip',
'path' => APP . 'outside_webroot_dir' . DS
);
$this->set($params);
}
}
In the database, I have a field that keeps track of how many times the file was downloaded. I'm looking for a way to make sure that this number is as accurate as possible, so if a user's download gets cancelled or times out, the number does not increment. Is there some way for CakePHP's Media view to report that the download was, indeed, successful?
Detecting when a file has finished downloading is no easy task. This is something that would be done on the client side with javascript, but browsers do not give you any hooks for that.
There is a pretty clever solution here (setting a cookie and then looking for it with javascript), but it only tells you when the download has started.
What is the best way to spit out XML for webservice in CakePHP?
I have it like the following but it's displaying an empty page.
Sample call /service/config.xml
In Controller
var $helpers = array('Xml');
function config() {
$this->autoRender = false;
$obj = array("response" => array("config" => array(...)));
$objXmlHelper = new XmlHelper();
$objXml = $objXmlHelper->header();
$objXml .= $objXmlHelper->serilize($obj);
echo $objXml;
}
That gives empty page. However, if I echo json_encode($obj); that actually prints out json.
Thanks,
Tee
You probably have an error in your code. My guess is you are not including the XML helper.
Check you CakePHP (app/tmp/logs/) and PHP logs. In addition you may need to set the DEBUG flag to a higher level ( i.e. > 0).
I'd also recommend considering moving such things to a model. Web Services are typically data access layers and that belongs in the Model.