Hello (sorry for my english...)
I got an aplication in Yii. I choose diffrent databases depending on $_GET['project']. My urls looks like index.php?r=controler/action&project=MyProject.
But i have to add &project=.. to every single link on my site, how can i make Yii do it automatically?
If you are using CUrlManager::createUrl() (or one of the other createUrl() variants) to create your links, you could override it in your own custom UrlManager:
class UrlManager extends CUrlManager {
public function createUrl($route, $params=array(), $ampersand='&') {
isset($params['project']) || $params['project'] = 'MyProject';
return parent::createUrl($route, $params, $ampersand);
}
}
Then in your config be sure to use your own custom UrlManager class:
return array(
...
'components' => array(
'urlManager' => array(
'class' => 'UrlManager',
),
),
...
);
Related
I have the ability for users to define URLs for some of their items so, for example:
http://x.com/mynewobject
mynewobject would be defined by the user in a form and I need to be able to say in the UrlManager to math that, but also match everything else.
Problem is the default rules in the UrlManager will try and catch the mynewobject controller and throw a 404 when it cannot.
What is the way to make a UrlManager catch user defined URLs?
The best way I have found of doing this, without manually declaring your URLs, is to actually take a closer look at the Yii 2 documentation.
It actually shows a good example here of user generated URLs http://www.yiiframework.com/doc-2.0/guide-runtime-routing.html#creating-rules which I used to complete my task.
The configuration I used was:
'urlManagerFrontend' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'cache' => null,
'baseUrl' => '/',
'rules' => [
[
'class' => 'common\components\ObjectUrlRule',
'pattern' => '<slug:.*>',
'route' => 'site/index'
],
'<controller:[\w-]+>/<id:\d+>'=>'<controller>/view',
'<controller:[\w-]+>/<action:[\w-]+>/<id:\d+>'=>'<controller>/<action>',
'<controller:[\w-]+>/<action:[\w-]+>'=>'<controller>/<action>',
// your rules go here
]
],
And a rule class of:
<?php
namespace common\components;
use Yii;
use yii\web\UrlRule;
use common\models\ObjectUrl;
class ObjectUrlRule extends UrlRule
{
public function parseRequest($manager, $request)
{
$pathInfo = trim($request->getPathInfo());
if(!$pathInfo){
return false;
}
$controller = Yii::$app->createController($pathInfo);
if($controller){
return false;
}
$objectUrl = ObjectUrl::find()->where(['url' => $pathInfo])->one();
if(!$objectUrl){
return false;
}
return $objectUrl->getUrl($pathInfo);
}
}
Where ObjectUrl is the model (table) which contains the map of user generated URLs.
The good thing about this class, as well, is that it will not run the database call unless the controller does not exist and there is a pathinfo.
I have a child class that parses urls customly that extends CBaseUrlRule.
The parseUrl() function must return a string that is 'controller/action', yet what I want to do is to be able to pass named parameters to that action. Is this possible?
For example, a url might be:
catalogName/brand/brandName/product/productname/
What I want is to redirect that path to the Catalog's index action, with that action having:
public function actionIndex($catalogName, $brandName, $productName) {
//do smthng
}
I'd make a simple url rule, but then I need the class to process certain information before parsing the url.
You can use Named Parameter by defing rules in main.php, like :
array(
'components' => array(
......
'urlManager' => array(
'urlFormat' => 'path',
'rules' => array(
'<catalogName>/brand/<brandName>/product/<productname>/' => 'catalog/index',
),
),
),
);
I have two module Student and Teacher.
I also have two different layout one is studentlayout.phtml and another is teacherlayout.phtml
How can I set studentlayout for Student module and teacherlayout for Teachermodule?
As Per Sam's answer .Thanks Its working fine.
but i also want to set two different layout For Teacher.
So i add following code in my main config file for project:
'module_layouts' => array(
'Teacher' => array(
'default' => 'layout/adminlayout',
'login' => 'layout/loginlayout',
),
'Student' => 'layout/studentlayout',
),
My module.config.php file for teacher module:
'module_layouts' => array(
'Teacher' => array(
'default' => 'layout/adminlayout',
'login' => 'layout/loginlayout',
),
'Student' => 'layout/studentlayout',
),
But all time all action of Teacher module take adminlayout. why login action can't take loginlayout?its ovveride?
Usage
Using EdpModuleLayouts is very, very simple. In any module config or autoloaded config file simply specify the following:
array(
'module_layouts' => array(
'Teacher' => 'layout/teacher',
'Student' => 'layout/student'
),
);
That's it! Of course you need to define those layouts, too... just check Application Modules module.config.php to see how to define a layout.
If you only want to change layout for your one action you can use layout() plugin in your controllers action, or if you want different layout for all actions in one controller only in your module you can do it in bootstrap:
public function onBootstrap(\Zend\EventManager\EventInterface $e) {
$eventManager = $e->getApplication()->getEventManager();
$sharedEventManager = $eventManager->getSharedManager();
$sharedEventManager->attach('Auth\Controller\AuthController', \Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'));
}
public function onDispatch(MvcEvent $e) {
$controller = $e->getTarget();
$controller->layout('layout/loginLayout');
}
After each action in that controller you will change root ViewModel layout you can go further and specify here more controllers where you want your layout like this
$sharedEventManager>attach(array('Auth\Controller\AuthController',
'Auth\Controller\Registration'),
\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'));
}
I have been trying to configure our Module.php to use the Module Manager Listeners for configuration (i.e interfaces that are available under Zend\ModuleManager\Feature\*). Specifically, I want to be able to configure the routes of my module outside of the main module.config.php. I have not been able to find any actual examples of this.
What I have found, if I have read the documentation correctly, is that the method getRouteConfig() should merge in my routes into the array provided by getConfig()?
Module.php
class Module implements Feature\RouteProviderInterface
{
//...
public function getRouteConfig()
{
return include __DIR__ . '/config/route.config.php';
}
//...
}
/config/route.config.php
return array(
'route_manager' => array(
'router' => array (
'routes' => array(
//.. routes that were working correctly when added to module.config.php
),
),
),
);
I can see the array returned via getRouteConfig() so I know the method is being called correctly.
Perhaps I am misunderstanding the purpose of the above interface, or I have not provided the correct "key" (route_manager) for this to be merged correctly, as I'm getting 404 for my routes.
Any help would be appreciated!
I haven't done this in the way you mentioned yet, but the key route_manager is not required within the getRouteConfig() Method.
This is due to the fact that all of the get{$specificManager}Config()-Methods are called directly from their respective Manager-Classes. Therefore the initial key is not required. Using another terminology, when using getRouteConfig() you are already in the scope of route_manager. Same as when you use getServiceConfig() you're already in the scope of service_manager. However getConfig() is within the application-scope and therefore accessing configuration of application-parts, you need to address tose specificaly.
One thing to note is: the configuration of getConfig() can be cached to increase performance, whereas all the other get{$specificManager}Config() methods are not. Especially in the case of the RouteConfiguration I'd highly suggest to use the getConfig()-Method for your RouteConfig.
If you really need to separate the configuration, then I'd suggest the way that #Hendriq displayed for you.
Well I have it working but I only use the getConfig(). What is do is I use an array_merge in the getConfig().
public function getConfig()
{
return array_merge(
require_once 'path_to_config/module.config.php',
require_once 'path_to_config/routes.config.php'
);
}
My router.config.php looks then like:
return [
'router' => [
'routes' => [
// routes
]
]
];
This way I also got some other config files seperated (ACL).
Edit
Thanks to the article Understanding ZF2-Configuration, I got an idea. I think your array should not be:
return array(
'route_manager' => array(
'router' => array (
'routes' => array(
//.. routes that were working correctly when added to module.config.php
)
)
)
);
but rather be
return array(
'router' => array (
'routes' => array(
//.. routes that were working correctly when added to module.config.php
),
),
);
The getRouteConfig is similar to the other providers it is there so you're able to create some custom routes. I guess what you're trying to do is most appropiate through hendriq's method.
An example of getRouteConfigcan be found at http://zf2cheatsheet.com/
public function getRouteConfig()
{
return array(
'factories' => array(
'pageRoute' => function ($routePluginManager) {
$locator = $routePluginManager->getServiceLocator();
$params = array('defaults' => array('controller' => 'routeTest','action' => 'page','id' => 'pages'));
$route = Route\PageRoute::factory($params);
$route->setServiceManager($locator);
return $route;
},
),
);
}
In our Module\Route namespace we create the class PageRoute which implements Zend\Mvc\Http\RouteInterface and, in our specific case for the example, Zend\ServiceManager\ServiceManagerAwareInterface. Now just implement the functions of the interface... In the sample he uses Doctrine to load the pages from the database.
Finally we can add our new custom route to our module.config.php so it can be used:
'page' => array(
'type' => 'pageRoute',
),
As you can see in this last step we go back to Hendriq's solution as the intended use is not to load the routes into the router, but creating custom routes.
Hope this helps
Using PHP framework Yii. As you know, default CGridView table CSS class is items. Well I want to change this value. I know it's possible for one specific widget. Like this:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->search(),
'columns'=>array(),
'itemsCssClass'=>'gridtablecss',
)); ?>
But how to do this for whole Yii application? I mean make default some another class not items
If you only want to set some static parameters for each widget then you don't need to extend the class. You can also use Yii's widgetFactory component. You can configure it in your main.php configuration file.
'components' => array(
// ...
// Default properties for some widgets
'widgetFactory' => array(
'widgets' => array(
'CGridView' => array(
'itemsCssClass' => 'gridtablecss'
),
),
),
),
Create another php file in your extensions folder, and name it MyGridView.php:
<?php
Yii::import('zii.widgets.grid.CGridView');
class MyGridView extends CGridView {
public function init() {
// Set default CSS class
$this->itemsCssClass = 'gridtablecss';
// Other modifications, i.e.: Increase page size
if ($this->dataProvider !== null)
$this->dataProvider->pagination->pageSize = 999999;
parent::init();
}
}
Now instead of using CGridView, you use your new CGridView like this:
<?php $this->widget('MyGridView', array(
Make sure your main.php config file is importing extensions:
'import' => array(
'application.extensions.*',
...
),
You can also extend CListView (and other similar core Yii classes) the same way.