ContentDiscount
, ItemDiscount
, I realized that I needed to do something about it, and decided to introduce namespasys into our project. Well, as they say, to app
(well, the application
is too long). However, yii does not understand it, so I had to define it in the config (you can also in index.php), but since the config was connected along the path to it, and at the time of initialization it could not use Yii::setPathOfAlias
(maybe the situation has changed now? ), then I had to modify index.php. $yii=dirname(__FILE__).'/yii/framework/yii.php'; $config=dirname(__FILE__).'/protected/config/main.php'; // remove the following lines when in production mode defined('YII_DEBUG') or define('YII_DEBUG',true); // specify how many levels of call stack should be shown in each log message defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3); // Yii, require_once($yii); // , , $config=require($config); Yii::createWebApplication($config)->run();
// - yii, Yii::getPathOfAlias Yii::setPathOfAlias('app', dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR); // define(NS_SEPARATOR,NAMESPACE_SEPARATOR); // return array( // .... );
app
, and everything works well. And no! For the time being, and all this falls in the case when the controller lies in a folder, for example, test and in the namespace app\test
. Yii searches for it in the test folder, but in the namespace app
. Since we need to work, and there was no time to write a bug report and do not need a pull request (but you can do it), I decided to write my decision. For this, I inherited from CWepApplication
and redefined the createController
method. It turned out not quite beautiful, because I had to duplicate a lot of code, but I still had to block this method to solve the internal tasks of the project. class WebApplication extends CWebApplication { // public $controllerNamespace='app'; public function createController($route,$owner=null) { if($owner===null) $owner=$this; if(($route=trim($route,'/'))==='') $route=$owner->defaultController; $caseSensitive=$this->getUrlManager()->caseSensitive; $route.='/'; while(($pos=strpos($route,'/'))!==false) { $id=substr($route,0,$pos); if(!preg_match('/^\w+$/',$id)) return null; if(!$caseSensitive) $id=strtolower($id); $route=(string)substr($route,$pos+1); if(!isset($basePath)) // first segment { if(isset($owner->controllerMap[$id])) { return array( \Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner), $this->parseActionParams($route), ); } /** @var $module \base\BaseModule */ if(($module=$owner->getModule($id))!==null){ return $this->createController($route,$module); } $basePath=$owner->getControllerPath(); $controllerID=''; } else $controllerID.='/'; $className=ucfirst($id).'Controller'; $classFile=$basePath.DIRECTORY_SEPARATOR.$className.'.php'; // if($owner->controllerNamespace!==null) $className=$owner->controllerNamespace.NS_SEPARATOR.str_replace('/',NS_SEPARATOR,$controllerID).$className; if(is_file($classFile)) { if(!class_exists($className,false)) require($classFile); if(class_exists($className,false) && is_subclass_of($className,'CController')) { $id[0]=strtolower($id[0]); return array( new $className($controllerID.$id,$owner===$this?null:$owner), $this->parseActionParams($route), ); } return null; } $controllerID.=$id; $basePath.=DIRECTORY_SEPARATOR.$id; } } }
// change the following paths if necessary $yii=dirname(__FILE__).'/yii/framework/yii.php'; $config=dirname(__FILE__).'/protected/config/main.php'; // remove the following lines when in production mode defined('YII_DEBUG') or define('YII_DEBUG',true); // specify how many levels of call stack should be shown in each log message defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3); // Yii, require_once($yii); // , $config=require($config); // , $app=new app\components\WebApplication($config); $app->run();
Yii::createComponent
, that is, it can be used by manually specifying the class name. array( 'modules'=>array( 'front'=>array( 'class'=>'front\FrontModule' ) ) )
front
alias. You can, by the same principle as for the alias app
, register it in the config, but I didn’t like this method because of the redundancy of scribbling code (I wanted to write only the module names), so I acted easier and changed my descendant CWebApplication
. class WebApplication extends CWebApplication { // .... /** * (, ) * @param array $modules */ public function setModules($modules) { $modulesConfig=array(); foreach($modules as $id=>$module){ if(is_int($id)) { $id=$module; $module=array(); } if(!isset($module['class'])) { // \Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id); $module['class']=NS_SEPARATOR.$id.NS_SEPARATOR.ucfirst($id).'Module'; } $modulesConfig[$id]=$module; } parent::setModules($modulesConfig); } }
app.modules.ModuleClass
). Now, I think, to do all this change and touch CWebApplication
less, for example, put the alias setting in the folder with the module and connect it to the main configuration.controllerNamespace
for each module. We fix this by defining a base class for all modules. class BaseModule extends \CWebModule { /** * + */ protected function init() { parent::init(); // , $namespace=implode(NS_SEPARATOR, array_slice(explode(NS_SEPARATOR,get_class($this)),0,-1)); $this->controllerNamespace=$namespace.NS_SEPARATOR.'controllers'; } /** * (, ) * @param array $modules */ public function setModules($modules) { $modulesConfig=array(); foreach($modules as $id=>$module){ if(is_int($id)) { $id=$module; $module=array(); } if(!isset($module['class'])) { \Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id); $module['class']=NS_SEPARATOR.$id.NS_SEPARATOR.ucfirst($id).'Module'; } $modulesConfig[$id]=$module; } parent::setModules($modulesConfig); } }
commandNampespace
either in `CConsoleApplication` or in` CConsoleCommandRunner` (maybe it’s worth writing a feature request?). I began to dig in the direction of commandMap
, but even here I was disappointed. // , Yii::setPathOfAlias('app',dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR); //... 'commandMap'=>array( 'import'=>'\app\commands\ImportCommand', ),
ImportCom
. // , Yii::setPathOfAlias('app',dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR); //... 'commandMap'=>array( // 'import'=>array( 'class'=>'\app\commands\ImportCommand', ) ),
const CLASS_NAME=__CLASS_NAME__;
. class NamespaceRecord extends CActiveRecord { public static function className() { return get_called_class(); } }
public function relations(){ return array( 'country'=>'app\location\Country', ) }
public function relations(){ return array( 'country'=>Country::className(), ) }
$this->widget(' \ ')
in my views $this->widget(' \ ')
, however, with the release of yii2, I made my widgets more similar to yii2. For this, I defined a base class for all widgets. class NSWidget extends \CWidget{ /** * @param array $options * @return \CWidget */ public static function begin($options=array()) { return \Yii::app()->controller->beginWidget(get_called_class(),$options); } /** * @return \CWidget */ public static function end() { return \Yii::app()->controller->endWidget(); } /** * @param array $options * @return string widget content */ public static function runWidget($options=array()) { return \Yii::app()->controller->widget(get_called_class(),$options,true); } }
echo MyWidgetNS\MyWidget::begin($options); echo MyWidgetNS\MyWidget::end(); //... echo MyWidget2NS\MyWidget2::runWidget($options);
'aliases'=>array( 'app'=>'application' ),
Source: https://habr.com/ru/post/209526/
All Articles