Cant use tockens and extrapattern together for REST services in Yii2 - rest

Yii2 REST query
I found this for using custom action in the controller for that i added the extrapattern mentioned in the above link
And its working fine when we search .but cant use the normal actions for the controller
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/country',
'extraPatterns' => [
'GET search' => 'search'
],
'tokens' => [
'{id}' => '<id:\\w+>'
]
]
],
]
Regards

Thanks all
this solved my problem after lots of trying..
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/country',
'extraPatterns' => [
'GET search' => 'search'
],
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/country',
'tokens' => [
'{id}' => '<id:\\w+>'
]
],
],

Related

Zend move translator configuration from module.config.php to Module.php

I'm pretty new to ZF and have a question regarding translator configuration. I have an application with the following translator configuration inside the module.cofig file:
'translator' => [
'locale' => 'ru_RU',
'translation_file_patterns' => [
[
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
],
[
'type' => 'phparray',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.php',
],
],
'cache' => \Zend\Cache\StorageFactory::factory(
[
'adapter' => [
'name' => 'Filesystem',
'options' => [
'cache_dir' => APPLICATION_LOAD_PATH . '/data/cache',
'ttl' => '3600',
],
],
'plugins' => [
[
'name' => 'serializer',
'options' => [],
],
'exception_handler' => [
'throw_exceptions' => true,
],
],
]
),
],
This configuration works fine, but I want to know if is it possible to move this code inside Module.php trough the getTranslatorPluginConfig() . What I've tried is to use this method and return this same config:
public function getTranslatorPluginConfig(){
return [
'translator' => [
'locale' => 'ru_RU',
'translation_file_patterns' => [
[
'type' => 'gettext',
'base_dir' => __DIR__ . '/language',
'pattern' => '%s.mo',
],
[
'type' => 'phparray',
'base_dir' => __DIR__ . '/language',
'pattern' => '%s.php',
],
],
'cache' => \Zend\Cache\StorageFactory::factory(
[
'adapter' => [
'name' => Filesystem::class,
'options' => [
'cache_dir' => APPLICATION_LOAD_PATH . '/data/cache',
'ttl' => '3600',
],
],
'plugins' => [
[
'name' => 'serializer',
'options' => [],
],
'exception_handler' => [
'throw_exceptions' => true,
],
],
]
),
],
];
}
As you can see I haven't changed anything (except base_dir path). I don't get any errors, but the translator is not working at all. If you can tell me what are the steps I need to take to make this configuration work from the Module file and if this is possible at all, I'll be grateful. I don't expect plain code, but just a guidance/suggestion of what could be done, since all I find in the Zend documentation is related with making this configuration inside module.config. Thanks in advance.

Zend routing issue

I'm working on converting a (quite sloppily put together) zend expressive website to a zend framework 3 website for a local restaurant. When I set up the routing on the expressive website I would load a location based on a query parameter looking like this.
website.com/location?location=xxx
On my new website the routing looks like this
website.com/locations/view/xxx
I need to set up a route that redirects the old url to the new url. So far I have set up a route that looks for the
/location?location=[/:location]
hoping that it would recognize this 'Segment' route and load the appropriate LocationsController. Right now it is giving me a route not found error.
My code looks like below.
module.config.php
namespace Application;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'router' => [
'routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'locations-old' => [
'type' => Segment::class,
'options' => [
'route' => '/location?location=[/:location]',
'defaults' => [
'controller' => Controller\LocationController::class,
'action' => 'index',
],
],
],
'locations' => [
'type' => Segment::class,
'options' => [
'route' => '/locations[/:action[/:location]]',
'constraints' => [
'action' => '[a-zA-Z]*',
'location' => '[a-zA-Z]*',
],
'defaults' => [
'controller' => Controller\LocationController::class,
'action' => 'index',
],
],
],
'locations.html' => [
'type' => Literal::class,
'options' => [
'route' => '/locations.html',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'location' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'about' => [
'type' => Literal::class,
'options' => [
'route' => '/about',
'defaults' => [
'controller' => Controller\AboutController::class,
'action' => 'index',
],
],
],
'employ' => [
'type' => Literal::class,
'options' => [
'route' => '/employ',
'defaults' => [
'controller' => Controller\EmployController::class,
'action' => 'index',
],
],
],
'news' => [
'type' => Literal::class,
'options' => [
'route' => '/news',
'defaults' => [
'controller' => Controller\NewsController::class,
'action' => 'index',
],
],
],
],
],
'view_manager' => [
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
],
];
LocationController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Application\Model\StoreTable;
use Zend\View\Model\ViewModel;
class LocationController extends AbstractActionController
{
private $table;
public function __construct(StoreTable $table)
{
$this->table = $table;
}
public function indexAction()
{
if($_GET['location'] && $this->table->doesExist($_GET['location'])) {
$location = $_GET['location'];
$this->redirect()->toRoute('locations', ['action' => 'view', 'location' => $location])->setStatusCode(302);
} else {
$this->redirect()->toUrl('/#locations')->setStatusCode(301);
}
}
public function viewAction()
{
$location = (string) $this->params()->fromRoute('location');
$store = $this->table->getStore($location);
return new ViewModel([
'store' => $store,
]);
}
}
Any help would be greatly appreciated and I can provide more info if needed.
Thanks!
configure your route as following, this will be handle query based url as you given "website.com/location?location=xxx",
In below route ":key" variable implies ?location=xxx
'locations-old' => [
'type' => Segment::class,
'options' => [
'route' => '/location/:key',
'defaults' => [
'controller' => Controller\LocationController::class,
'action' => 'index',
],
'constraints' => [
'key' => '[a-z0-9]+',
],
],
'child_routes' => [
'query' => ['type' => 'query'],
],
]

Yii2 Rest Custom actions with OPTIONS request

I am working on api up to now it has only been tested in Postman so cors wasnt an issue. However now developing the front end and when it comes to custom Yii actions they are failing the preflight request. I solved this by adding these lines to url-manager config:
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/call-rates'],
'pluralize' => false,
'extraPatterns' => [
'OPTIONS' => 'options',
'GET all-resellers' => 'all-resellers',
'POST updatefromcsv' => 'updatefromcsv',
'OPTIONS all-resellers' => 'options',
'OPTIONS updatefromcsv' => 'options',
// other end points....
],
So every custom action has to have a corresponding OPTIONS pattern. I have seen on a similar question that it is possible to apply the OPTIONS pattern to all custom actions in one line like so:
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'v1/call-rates',
// rest of controllers...
],
'pluralize' => false,
'extraPatterns' => [
'OPTIONS <action:\w+>' => 'options',
],
],
However that is not working. I have also tried with a token like this:
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'v1/call-rates'
],
'tokens' => [
'{action}' => '<action:\\w+>',
],
'pluralize' => false,
'extraPatterns' => [
'OPTIONS {action}' => 'options',
],
],
But again no luck. Any help would be appreciated. Thank you in advance.
Solved by adding the following in to urlmanager config:
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'v1/call-rates',
'v1/call-recordings',
],
'tokens' => [
'{action}' => '<action:[a-zA-Z0-9\\-]+>',
],
'pluralize' => false,
'extraPatterns' => [
'OPTIONS {action}' => 'options',
'OPTIONS' => 'options'
],
],
Because my custom actions were named like:
public function actionGetResellers
The Url would be get-resellers so the pattern was incorrect as it didn't accept -'s. So now what whatever controller I add it will add OPTIONS pattern for every custom action
I use Regular Expression <action:\w+-\w+>. Here is the solution:
[
'class' => 'yii\rest\UrlRule', //
'controller' => 'v1/content/my',
'pluralize' => false,
'extraPatterns' => [
'OPTIONS <action:\w+-\w+>' => 'options',
'GET foot-print' => 'foot-print',
'GET my-courses' => 'my-courses',
]

Method not allowed(#405)

following code throws out error like this:
"Method Not Allowed (#405)
Method Not Allowed. This url can only handle the following request methods: ."
Any ideas,how to fix this?
['label' => 'Logout', 'url' => ['/site/logout'], 'linkOptions' => ['data' => ['method' => 'post']]],
Here is still method in SiteController:
public function actionLogout() {
Yii::$app->user->logout();
return $this->goHome();
}
use data-method in linkOptions
['label' => 'logOut',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']
],
notice:check behavior in sitecontroller
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'dashboard'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}

rewrite POST method on rest api yii2

I must rewrite post request on rest yii2.
Every time i've post request on url v1/availability
I want to call actionCreate for manage request.
This is my main.php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability'],
'pluralize' => true,
'extraPatterns' => [
'POST v1/availability' => 'v1/availability/create'
]
],
'OPTIONS v1/user/login' => 'v1/user/login',
'POST v1/user/login' => 'v1/user/login',
'POST v2/user/login' => 'v2/user/login',
'OPTIONS v2/user/login' => 'v2/user/login',
],
],
In the v1/controllers/AvailabilityController.php
i've
public function actions()
{
$actions = parent::actions();
unset($actions['view']);
return array_merge(
$actions,
[
'index' => [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
'prepareDataProvider' => [$this, 'index']
],
]
);
}
public function actionCreate(){
throw new \yii\web\HttpException(200, 'IT WORKS!', 200);
}
Any idea?
add url rule outside like below.
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability']
],
'POST v1/availability' => 'v1/availability/create',
'OPTIONS v1/user/login' => 'v1/user/login',
'POST v1/user/login' => 'v1/user/login',
'POST v2/user/login' => 'v2/user/login',
'OPTIONS v2/user/login' => 'v2/user/login',
],
],
And here you need understand rules of Yii. if you add one rule like below.
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
this open many urls for clients.
[
'PUT,PATCH users/<id>' => 'user/update',
'DELETE users/<id>' => 'user/delete',
'GET,HEAD users/<id>' => 'user/view',
'POST users' => 'user/create',
'GET,HEAD users' => 'user/index',
'users/<id>' => 'user/options',
'users' => 'user/options',
]
above all urls will open for clients.
So...
there are 2 way to override post.
First #Irfan Ali method
This method permit to declare single call in main.php and work with single function in controller.
Second method is
in main.php declare general call to availability
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability'],
'pluralize' => true,
],
],
],
for intercept post method you must override in the controller
public function createAction($id){
throw new \yii\web\HttpException(200, 'You receive post or put', 200);
}
and in this function you must intercept if call is post you do anything.
I love first method!