Combining Yii2 controllers with Yii1 controllers - yii

I have a rather large Yii1 application that I want to migrate slowly to Yii2. I would like to do this gradually.
I have followed the instructions in the Yii2 and Yii1 integration manual.
And my application is running fine.
I have also tried the yii2-yii-bridge trick and it also seems to work after some tweaks.
My question is, now that I know I have both versions of Yii in my application, how can I start adding Yii2 style controllers?
If I create a simple Yii2 style controller, like this:
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
class SecondController extends Controller {
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['index'],
'rules' => [
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied
],
],
];
}
public function actionIndex()
{
Yii::trace("(!!!) SecondController::index called!!!");
return "SecondController::index!!";
}
} // class
I can't access it using the URL scheme that I am used to, so http://local.url/second/index doesn't seem to be found.
However if I create a Yii1 style the way I have always done, it resolves just fine:
class ThirdController extends Controller {
public function accessRules() {
return array(
array('allow',
'actions' => array('index'),
'users' => array('*'),
),
);
}
public function actionIndex() {
Yii::trace("ThirdController::index called!!!");
return "ThirdController::index!!";
}
}
Seems that the default url mapping of <controller>/<action> cannot deal with namespaced controllers is there a way around this?

Seems that the default url mapping of / cannot deal with namespaced controllers is there a way around this?
To support namespaced controllers you need to use CWebModule::$controllerNamespace for module controllers or CWebApplication::$controllerNamespace for global application controllers. Then all controllers in given scope needs to be namespaced. If you want to use namepsaces only in some controllers, you need to use CWebApplication::$controllerMap or CWebModule::$controllerMap and configure controllers classes for specified routes.
However running Yii 2.0 controller in Yii 1.1 application most likely will not work at all. If you want to move only some part of application to Yii 2, I suggest to configure and run it as a separate application and route to proper application using rewrite rules. For example, if you move user module to Yii 2 you may use this in your .htaccess:
RewriteEngine on
# Yii 2 rules
RewriteRule ^user index-yii2.php [L]
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php [L]
In index.php file you should have bootstrapped your application in Yii 1.1, and in index-yii2.php you have Yii 2 application.

The main goal of integration is to using some of the features only available in Yii 2. Imagine that you still have a running Yii 1 application. But you add some external library with new features.
To be able using controllers from Yii 2 you should make a deep integration with Yii 1 core.
I can only suggest splitting requests to applications index files, e.g. in .htaccess and create some new functionality in Yii 2.

Related

how to using plugin with inherited auth as child of other plugin

for my application i want to write an "admin" plugin, named "db" with own auth-component. To manage acl i tried to implement ivanamat/cakephp3-aclmanager as part of my admin tool, because my app won't need user authentification, maybe later.
i load AclManager in plugins/db/Plugin.php
public function bootstrap(PluginApplicationInterface $app)
{
Configure::write('AclManager.aros', array('DbGroups', 'DbRoles', 'DbUsers'));
parent::bootstrap($app);
$app->addPlugin('AclManager', ['routes' => false]);
}
I set up Routing Rules in db/config/routes.php
Router::connect(
'db/acl',
['plugin' => 'AclManager', 'controller' => 'Acl', 'action' => 'index']
);
Router::connect(
'db/acl/:action/*',
['plugin' => 'AclManager', 'controller' => 'Acl']
);
And i set up Auth Configuration in plugins/db/Controller/AppController.php
It's loaded and aside a "Auth not found"-error it works, but this is my problem.
When i debug $this->Auth in app.local/db/ it's filled. But not when i debug in app.local/db/acl. even when i load this plugin in my plugin, it's using Base AppController, not Plugin AppController.
Is it possible to inherit auth from plugin to plugin or load plugins with parent-child-association?
You cannot change what a (controller) class inherits, that is compile time information, and once it's processed, it is what it is, the controller classes of the AclManager plugin do extend App\AppController.
There's lots of different ways to solve your problem, one would for example be to dynamically configure the authentication in your application's base App\AppController class, rather than in your Db plugin's Db\AppController class.
You can check the routing information whether it's a request for the Db plugin or the AclManager plugin, and only load the auth component in that case, something like this:
public function initialize()
{
if (in_array($this->request->getParam('plugin'), ['Db', 'AclManager'], true)) {
$this->loadComponent('Auth', [
// ...
]);
}
}
That way the Db and AclManager plugin controller classes will inherit the authenticaton setup while your main application and possible other plugins are being excluded.
ps. if you're just starting to implement authentication, then I'd strongly suggest that you try the new authentication and authorization plugins, they're much more versatile than the (deprecated) auth component!

Alias "ext.components.MyClass" is invalid. Make sure it points to an existing PHP file and the file is readable

i am new in yii framework. currently i am using yii 1.1.
now i want to create custom components and we can say than create global function which is use anywhere in the application.
According to this url 'http://www.yiiframework.com/wiki/727/updated-how-to-create-call-custom-global-function-in-whole-application/'
i am follow all steps according to above url
but i have occur a error
Alias "ext.components.MyClass" is invalid. Make sure it points to an existing PHP file and the file is readable.
MyClass.php in the components folder
class MyClass extends CApplicationComponent {
public function get_my_info() {
$value = '1';
return $value;
}
}
Declare in the config folder
'components'=>array(
'user'=>array(
// enable cookie-based authentication
'allowAutoLogin'=>true,
),
'myClass' => array(
'class' => 'ext.components.MyClass',
),
And use in the view file
<?php
$myInfo = Yii::app()->myClass->get_my_info();
echo $myInfo;
?>
Have you put the file in correct component directory?. As per your alias the path should be /protected/extensions/components/MyClass.php
Write full path like application.modules.setting.components.*

Yii2 config params vs class properties

What is better to use:
params in config
'modules' => [
'admin' => [
'class' => 'app\modules\admin\Admin',
'defaultRoute' => 'question',
'layout' => 'main.php',
], ],
or properties in class
namespace app\modules\admin;
class Admin extends \yii\base\Module
{
public $class = 'app\modules\admin\Admin';
public $defaultRoute ='question';
public $layout = 'main.php';
...
What is the best practise?
For me the best pratice is the firts one.
Is the pratice suggested by Yii2 framework, and It allows you to centralize all major aspects of recurring costs related to the configuration, leaving the class aspects of its behavior are not relevant to the configfurazione framework. In one fell swoop in the first solution all the configuration of the framework is visible.
It is also active from the start without having to invoke the class
Configuration is only for the configuration files. The reason is that you put it in one centralized place. The configuration is used by the whole application and if you change it, you don't change the code in your application.

Extending Laravel 5.1 Mess Detection the right way

Laravel 5.1 has only one built-in hardcoded Mess Detection, it searches to see if #package tag is the same with /namespace, like so:
preg_match('/namespace\ ' . self::REQUIRED_NAMESPACE . '\\\(.*);/isU', $content, $namespace);
preg_match('/\/*( )+#package\ (.*)[\r?\n]/isU', $content, $package);
if (!isset($namespace[1]) || empty($namespace[1])) {
continue;
}
I want to extend this to add multiple detection classes.
My folder structure currently looks like this:
Helpers >
Commands >
MessDetector >
Detector >
DetectorInterface.php
DetectorAbstract.php
PackageTagDetector.php
MessDetector.php
The file MessDetector is made as an Artisan Command, that means it extends \Illuminate\Console\Command
I have a config file called mess_detection.php which has the detection rules like so:
return [
'rules' => [
'\Helpers\Commands\MessDetector\PackageTagDetector' =>
[
'rule' => '/\/*( )+#package\ (.*)[\r?\n]/isU',
'path' => app_path(),
'info' => 'Checking for #package tag',
'error'=> 'Malformed or missing package tag'
]
]
];
But got stuck with figuring out how exactly to instantiate PackageTagDetector class in MessDetector class.
Any ideas design pattern wise?
Laravel has no built in mess detector.
Also checking if package tags matches the namespace is a custom convention, Laravel doesn't use package tags at all.
It seems like you are using a third party library?
I have made an abstract class and interfaces for every rule I needed.
Each rule had it's own class.
The rules extended the abstract and in the abstract most of the logic was used.
The rules themselves where stored in a config file, in the config file I also mentioned the class and class specific actions.

Prevent Yii from loading JS out of assets

Is there a way to configure Yii such that it will no longer load any Javascript out of the Assets folder?
Make your own AssetManager or extend current
protected/components/DummyAssetManager.php:
class DummyAssetManager extends CApplicationComponent {
public function publish(){}
}
add into components array in
protected/config/main.php:
'assetManager'=>array(
'class'=>'DummyAssetManager',
),
You should consult the manual for a detailed description of
the assetManager options
I think you can try following option in your config/main.php
'components' => array(
'assetManager' => array(
'linkAssets' => true,
),
),
This will make asset files symbolic links to your original js/css sources. See linkAssets for more details on it.
If your PHP<5.3, or the OS it's running on doesn't support symbolic links, you won't be able to use 'linkAssets' option, in this case you can try:
'components' => array(
'assetManager' => array(
'forceCopy' => true,
),
),
This should update asset folder on every request. These two options are usually used during development process (btw, you can't use both) and should be removed from production.
PS: if you're sure that you haven't explicitly enabled ckeditor somewhere in your code and you're confident about your assetmanager calls throughout the code, check your layout and page for widgets that require this CKeditor, as Yii can't preload 'stuff' just randomly, it can be triggered by some preloaded component/extension or yii widget.