Clear All Query Cache in Yii - php

Following is the configuration Code for my DB cache in Yii
'dbcache'=>array(
'class'=>'system.db.CDbConnection',
'connectionString'=>'sqlite:/' . str_replace('\\','/',str_replace('C:\\','',getcwd()).'/protected/data/cache.db'),
),
And the following is my code for getting the record set and setting in the cache:
$recordset = Table1::model ()->cache(0)->find ( "primary_id=:id", array (":id" => $id) );
I have used 0 for the cache duration because I need to make it for infinite period.
Now I need to refresh my Cache. on some condition. How can I refresh the query Cache in Yii if its duration is infinite. Please help :)

First of all, setting the value as 0 doesn't mean that you are setting for Infinite Period. It does mean that you have simply Disabled the cache.
Refer the Code: Class Reference - CActiveRecord
If you want to refresh the Schema Cache, use the code as Yii::app()->schema->refresh()

Related

Fat Free Framework dynamic cache expiration

I am trying to improve my Fat Free Framework web app by using cached queries, wherever possibile.
I am wondering whether it would make any sense to try caching even queries involving data which changes quite ofter or so, by applying a little 'trick'.
IE, tipically you wouldn't cache this:
SELECT * FROM tasks WHERE status = 'open';
But what if I could instead cache it indefinitely and have external factors clear its cache when a specific event (e.g. a task is closed, in this case) occurs?
If this is my query:
$tasks = $this->db->exec(
array(
"SELECT *
FROM tasks
WHERE status = 'open'"
),
NULL,
86400
);
is there any possible way by which I can force its 24h-long cached version to expire earlier?
Yes:
Solution #1:
Clear the whole cache content: $f3->clear('CACHE')
Solution #2:
Tag your cached query:
$tasks = $this->db->exec(
array(
"SELECT *
FROM tasks
WHERE status = 'open'"
),
NULL,
[86400,'mytag'] // << tag defined here
);
Then you can clear only the cache content matching this tag:
Cache::instance()->reset('mytag');

Magento 2 - how to skip the cache when getting system config value?

I'm trying to get config values using:
$this->_scopeConfig->getValue(
$config_path,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
& it returns the cached value.
Is there any way to make it skip the cache without disabling it?
*I want the cache to be enabled but still bypass it for this value only.
**I also don't want to always clear the cache programmatically before getting it.
-- Any idea?
What you basically need is to query the database directly.
So Inject a Magento\Config\Model\ResourceModel\Config\Data\CollectionFactory in your class.
Then you can query the database :
$collection = $collectionFactory->create();
$collection->addScopeFilter($scope, $scopeId, $section)
The $section is the path,
$scopeId the id of the store or website depending on the scope
& $scope is either "stores" or "website" or "default".

CakePhp sessions clear almost instantly, but only sometimes

I have adopted a CakePhp 2 project. We get to the project from another project, linking to the CakePhp project with a "token" and a conference ID as a parameter in the URL. Using that token, we authorize the user, and using the conference ID get the information from the database. The session value "auth" is set to true.
We have it running on 2 "platforms" locally on my system using a vagrant machine, and on a production server. Locally the session value dies really quick and at random times. On the production server not as often, but the issues we have where Ajax calls don't seem to do what are expected, we believe are being caused by a similar issue. We have many different projects, all Laravel, with zero issues where the session values clear. This issue is strictly with the CakePhp project.
All the authentication magic happens in the beforeFilter method. The code:
public function beforeFilter() {
$session = new CakeSession();
/**
*
* We will check if the current user is authorized here!
*
*/
// If the visitor is coming for the first time, there should be a parameter in
// the URL that is the auth code to check against the database.
if ( ( isset($_GET['conf']) && is_numeric($_GET['conf']) ) && isset($_GET['token']) ) {
$getConference = ClassRegistry::init('Conference')->find('first', ["conditions" => ["conference_id"=>$_GET['conf'] ]]);
$checkToken = ClassRegistry::init('User')->find('first', ["conditions" => ["remember_token"=>$_GET['token'] ]]);
if ($getConference && $checkToken) {
$checkToken['User']['remember_token'] = $this->generateToken();
if ( ClassRegistry::init('User')->save( $checkToken ) ) {
$session->write('auth', true);
$session->write('conferenceId', $_GET['conf']);
$this->redirect('/');
}
}
else {
$session->write('auth', false);
$session->write('conferenceId', null);
}
}
if (! $session->read('auth') || $session->read('conferenceId') == null ) {
echo "No permission!";
exit;
}
}
At the top of the controller:
App::uses('CakeSession', 'Model/Datasource');
When the URL parameters are present, it traps them, does the work, and redirects to the home route without the parameters.
$this->generateToken();
Creates a new token, and overwrites the old one in the database.
There are 2 main controllers. The controller with this code is the main projects controller. The only time it is really hit is the first time you go to the project, and we hit the index method. From there everything else is AJAX calls to the other controller. There is one link, a "home" type link that will hit that index method.
Sometimes these Ajax calls stop working, and clicking that home link will output "No Permission" instead of the expected html in the container the Ajax call outputs too.
Steps to troubleshoot led me to putting this beforeFilter method on the top of the second controller. Now, randomly I'll get no permission. Sometimes, when I'm on the main project that links to this CakePhp project, I click that link, I get no permission right off the bat.
I found this page: cakephp takes me to login page on multiple request and have tried to set the session details like this:
Configure::write('Session', array(
'defaults' => 'php',
'timeout' => '300' // <- added this element
));
And I have tried:
Configure::write('Session.timeout', '300');
Additionally, I have tried cookieTimeout in both of those cases.
I've also tried
Configure::write('Security.level', 'low');
and included
Configure::write('Session.autoRegenerate', true);
In any order, any of these cause the session to bomb out immediately. I get "No permission on page load, and never get anywhere.
The code for this project is honestly crap. The developer who wrote it had mistakes and errors all over the place. On top of that, we are a Laravel shop. We are just trying to keep the project limping along until sometime in the future when we can nuke it from orbit. So we just need to get this working. Any thoughts on what could be causing this? Any other details I am forgetting to include that would help troubleshoot this issue?
Thanks
Reading & writing session data
You can read values from the session using Set::classicExtract() compatible syntax:
CakeSession::read('Config.language');
$key should be the dot separated path you wish to write $value to:
CakeSession::write('Config.language', 'eng');
When you need to delete data from the session, you can use delete:
CakeSession::delete('Config.language');
You should also see the documentation on Sessions and SessionHelper for how to access Session data in the controller and view.

Laravel 5: To cache or use sessions for building a site-wide banner?

I'm building a feature into a Laravel 5 app that will allow you to set the content of a status banner that will display across the top of the page. We will be using this banner both to display page-specific things (status messages, etc) and site-wide announcements (every user sees the same thing, banner stays the same for awhile).
Right now, I've implemented this by using Laravel sessions to allow banners to be added by calling a helper method from any controller or middleware:
// Call set_banner from in a controller or middleware (for persistent banners)
function set_banner($banner_text, $banner_class, $banner_persistant=false, $replace=false)
{
$banners = session()->get('banners', []);
// Create new banner
$banner = [
'text' => $banner_text,
'type' => $banner_class,
'persistent' => $banner_persistant
];
// Only put banner in array if it's not already there
if( !in_array($banner, $banners) ) {
// Either override existing banners, or add to queue
if( !$replace ) session()->push('banners', $banner);
else session()->put('banners', [$banner]);
}
}
// Called by default in the master.blade.php template
function get_banners()
{
$banners = session()->pull('banners', Array());
foreach( $banners as $banner ) {
// Print out each banner
print '<div class="col-md-12"><div class="text-center alert alert-block alert-'.$banner['type'].'">';
print $banner['text'];
print '</div></div>';
// Push back into the session if banner is marked as persistent
if ( $banner['persistent'] ) session()->push( 'banners', $banner );
}
}
Banners are created in controllers or middleware like this:
set_banner("<b>Note:</b> This is a sample persistant-scope banner set in a controller", "success", true);
Is there a better way to accomplish storing both page-level and site-wide banners? My concerns is that hitting the session on every pageload may be inefficient, especially for banners that won't be changing for long periods of time. Will this approach mess with Laravel's cache, etc?
As you said the banners do not change that often. Hence for me i would implement it using Cache. This improves performance since we need only one use to have the banners cached. And for the rest its retrieved faster from the Cache rather Session.
Do you want to have to change code to change the banner of a given page?
I would suggest instead creating a "pages" package, where each page route name is entered into a database.
From there, from your page service provider you get Page::getModel()->banner_text or something similar.
The method would look for a db result matching the current route name with a result within db.
when a controller method is triggered you simply call
Page::getBannerText()
That method will pull the current route name, pull the page result related to that page if it exists or create it if it does not exist (easy way to get everything). You cache the db query result for X hours, days or whatever so whenever someone else makes a call, you don't even need to deal with any storage on client side.
This allows you to modify the value from a db fascet. Its the more "proper" way to do it.

Best way of triggering to delete a row from database if 'date` is 'today'?

I made a Diary at http://kees.een-site-bouwen.nl/agenda which can have Events for specific dates. You can add an event using the form located here: http://kees.een-site-bouwen.nl/evenementform
As you can see I have 3 fields 'Datum, Van & Tot' (translation: Datum = date, Van = From, Tot = till)
If the time on that specific date expires I would like to run a script which deletes that specific row from the database.
I searched on google and found a few things like MYSQL Trigger and PHP cronjob, but I don't know if there's an easier way to do this? or how to do it exactly.
My database structure looks like this:
agenda // diary
- - - - // not added the whole structure.
idagenda
titel
waar
www
email
activated
....
....
agendadatum // diary dates
- - - - - -
id
datum
van
tot
idagenda
as you can see I'm using a join to add more dates to one event.
How could I trigger the datetime to delete the rows from the db if the date = today?
NOTE: I am using the Codeigniter framework.
You could set a hook. And use a function like
$this->db->where('tot <', date('Y-m-d H:i:s'));
$this->db->delete('agendadatum');
My codeigniter is a bit rusty but that query should remove all "old" entries on EVERY page load. So if you're going for high traffic this will not hold up.
Running a cronjob every hour/day is probably the "cleanest" way. This will require you to set a where condition on all selections of agendadatum that forces the "tot" date to be in the future. Else it's possible you see expired entries.
Edit:
From what I can gather if you define your hook like:
$hook['post_controller_constructor'] = array(
'class' => '',
'function' => 'delete_old_entries',
'filename' => 'agenda.php',
'filepath' => 'hooks',
'params' => array()
);
And create a file named agenda.php in application/hooks which looks like:
<?php
function delete_old_entries() {
$CI =& get_instance();
$CI->load->database();
$query = $CI->db->query(" DELETE FROM agendadatum WHERE tot < NOW(); ");
}
It should work. However this is pieced together from what I could find and untested. So it might work, it might not. But something along these lines should do the trick even if it isn't this.
If I understand correctly:
CREATE TRIGGER deleteRows AFTER UPDATE,INSERT ON myTable
FOR EACH ROW BEGIN
DELETE FROM myTable WHERE Datum = NOW()
END;
MySQL has a built-in Event Scheduler that basically allows you to run arbitrary SQL code at scheduled times. You could purge your database once a day for instance.
However, I know from your other question that you are hosting your project on a shared host, and, unfortunately, shuch hosts often disable the feature. Check out this manual page to find out whether the feature is active on your server.

Categories