Expiration time makes error in caching - php

I'm using file caching (CFileCache) to show a simple message from a database table.
When page load for the first time it works correct but when I reload page it makes an Error as:
include(CTimestampBehavior.php) [function.include]: failed to open stream: No such file or directory
And This error remains until TIME EXPIRATION which I set in cache->set() and next page load just one time and it makes error again and so on.
Here is my method to handle caching:
public static function getLatest()
{
//see if it is in the cache, if so, just return it
if( ($cache=Yii::app()->cache)!==null)
{
$key='TrackStar.ProjectListing.SystemMessage';
if(($sysMessage=$cache->get($key))!==false)
return $sysMessage;
}
//The system message was either not found in the cache, or
//there is no cache component defined for the application
//retrieve the system message from the database
$sysMessage = SysMessage::model()->find(array(
'order'=>'t.update_time DESC',
));
if($sysMessage != null)
{
//a valid message was found. Store it in cache for future retrievals
if(isset($key))
//$cache->set($key,$sysMessage,300);
$cache->set($key, $sysMessage, 300, new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_sys_message'));
return $sysMessage;
}
else
return null;
}
Error occures in this line:
if(($sysMessage=$cache->get($key))!==false)
I'm new to Yii and caching and have no idea about it.
UPDATE:
behaviors method of AR models:
public function behaviors()
{
return array(
'CTimestampBehavior' => array(
'class' => 'zii.behaviors.CTimestampBehavior',
'createAttribute' => 'create_time',
'updateAttribute' => 'update_time',
'setUpdateOnCreate' => true,
),
);
}

This looks like your issue is either that:
framework/zii/behaviors/CTimestampBehavior.php is missing
framework/zii/behaviors/CTimestampBehavior.php doesn't have correct permissions to be read by your server user
You are using opcode cache (APC?) and there are some issues on that end, (though reports for this seem to be for random occurrences). Try disabling it.
For some unknown reason Yii doesn't import your zii routes
In any event I suggest trying a workaround of adding "zii.behaviors.CTimestampBehavior" to your main.php configuration file "import" section. Or simply calling Yii::import('zii.behaviors.CTimestampBehavior'); in your function. Hopefully that works and you can continue with your work while diving deaper into the issue when you've got the time.
If it doesn't you can investigate the above (and at least people who come here will have more information to work with)

Related

Force all errors to a custom error page in CakePHP

I'm trying to force all of my errors to a single custom page in Cakephp(2.0) but most of the tutorials that I find are for very specific error codes. I want it to show just a single error page so what I first did was to point all of the errors of specific error status to a single error page. But after further testing, I noticed that other codes were not being captured.
I need my code to capture all of the http error codes to a single error page.
This is my code:
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'AppExceptionRenderer',
'log' => true
));
And my AppExceptionRenderer:
<?php
App::uses('ExceptionRenderer', 'Error');
class AppExceptionRenderer extends ExceptionRenderer {
public function internalError($error) {
$this->controller->beforeFilter();
$this->controller->set('title_for_layout', 'Internal Server Error');
$this->controller->render('/Errors/error500');
$this->controller->response->send();
... All the other error handlers are similar to this, but very limited since there are a lot of client and server errors
} ?>
My template pages seems to be working just fine, so I did not include it.
How do I alter the code to cover every http status code instead? Or is it not possible?
You have to override the following methods:
ExceptionRenderer::error400($error)
ExceptionRenderer::error500($error)
Alternatively, you can override ExceptionRenderer:_outputMessage($template) with something like:
protected function _outputMessage($template) {
$this->controller->layout = 'my_error';
parent::_outputMessage($template);
}
And add the file /app/View/Layouts/my_error.ctp as a new custom layout.

Yii does not log with an infinite loop

I am not sure if this is the bug in yii or i am doing a wrong approach. I am creating a back-end process that runs without stop and logging is something that is crucial.
I created a console application. My logging works when I do this:
public function actionTest(){
Yii::log( "testing", 'error', 'worker.*');
return;
}
I am able to see "testing" logged into the file worker.log that is located in runtime folder>
However when I create an infinite loop, I don't see anything that is logged:
public function actionTest(){
while(1){
Yii::log( "testing", 'error', 'worker.*');
echo 'running';
usleep(5000000);
}
}
The worker.log file is empty.
Here is the configuration setting for worker.log in console.php:
array(
'class'=>'CFileLogRoute',
'categories' => 'worker.*',
'logFile' => 'worker.log'
)
For performance reasons, by default Yii outputs log records at the end of the request OR when CLogger::autoFlash messages limit is reached IF CLogger::autoDump is set to true.
In your case this event never occurs. To fix it you have several options:
configure CLogger to flush messages as soon as you log them, by setting autoFlash = 1 and autoDump = true
call CLogger::flush() method manually
you can create your own logger class that flushes messages the way you need
or use one of the existing implementations that flushes messages right away, like this one.

how to fix CConsoleApplication.user undefined in a command class in yii framework?

I am having that error , whenever I ran my simple cron script in shell ,
any idea how to fix that thing ?, from the error itself, it says the .user is undefiend,
when I placed the
'user' => array(
// enable cookie-based authentication
'allowAutoLogin' => true,
'loginUrl' => array('myaccount/blah/login'),
in the console config, it is looking for a "Class" ,, what class am i supposed to include in that array? , this user login url is using an LDAP stuff in loggin in and authentication, what should I do ?
A CConsoleApplication is for handling offline tasks. For example, the application starts a cronjob within a linux system. The application checks each day if a registered user of your website should change his password, because it must be changed every 3 month. If the password expired send an email.
To preselecting the users you have set a scope condition to check the status of a user, as well as a scope to restricted signed in users on her own data:
public function scopes(){
return array(...,
'user' => array(
'condition'=>'id='.Yii::app()->user->id,
),
'active' => array(
'condition'=>'status='.self::STATUS_ACTIVE,
), ...
);
}
Now, in your CCA-Code you use the active scope to get all users:
$usersArray = User::model()->active()->findAll(); ...foreach.... The Problem here is in the use of the extended class, the CActiveRecord-class. Mostly used as a class extension in models, which are stored in a database. In this CActiveRecord-class the CActiveRecord->__call function is used to get all stored scopes of a model. After that the class merged the actually requested scopes with the rest of the database criteria. The fact that all scopes are loaded first occures the error in loading the user-scope, include Yii::app()->user->id. The WebUser is called and throws the exception 'CException' with message 'attribute "CConsoleApplication.user is not defined'. You wouldn't call the WebUser, but the automatism arrange this for you :-)
So, do it like schmunk says. Generate in your scope code an exception part where ensures that Yii::app()->user is not called:
public function scopes(){
if (Yii::app() instanceof CConsoleApplication) {
$user = array(''); //no condition
}else{
$user = array(
'condition'=>'id='.Yii::app()->user->id,
);
}
return array(
'user' => $user,
'active' => array(
'condition'=>'status='.self::STATUS_ACTIVE,
), ...
);
}
I hope the explanation helps and perhaps also for other problems.
Short answer: You can't use CWebUser in console application. Don't include it in your config/console.php
Long(er) answer: If you rely on a component, which needs CWebUser, you'll have to detect this in the component and create some kind of workaround for this case. Have a look at this code piece for an example how to detect, if you're running a console app.
Try this
public static $console_user_id;
public function init() {
if (Yii::app() instanceof CConsoleApplication) {
if (self::$console_user_id) $this->id = self::$console_user_id;
return false;
}
parent::init();
}
solved my problem by using update, instead of save in the script...no need to use user array and CWebUser class
I had the same problem. Screened all answers given here and found some good point, but solved my problem my way, although it may not be the best.
First off all I had to figure out that my Cron Jon threw the aforementioned Exception because inside the Cron job I was running a script which had this part of code in it
if(Yii::app()->user->isAdmin()) {...} else {...}
So the console threw the error since the user was not defined. I changed my code in such a way that I tested if the console was running it. The changed code is as follows:
$console = false;
try {
$test = Yii::app()->user->isAdmin();
}
catch (CException $e) {
$console = true;
}
if($console || (!$console && Yii::app()->user->isAdmin()) {...} else {...}
As said, not perfect, but maybe a solution for someone.

Preventing error pages caching when using Zend_Cache_Backend_Static

We're currently running an app that caches pages to static html files using Zend_Cache_Backend_Static. This works really well, except that our cache is getting filled with hundreds of empty files and folders when incorrect urls are requested. Is there any way to prevent a page being cached if an Exception is being thrown? I was surprised to discover that this wasn't standard behaviour.
I've done a little digging and the ZF code that actually deals with saving out the static html pages is as follows in Zend_Cache_Frontend_Capture:
public function _flush($data) {
$id = array_pop($this->_idStack);
if ($id === null) {
Zend_Cache::throwException('use of _flush() without a start()');
}
if ($this->_extension) {
$this->save(serialize(array($data, $this->_extension)), $id, $this->_tags);
} else {
$this->save($data, $id, $this->_tags);
}
return $data;
}
This function is the output_callback for ob_start. I've tried getting hold of the response object to test for status but it doesn't seem to work inside _flush.
$response = Zend_Controller_Front::getInstance()->getResponse();
if($response->getStatus() == '200') {
// do the save as normal
}
else {
// do nothing
return false;
}
My only other thought was to test the length of $data, only caching if strlen($data) > 0 seems to work but it doesn't feel robust enough.
Update:
Unfortunately by the time we hit the ErrorController the static page has already been written to the cache, so disabling the cache at that point won't work. However it is possible to remove the page based on $_SERVER['REQUEST_URI'], which is what is used as an id when the page is first written. This line can be added to the start of errorAction in the ErrorController:
$this->_helper->cache->removePage($_SERVER['REQUEST_URI'], true);
It works nicely, but I'd prefer not to write the page in the first place!
From further experimentation the problem is not down to standard Zend Framework exceptions that cause 404s (ie. Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE, Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER, Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION) but to my custom exceptions. This is now really obvious now that I think about it, as Zend_Cache_Backend_Static needs to be initialised in the init method of an action controller. Any situation where there is no route, controller or action it won't ever be initialised anyway.
I'm throwing exceptions in existing actions where a user may be querying for a non-existent article. Therefore caching has been enabled in init and the page has been written by the time we hit postDispatch in a Front Controller Plugin (still not sure why this is the case it just is) so I can't cancel at that point. One solution then is to cancel the cache at the point of throwing the exception. The standard method of managing static page caching is using the Zend_Controller_Action_Helper_Cache action helper. I've extended this to add a cancel method like so:
<?php
class Zend_Controller_Action_Helper_PageCache extends Zend_Controller_Action_Helper_Cache {
public function cancel() {
$cache = $this->getCache(Zend_Cache_Manager::PAGECACHE);
$cache->setOption('caching', false);
$cache->getBackend('disable_caching', true);
}
}
My action controller now looks like this:
<?php
class IndexController extends Zend_Controller_Action {
private $_model;
public function init() {
$this->_model = new Model();
// using extended pageCache rather than $this->_helper->cache:
$this->_helper->pageCache(array('index'), array('indexaction'));
}
public function indexAction() {
$alias = $this->_request->getParam('article');
$article = $this->_model->getArticleByAlias($alias);
if(!$article) {
// new cancel method will disable caching
$this->_helper->pageCache->cancel();
throw new Zend_Controller_Action_Exception('Invalid article alias', 404);
}
$this->view->article = $article;
}
}
You should alter your .htaccess file RewriteRules to check for filesizes with option -s
This way if an error should occur when a page is being cached (thus producing a 0 byte file) it won't permanently be stored in the cache.
If you are using the standard ErrorController to handle 404, 500, and unhandled exceptions, and you can get a reference to your cache object from there, you could disable caching from the error handler.
In your error controller (or wherever you would like to cancel caching from), try:
$cache->setOption('caching', false);
When the save() metod of Zend_Cache_Core is called by Zend_Cache_Frontend_Capture::_flush(), it will see the caching option is set to false and it will not actually save the data to the cache and return true.

Why is frontend of Magento site not loading up? - Fatal error: Class ‘Mage__Helper_Data’ not found

I’ve got an issue with the front end of a magento site, it is throwing a 500 error. The back end admin is absolutely fine and functional, I'm able to log in no problem and there is no loss of product data.
I have un-commented out line 70 in my index.php file -
#ini_set(\'display_errors\', 1);
in order to see the errors, and this is what now displays when you load up the front end of the site - Fatal error: Class \’Mage__Helper_Data\’ not found in /var/www/vhosts/beta.mydomain.com/httpdocs/countrytoys/app/Mage.php on line 520
I reckon the double underscore here is to do with a module being missing or something..
This problem came to light after I refreshed all cache types in the admin area, but I suspect the problem was there beforehand but just bared it’s head after the cache refresh.
So far I have tried/checked -
deleting the contents of var/cache, var/session
The base URL in the db is correct
made all directories 755 permissions, and all files 644, I have also tried making index.php 755, and 777 on suggestion from other forums.
checked htaccess, all seems fine.
the physical files are all there on the server.
system.log seems to be consistently pointing to line 93 in Autoload.php -
2011-09-12T15:18:52+00:00 ERR (3): Warning: include() [<a href=\'function.include\'>function.include</a>]: Failed opening \'Mage//Helper/Data.php\' for inclusion (include_path=\'/var/www/vhosts/beta.mydomain.com/httpdocs/countrytoys/app/code/local:/var/www/vhosts/beta.mydomain.com/httpdocs/countrytoys/app/code/community:/var/www/vhosts/beta.mydomain.com/httpdocs/countrytoys/app/code/core:/var/www/vhosts/beta.mydomain.com/httpdocs/countrytoys/lib:.:\') in /var/www/vhosts/beta.mydomain.com/httpdocs/countrytoys/lib/Varien/Autoload.php on line 93
Other things I can think of that I have recently done include adding google analytics through admin, altering the code for links at the top of the site in app\design\frontend\default\blue_toys\template\page\html\header.phtml and entering some paypal details in order to set up the payment gateway.
installation details -
ver -1.5.0.1,
Theme - custom installed theme
Can anyone help?
thanks,
Luke
Your error message shows two underscores between Mage and Helper, where there usually is only one of them. For me it looks like you lost a word between Mage and Helper somewhere, as usually Mage helper identifiers are s/t like Mage_Core_Helper_Data.
I'd check the <helpers> sections of my /etc/config.xml files for wrong definitions first.
Other than that I'd probably try to get a debug trace inside the Varien_Autoload::autoload method.
I'd lookout for patterns in the parameter $class which could result in s/t like Mage__Helper_Data, e.g. occurences where $class contains spaces or double underscores:
public function autoload($class)
{
try {
if (strpos($class, ' ') !== false || strpos($class, '__') !== false) {
throw new Exception('fishy');
}
}
catch (Exception $e) {
var_dump($class, $e->getTraceAsString());
die('stop');
}
// original method code starts here
// :
}
I had a similar problem, and this question appeared in the Google results, so I thought it would be sensible to add an answer here for anyone else struggling with the same problem. With my issue, it was related to a custom <source_model> I was trying to use in the Magento configuration system.
I used the example code from Magento, which looks like this:
public function toOptionArray()
{
return array(
array('value' => 0, 'label' => Mage::helper()->__('First item')),
array('value' => 1, 'label' => Mage::helper()->__('Second item')),
array('value' => 2, 'label' => Mage::helper()->__('third item'))
);
}
The error was coming from the Mage::helper() bit - no helper was being loaded. You can change it to this, or load a specific helper:
public function toOptionArray()
{
return array(
array('value' => 0, 'label' => 'First item'),
array('value' => 1, 'label' => 'Second item'),
array('value' => 2, 'label' => 'third item')
);
}

Categories