Suppose I have a route like this :
$api->group(['prefix' => 'Tag/{type}'], function ($api) {
});
As you can see there is a required type parameter.
Now I want type parameter can only one of items of an array that is defined in a config file like this :
return [
'name' => 'Tag',
'types' => [
'product' => 'product',
'user' => 'user'
]
];
Means type can be product or user only. I know that I should use Regular Expression Constraints but I do not know how ?
simple!!!
create a helper file(I hope u know how to create a helper file) and make a function that return an implode version. for instance.
you created a arrayconfig.php in config folder and the code inside it is
return [
'name' => 'Tag',
'types' => [
'product' => 'product',
'user' => 'user'
]
];
now in helper.php create a function
function typechecker(){
$array = config()->get('arrayConfig.types');
return implode("|",$arr);
}
you must remember you add it to composer.json file and run a command in console
composer dump-autoload
after adding helper files
what is to be added in composer.json
if you create a folder helpers in app and your file path is
app/Helpers/helpers.php
Your composer.json will be something like this
"autoload": {
"classmap": [
....
],
"files": [
"app/Helpers/helpers.php"
],
"psr-4": {
....
}
}
just concentrate on files. rest of the section is already there. I added all code to make it understandable
Final step in your route
$api->group(['prefix' => 'Tag/{type}'], function ($api) {})->where('type', typechecker());
Cheers!!!
N.B it's 100% workable. If it does not work, that means you did something wrong
Related
I implemented CakePHP4 authentication following this:
https://book.cakephp.org/4/en/tutorials-and-examples/cms/authentication.html
It worked, then I need to use my custom PasswordHasher to satisfy the client requirements. I couldn't find any tutorial to do that, but figured out the following code works.
In Application.php:
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface {
// ....
$authenticationService->loadIdentifier('Authentication.Password', [
'fields' => [
'username' => 'username',
'password' => 'password',
],
'passwordHasher' => [
'className' => 'Authentication.MyCustom',
]
]);
The problem is that I need to put MyCustomPasswordHasher.php file in vendor\cakephp\authentication\src\PasswordHasher in order to make this work. Of course I don't want to put my own code under vendor directory.
Temporarily, I created and used src\Authentication\PasswordHasher directory and forced to make it work by doing this:
spl_autoload_register(function ($class) {
if (strpos($class, 'MyCustomPasswordHasher') !== false) {
require_once __DIR__ . '/' . str_replace(['\\', 'App/'], [DS, ''], $class) . '.php';
}
});
Is there any cleaner way to accomplish the purpose in CakePHP4? Where should I put custom codes?
Don't use plugin notation for the short name, pass only 'MyCustom', then it will look inside of your application, in the App\PasswordHasher namespace, so your class would accordingly go into
src/PasswordHasher/MyCustomPasswordHasher.php
Alternatively you can always pass a fully qualified name, meaning you could put your class wherever you want, as long as the composer autoloader can resolve it:
'passwordHasher' => [
'className' => \Some\Custom\Namespaced\PasswordHasher::class,
]
i have a little problem with smarty extension for yii2.
I've created a new smarty function, and i've added the code into this file:
backend/vendor/yiisoft/yii2-smarty/src/Extension.php
public function __construct($viewRenderer, $smarty)
{
//other code
/* CUSTOM FUNCTION REGISTER */
$smarty->registerPlugin('function', 'test', [$this, 'functionTest']);
}
//this is the custom function
public function functionTest($params, $template){
return "Test custom funcion";
}
And i can use this custom function into my template like this {test} and all works fine.
Today i have update the yii2 to the 2.0.20 version, and obviously the Extension.php file was replaced, so i can't access anymore to the custom function.
My question is: How i can add a custom function for smarty in yii2?
I'll set the config array in this way:
//this is in backend/config/main.php
'view' => [
'renderers' => [
'tpl' => [
'class' => 'yii\smarty\ViewRenderer',
'pluginDirs' => ['#backend/saSmartyPlugin'],
'widgets' =>[
'functions' => [['test' => 'test'], ],
],
//'cachePath' => '#runtime/Smarty/cache',
],
],
],
and the into saSmartyPlugin folder i insert my test.php file like this:
<?php
class Test{
function functionTest($params, $template){
return "Test custom funcion";
}
}
But i get this error:
Smarty: Undefined class 'test' in register template class
I agree with Muhammad Omer Aslam, you should extend from backend/vendor/yiisoft/yii2-smarty/src/Extension.php in order to create Any new methods and be able to use them after update. After that you just write in your config file path to your extended class.
I'll find a solution thinking about #MuhammadOmerAslam and #SergheiLeonenco suggest me.
I write this answer for anyone who has this problem.
First i create my php file Test.php and i extend the Extension class of Smarty
namespace common\components;
use yii\smarty\Extension;
class Test extends Extension{
public function __construct($viewRenderer, $smarty){
parent::__construct($viewRenderer, $smarty);// call parent construct
$smarty->registerPlugin('function', 'bread', [$this, 'functionBreadcrumbs']);//register my custom function
}
//My custom function
function functionTest($params, $template){
return "Test custom funcion";
}
And i save this file into common/components/
After that i have modified my config.php file
'view' => [
'renderers' => [
'tpl' => [
'class' => 'yii\smarty\ViewRenderer',
'extensionClass' => 'common\components\Test'
],
],
],
],
I want use route groups for FastRoute in Expressive.
Like sample:
$router = $app->getContainer()->get(FastRoute\RouteCollector::class);
$router->get('/', App\Action\HomePageAction::class);
$router->addGroup('/pages', function (FastRoute\RouteCollector $router) {
$router->get('', App\Action\PagesIndexAction::class);
$router->get('/add', App\Action\PagesAddAction::class);
$router->get('/edit/{id}', App\Action\PageEditActionFactory::class);
$router->post('/edit/{id}', App\Action\PageEditActionFactory::class);
$router->get('/another/{section}[/{subsection}]', PagesAnotherActionFactory::class);
});
I created factories as written in docs (https://docs.zendframework.com/zend-expressive/features/router/fast-route/#advanced-configuration)
And register their in router.global.php:
// ...
'factories' => [
FastRoute\RouteCollector::class => App\Container\FastRouteCollectorFactory::class,
FastRoute\DispatcherFactory::class => App\Container\FastRouteDispatcherFactory::class,
Zend\Expressive\Router\RouterInterface::class => App\Container\RouterFactory::class,
],
// ...
Now I can not figure out where to write the configuration and how to activate it.
Can this be done in the file config/router.php?
Help me, please.
you can put them in config.router.php as long as the file gets merged with the rest of your config.
'dependencies' => [
//..
'invokables' => [
/* ... */
// Comment out or remove the following line:
// Zend\Expressive\Router\RouterInterface::class => Zend\Expressive\Router\FastRouteRouter::class,
/* ... */
],
'factories' => [
/* ... */
// Add this line; the specified factory now creates the router instance:
FastRoute\RouteCollector::class => App\Container\FastRouteCollectorFactory::class,
FastRoute\DispatcherFactory::class => App\Container\FastRouteDispatcherFactory::class,
// Zend\Expressive\Router\RouterInterface::class => Zend\Expressive\Router\FastRouteRouterFactory::class, // replaced by following line
Zend\Expressive\Router\RouterInterface::class => App\Container\RouterFactory::class,
/* ... */
],
],
Note the dependencies key and that your own RouterFactory replaces the FastRouteRouterFactory because it shares the same config key.
This is not supported and I am not sure if this can be implemented in FastRoute.
You can check the thread "Zend router - child routes"
I am trying to configure Yii2 url manager in a manner that if a controller name is skipped in url it should call the default controller for action. I have managed to achieve this without action parameter. But got stuck when using parameters in action name.
Here is my route config:
return [
'catalog/category/<alias:[\w-]+>' => 'catalog/default/category',
'catalog/<action:\w+>' => 'catalog/default/<action>',
];
Controller File:
namespace app\modules\catalog\controllers;
use yii\base\Controller;
use app\modules\catalog\models\Categories;
class DefaultController extends Controller
{
public function actionShopbydepartment()
{
$data['categories'] = Categories::findParentSubHierarchy();
return $this->renderPartial('shopbydepartment', $data);
}
public function actionCategory($alias = null)
{
die(var_dump($alias));
$data['category'] = Categories::findCategoryBySlug($alias);
return $this->render('category', $data);
}
}
when I access the following url it loads perfectly.
http://domain.com/index.php/catalog/shopbydepartment
But when i access the below url it called the right function but did not pass the $alias value:
http://domain.com/index.php/catalog/category/appliances
UPDATE:
I have used the following approach for module wise url rules declaration:
https://stackoverflow.com/a/27959286/1232366
Here is what i have in the main config file:
'rules' => [
[
'pattern' => 'admin/<controller:\w+>/<action:[\w-]+>/<id:\d+>',
'route' => 'admin/<controller>/<action>'
],
[
'pattern' => 'admin/<module:\w+>/<controller:\w+>/<action:[\w-]+>/<id:\d+>',
'route' => 'admin/<module>/<controller>/<action>'
],
],
the admin is working fine and this is my first module so rest of the rules are mentioned already
Well just to help other fellows I have retrieve the value of $alias using the following approach:
$alias = \Yii::$app->request->get('alias');
But definitely this is not an accurate answer of the question. I still didn't know what i am doing wrong that i didn't get the value using the approach mentioned in question.
It wirk!
[
'name' => 'lang_country_seller_catalog',
'pattern' => '<lang:\w+>-<country:\w+>/seller/catalog/<module>/<controller>/<action>',
'route' => 'seller/catalog/<module>/<controller>/<action>',
],
[
'name' => 'lang_country_seller_catalog_attributes',
'pattern' => '<lang:\w+>-<country:\w+>/seller/catalog/attributes/<module>',
'route' => 'seller/catalog/attributes/<module>',
],
I use yii-jui to add some UI elements in the views such as datePicker. In the frontend\config\main-local.php I set the following to change the theme used by the JqueryUI:
$config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'gjhgjhghjg87hjh8878878',
],
'assetManager' => [
'bundles' => [
'yii\jui\JuiAsset' => [
'css' =>
['themes/flick/jquery-ui.css'],
],
],
],
],
];
I tried the following to override this configuration item in the controller actions method:
public function actions() {
Yii::$app->components['assetManager'] = [
'bundles' => [
'yii\jui\JuiAsset' => [
'css' =>
['themes/dot-luv/jquery-ui.css'],
],
],
];
return parent::actions();
}
Also I tried to set the value of Yii::$app->components['assetManager'] shown above to the view itself (it is partial view of form _form.php) and to the action that calls this view (updateAction). However, all this trying doesn't be succeeded to change the theme. Is there in Yii2 a method like that found in CakePHP such as Configure::write($key, $value);?
You should modify Yii::$app->assetManager->bundles (Yii::$app->assetManager is an object, not an array), e.g.
Yii::$app->assetManager->bundles = [
'yii\jui\JuiAsset' => [
'css' => ['themes/dot-luv/jquery-ui.css'],
],
];
Or if you want to keep other bundles config :
Yii::$app->assetManager->bundles['yii\jui\JuiAsset'] = [
'css' => ['themes/dot-luv/jquery-ui.css'],
];
You are going about this all wrong, you want to change the JUI theme for 1 controller alone because of a few controls. You are applying 2 css files to different parts of the website that have the potential to change styles in the layouts too. The solution you found works but it is incredibly bad practice.
If you want to change just some controls do it the proper way by using JUI scopes.
Here are some links that will help you:
http://www.filamentgroup.com/lab/using-multiple-jquery-ui-themes-on-a-single-page.html
http://jqueryui.com/download/
In this way you are making the website easier to maintain and you do not create a bigger problem for the future than you what solve.