Closed fazliddin closed 9 years ago
Indeed there is no lang
field or property in CWebApplication
.
There is language
instead.
Look the line which causes problem 10 if(isset($params['lang']) && ($params['lang']==Yii::app()->lang->default))
if there is no field lang
then error must be on this line:
if(count(Yii::app()->lang->data)<2) return;
In any of the case framework does NOT have CApplication::lang
, so it is all your code.
here is config file:
'lang' => [
'class' => 'core.components.LanguageComponent',
],
if I add lang
to preload everything works fine, It is problem of framework!
you have to put lang into component section of config.
Yes, of course, it is there:
'components' => [
'session' => [
'class' => 'CDbHttpSession',
'connectionID' => 'db',
'cookieParams' => [
'domain' => '.domain.loc', // NEED TO CHANGE DYNAMIC VALUE
],
],
'user' => [
'allowAutoLogin' => true,
'identityCookie' => [
'domain' => '.domain.loc', // NEED TO CHANGE DYNAMIC VALUE
],
],
'sitecookie' => [
'class' => 'SiteCookie',
'timeOut' => 2592000, //30*24*60*60 ~ 30 days
],
'lang' => [
'class' => 'core.components.LanguageComponent',
],
'request' => [
'enableCsrfValidation' => true,
'enableCookieValidation' => true,
'csrfTokenName' => 'session-token',
],
'db' => [
'schemaCachingDuration' => PRODUCTION_MODE ? 86400000 : 0, // 1000 days
'enableParamLogging' => !PRODUCTION_MODE,
'charset' => 'utf8',
'emulatePrepare' => true,
'enableProfiling' => false,
],
'cache' => [
'class' => 'CFileCache',
],
],
Problem is that I can't understand why lang
can be used normally in foreach(Yii::app()->lang->data as $key => $value)
before the error, but $links[$key] = $this->owner->createUrl('', $params);
causes problem
can you show the complete error including stack trace?
I put (>) sign to indicate bold lines
PHP notice
Undefined property: CWebApplication::$lang
/var/www/vhost/myproject/core/components/UrlManager.php(10)
01 <?php
02
03 /**
04 * Custom url manager which adds language code to url
05 */
06 class UrlManager extends CUrlManager
07 {
08 public function createUrl($route,$params=array(),$ampersand='&')
09 {
>10 if(isset($params['lang']) && ($params['lang']==Yii::app()->lang->default))
11 unset($params['lang']);
12 elseif(!isset($params['lang']) && Yii::app()->lang->isDifferent())
13 $params['lang'] = Yii::app()->lang->current;
14
15 return parent::createUrl($route,$params,$ampersand);
16 }
17 }
Stack Trace
#0
– /var/www/vhost/yii-framework/base/CApplication.php(543): UrlManager->createUrl("", array("lang" => "uz"), "&")
538 * @param string $ampersand the token separating name-value pairs in the URL.
539 * @return string the constructed URL
540 */
541 public function createUrl($route,$params=array(),$ampersand='&')
542 {
>543 return $this->getUrlManager()->createUrl($route,$params,$ampersand);
544 }
545
546 /**
547 * Creates an absolute URL based on the given controller and action information.
548 * @param string $route the URL route. This should be in the format of 'ControllerID/ActionID'.
#1
– /var/www/vhost/myproject/core/components/LanguageComponent.php(50): CApplication->createUrl("", array("lang" => "uz"))
45
46 // if user visits default home page, but he chose other language before
47 // we redirect him to his prefered language
48 if(empty($_GET) && $cookLang && ($cookLang != $this->default))
49 {
>50 Yii::app()->request->redirect(Yii::app()->createUrl('', ['lang' => $cookLang]));
51 }
52
53 // If user chose language by select option
54 elseif(isset($_POST['lang']) && $this->exist($_POST['lang']))
55 {
#2
– /var/www/vhost/yii-framework/base/CModule.php(387): LanguageComponent->init()
382 if(!isset($config['enabled']) || $config['enabled'])
383 {
384 Yii::trace("Loading \"$id\" application component",'system.CModule');
385 unset($config['enabled']);
386 $component=Yii::createComponent($config);
>387 $component->init();
388 return $this->_components[$id]=$component;
389 }
390 }
391 }
392
#3
– /var/www/vhost/yii-framework/base/CModule.php(103): CModule->getComponent("lang")
098 * @return mixed the named property value
099 */
100 public function __get($name)
101 {
102 if($this->hasComponent($name))
>103 return $this->getComponent($name);
104 else
105 return parent::__get($name);
106 }
107
108 /**
#4
– /var/www/vhost/myproject/application/extensions/language/LanguageSwitcherWidget.php(11): CModule->__get("lang")
06 class LanguageSwitcherWidget extends CWidget
07 {
08 public $template='link'; //select
09 public function init()
10 {
>11 if(count(Yii::app()->lang->data)<2) return;
12
13 $links = array();
14 $params = $_GET;
15 foreach(Yii::app()->lang->data as $key => $value)
16 {
#5
– /var/www/vhost/yii-framework/web/CBaseController.php(147): LanguageSwitcherWidget->init()
142 * @return CWidget the fully initialized widget instance.
143 */
144 public function createWidget($className,$properties=array())
145 {
146 $widget=Yii::app()->getWidgetFactory()->createWidget($this,$className,$properties);
>147 $widget->init();
148 return $widget;
149 }
150
151 /**
152 * Creates a widget and executes it.
#6
– /var/www/vhost/yii-framework/web/CBaseController.php(172): CBaseController->createWidget("ext.language.LanguageSwitcherWidget", array("template" => "link"))
167 $widget->run();
168 return ob_get_clean();
169 }
170 else
171 {
>172 $widget=$this->createWidget($className,$properties);
173 $widget->run();
174 return $widget;
175 }
176 }
177
#7
– /var/www/vhost/myproject/application/views/site/index.php(22): CBaseController->widget("ext.language.LanguageSwitcherWidget", array("template" => "link"))
17 <p>For more details on how to further develop this application, please read
18 the <a href="http://www.yiiframework.com/doc/">documentation</a>.
19 Feel free to ask in the <a href="http://www.yiiframework.com/forum/">forum</a>,
20 should you have any questions.</p>
21
>22 <?php $this->widget('ext.language.LanguageSwitcherWidget',['template' => 'link']); ?>
#8
– /var/www/vhost/yii-framework/web/CBaseController.php(126): require("/var/www/vhost/myproject/application/views/site/index.php")
121 $data=$_data_;
122 if($_return_)
123 {
124 ob_start();
125 ob_implicit_flush(false);
126 require($_viewFile_);
127 return ob_get_clean();
128 }
129 else
130 require($_viewFile_);
131 }
#9
– /var/www/vhost/yii-framework/web/CBaseController.php(95): CBaseController->renderInternal("/var/www/vhost/myproject/application/views/site/index.php", null, true)
090 {
091 $widgetCount=count($this->_widgetStack);
092 if(($renderer=Yii::app()->getViewRenderer())!==null && $renderer->fileExtension==='.'.CFileHelper::getExtension($viewFile))
093 $content=$renderer->renderFile($this,$viewFile,$data,$return);
094 else
>095 $content=$this->renderInternal($viewFile,$data,$return);
096 if(count($this->_widgetStack)===$widgetCount)
097 return $content;
098 else
099 {
100 $widget=end($this->_widgetStack);
#10
– /var/www/vhost/yii-framework/web/CController.php(869): CBaseController->renderFile("/var/www/vhost/myproject/application/views/site/index.php", null, true)
864 */
865 public function renderPartial($view,$data=null,$return=false,$processOutput=false)
866 {
867 if(($viewFile=$this->getViewFile($view))!==false)
868 {
>869 $output=$this->renderFile($viewFile,$data,true);
870 if($processOutput)
871 $output=$this->processOutput($output);
872 if($return)
873 return $output;
874 else
#11
– /var/www/vhost/yii-framework/web/CController.php(782): CController->renderPartial("index", null, true)
777 */
778 public function render($view,$data=null,$return=false)
779 {
780 if($this->beforeRender($view))
781 {
>782 $output=$this->renderPartial($view,$data,true);
783 if(($layoutFile=$this->getLayoutFile($this->layout))!==false)
784 $output=$this->renderFile($layoutFile,array('content'=>$output),true);
785
786 $this->afterRender($view,$output);
787
#12
– /var/www/vhost/myproject/application/controllers/SiteController.php(38): CController->render("index")
33 System::out($l,false);
34
35 $l1 = LanguageModel::model();
36 //$l->init();
37 System::out($l1);*/
>38 $this->render('index');
39 }
40
41 /**
42 * This is the action to handle external exceptions.
43 */
#13
– /var/www/vhost/yii-framework/web/actions/CInlineAction.php(49): SiteController->actionIndex()
44 $controller=$this->getController();
45 $method=new ReflectionMethod($controller, $methodName);
46 if($method->getNumberOfParameters()>0)
47 return $this->runWithParamsInternal($controller, $method, $params);
48 else
>49 return $controller->$methodName();
50 }
51
52 }
#14
– /var/www/vhost/yii-framework/web/CController.php(308): CInlineAction->runWithParams(array())
303 {
304 $priorAction=$this->_action;
305 $this->_action=$action;
306 if($this->beforeAction($action))
307 {
>308 if($action->runWithParams($this->getActionParams())===false)
309 $this->invalidActionParams($action);
310 else
311 $this->afterAction($action);
312 }
313 $this->_action=$priorAction;
#15
– /var/www/vhost/yii-framework/web/CController.php(286): CController->runAction(CInlineAction)
281 * @see runAction
282 */
283 public function runActionWithFilters($action,$filters)
284 {
285 if(empty($filters))
>286 $this->runAction($action);
287 else
288 {
289 $priorAction=$this->_action;
290 $this->_action=$action;
291 CFilterChain::create($this,$action,$filters)->run();
#16
– /var/www/vhost/yii-framework/web/CController.php(265): CController->runActionWithFilters(CInlineAction, array())
260 {
261 if(($parent=$this->getModule())===null)
262 $parent=Yii::app();
263 if($parent->beforeControllerAction($this,$action))
264 {
>265 $this->runActionWithFilters($action,$this->filters());
266 $parent->afterControllerAction($this,$action);
267 }
268 }
269 else
270 $this->missingAction($actionID);
#17
– /var/www/vhost/yii-framework/web/CWebApplication.php(282): CController->run("")
277 {
278 list($controller,$actionID)=$ca;
279 $oldController=$this->_controller;
280 $this->_controller=$controller;
281 $controller->init();
>282 $controller->run($actionID);
283 $this->_controller=$oldController;
284 }
285 else
286 throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
287 array('{route}'=>$route===''?$this->defaultController:$route)));
#18
– /var/www/vhost/yii-framework/web/CWebApplication.php(141): CWebApplication->runController("")
136 foreach(array_splice($this->catchAllRequest,1) as $name=>$value)
137 $_GET[$name]=$value;
138 }
139 else
140 $route=$this->getUrlManager()->parseUrl($this->getRequest());
>141 $this->runController($route);
142 }
143
144 /**
145 * Registers the core application components.
146 * This method overrides the parent implementation by registering additional core components.
#19
– /var/www/vhost/yii-framework/base/CApplication.php(180): CWebApplication->processRequest()
175 public function run()
176 {
177 if($this->hasEventHandler('onBeginRequest'))
178 $this->onBeginRequest(new CEvent($this));
179 register_shutdown_function(array($this,'end'),0,false);
>180 $this->processRequest();
181 if($this->hasEventHandler('onEndRequest'))
182 $this->onEndRequest(new CEvent($this));
183 }
184
185 /**
#20
– /var/www/vhost/myproject/public/frontend/index.php(20): CApplication->run()
15 require(ROOT_DIR . '/application/config/main-shared.php'),
16 require(ROOT_DIR . '/application/config/main.php'),
17 require(ROOT_DIR . '/application/config/main-local.php')
18 );
19
>20 Yii::createWebApplication($config)->run();
21
22 if(!PRODUCTION_MODE)
23 require ROOT_DIR . '/application/config/debug-info.php';
24
2014-12-28 05:29:11 Apache/2.4.7 (Ubuntu) Yii Framework/1.1.15
Application Log
Timestamp Level Category Message
05:29:11.581417 trace system.db.CDbCommand
Querying SQL: SELECT *
FROM `cms_languages`
in /var/www/vhost/myproject/application/models/LanguageModel.php (84)
in /var/www/vhost/myproject/application/models/LanguageModel.php (93)
in /var/www/vhost/myproject/core/components/LanguageComponent.php (33)
here is lang component:
<?php
/**
* Automatically initializes languages
*/
class LanguageComponent extends CApplicationComponent
{
public $data = array(); // array of key-values: en=>English, ...
public $default = null; // index: [en|ru]
public $current = null; // index: [en|ru]
/**
* [getIndices description]
* @return [type] [description]
*/
public function getIndices()
{
return array_keys($this->data);
}
public function exist($code)
{
return array_key_exists($code, $this->data);
}
public function isDifferent()
{
return ($this->default != $this->current) ? true : false;
}
public function initData()
{
$data = LanguageModel::model()->getProcessedData();
if (empty($data))
throw new CHttpException(404, Yii::t('system', 'No language found'));
$this->default = $data['default'];
$this->data = $data['data'];
}
public function init()
{
$this->initData();
$cookLang = Yii::app()->sitecookie->get('lang');
// if user visits default home page, but he chose other language before
// we redirect him to his prefered language
if(empty($_GET) && $cookLang && ($cookLang != $this->default))
{
Yii::app()->request->redirect(Yii::app()->createUrl('', ['lang' => $cookLang]));
}
// If user chose language by select option
elseif(isset($_POST['lang']) && $this->exist($_POST['lang']))
{
// we do nothing if he rechose his current language
if($cookLang && ($cookLang == $_POST['lang']))
$this->current = $_POST['lang'];
else
// we redirect him to chosen language url
Yii::app()->request->redirect($_POST[$_POST['lang']]);
}
// if language code is already provided by GET
elseif(isset($_GET['lang']) && $this->exist($_GET['lang']))
{
$this->current = $_GET['lang'];
}
else
// we neither POST, nor GET and we are not in homepage
$this->current = $this->default;
Yii::app()->language = $this->current;
if($this->current != $cookLang)
Yii::app()->sitecookie->set('lang', $this->current);
return parent::init();
}
}
Huh, I found problem. It is partially my fault, and partially frameworks fault.
LanguageComponent
calls UrlManager::createUrl
and, in turn, createUrl
calls LanguageComponent::default
which results infinite loop. Framework must have
internal stack and should detect such situations and give understandable error.
Actually lang
component must be preload, but it uses results of UrlManager through
$_GET array. If I put lang
in preload, parsed data of UrlManager
is not available.
How to make preload of lang
after request has been parsed?
it may be better to move some of the things you do in init() to a beforeAction event that you add by attaching a behavior to the application.
Error:
Code that causes problem: