How to write a url pattern for 3 modules in Yii2 ? - yii2

My urls:
1) It work
http://yii2store/backend/web/en-us/seller/catalog/products
en-us/seller/catalog/products
[
'name' => 'lang_country_module',
'pattern' => '<lang:\w+>-<country:\w+>/<module>/<controller>/<action>',
'route' => '<module>/<controller>/<action>',
],
2) It don`t work
http://yii2store/backend/web/en-us/seller/catalog/attributes/productsattributeslogisticsinfo
en-us : -
seller/catalog/attributes : 3 modules
productsattributeslogisticsinfo : controller
My full rules:
[
// Lang rule
'name' => 'lang_country',
'pattern' => '<lang:\w+>-<country:\w+>/<controller>/<action>',
'route' => '<controller>/<action>',
],
[
'name' => 'lang_country_module',
'pattern' => '<lang:\w+>-<country:\w+>/<module>/<controller>/<action>',
'route' => '<module>/<controller>/<action>',
],
[
'name' => 'lang_country_module2',
'pattern' => '<lang:\w+>-<country:\w+>/(?J)<module>/<controller>/<action>',
'route' => '<module>/<controller>/<action>',
],
[
'name' => 'lang_country_module_only',
'pattern' => '<lang:\w+>-<country:\w+>/<module>',
'route' => '<module>',
],
[
'name' => 'lang_country_module_only2',
'pattern' => '<lang:\w+>-<country:\w+>/(?J)<module>',
'route' => '<module>',
],
I dont like it http://yii2store/backend/web/seller/catalog/attributes/attributesproducts?lang=en&country=us
I want http://yii2store/backend/web/en-us/seller/catalog/attributes/attributesproducts
My

To lang param I propose use codemix/yii2-localeurls. With this you can forget about <lang:\w+> in your patter.

Related

yii2 conflict in Urlmanager

Help me find a solution for subsections.
Category: /blog/cat1/ /blog/cat/cat2/cat3/
Detail: /blog/cat/cat2/cat3/element_code
Subsection for tags in section 'blog': /blog/tag/ /blog/tag/some-tag/
I have this rules:
[
'pattern' => '/blog/tags/<title>',
'route' => 'blog/tag',
'encodeParams' => false
],
[
'pattern' => 'blog/tags/',
'route' => 'blog/tags/',
'encodeParams' => false
],
[
'pattern' => 'blog/<category:[\w_\/-]+>/<slug>',
'route' => 'blog/post',
'encodeParams' => false
],
[
'pattern' => 'blog/<category:[\w_\/-]+>',
'route' => 'blog/category',
'encodeParams' => false
],
But in tag section (/blog/tag/) Category controller starts, no Tag controller.
What to do in this case?

ZF3 zend-mvc generic route for many controllers in one module not working

I'm in ZF3, using the zend-mvc-skeleton and trying to configure a generic route that will match as many URLs as possible as I want to be able to create new controllers (including action methods of course), and have them immediately available.
The common approach described in the documentation is to write a route that matches the controller and action (same with ZF2).
Here is my 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',
],
],
],
'default' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/:controller[/:action]]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
'constraints' => [
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
],
],
],
],
'controllers' => [/* ... */],
'view_manager' => [/* ... */],
],
It works like a charm for http://localhost/ and http://localhost/application calling the indexAction() function of the IndexController class inside the /module/Application/src/IndexController.php file.
However, it's not working when I try to get the fooAction() function in the same Controller (i.e. IndexController). It's not resolving correctly http://localhost/application/foo. and I get the following error:
A 404 error occurred
Page not found.
The requested controller could not be mapped to an existing controller class.
Controller:
foo (resolves to invalid controller class or alias: foo)
No Exception available
Same error if I try http://localhost/bar/foo to get the fooAction() in the barController.
Do you have any idea of what's wrong with this? Any help will be appreciated. Many thanks.
The route http://localhost/application/foo won't resolve to fooAction() in the index controller, since /foo in the URL will match the controller not the action. With that route setup you would need to visit http://localhost/application/index/foo.
To get it working you'll also need to make sure you have aliased your controller in the config, e.g. assuming you have:
'controllers' => [
'invokables' => [
'Application\Controller\Index' => \Application\Controller\IndexController::class
]
],
Then alias the controller so it matches the route parameter:
'controllers' => [
'invokables' => [
'Application\Controller\Index' => \Application\Controller\IndexController::class
],
'aliases' => [
'index' => 'Application\Controller\Index'
]
],
You'll need to add aliases that match the route parameter for each controller that isn't registered using the string you want for the route, e.g. a controller Namespace\Controller\BarController should be aliased to bar, etc.
I came here with similar problem. I have created two controllers in
"Application" module, and two in new module "Account" with the same name.
Application/Controller/IndexController
Application/Controller/OverviewController
Account/Controller/IndexController
Account/Controller/OverviewController
here are my modules.config.php
module/Account/config/module.config.php
return [
'router' => [
'routes' => [
'Account-account' => [
'type' => Segment::class,
'options' => [
'route' => '/account[/][:controller[/][:action][/]]',
'defaults' => [
'__NAMESPACE__' => 'Account\Controller',
'controller' => Account\Controller\IndexController::class,
'action' => 'index',
'locale' => 'en_us'
],
],
'may_terminate' => true,
'child_routes' => [
'wildcard' => [
'type' => 'Wildcard'
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => AccountControllerFactory::class,
Controller\OverviewController::class => AccountControllerFactory::class,
],
'aliases' => [
'index' => IndexController::class,
'overview' => OverviewController::class
]
],
and my
module/Application/config/module.config.php
return [
'router' => [
'routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'Application-application' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/][:controller[/][:action][/]]',
'defaults' => [
'__NAMESPACE__' => 'Application\Controller',
'controller' => Application\Controller\IndexController::class,
'action' => 'index',
'locale' => 'en_US'
],
],
'may_terminate' => true,
'child_routes' => [
'wildcard' => [
'type' => 'Wildcard'
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => IndexControllerFactory::class,
Controller\OverviewController::class => IndexControllerFactory::class,
],
'aliases' => [
'index' => IndexController::class,
'overview' => OverviewController::class,
]
],
With this configuration if aliases sections are commented there is a error message which says that there is invalid controller or alias (index/overview).
If there are aliases
route: "application/overview/index" goes into Account module.

Yii2: Select2, How to set initValueText in Gridview or Tabularform?

I need to set initValueText for Select2, which is in loop, like gridview or Tabularform. but I don't know how to set right value for each.
<?= TabularForm::widget([
'dataProvider' => $dataProvider,
'form' => $form,
'actionColumn' => false,
'checkboxColumn' => false,
'attributeDefaults' => [
'type' => TabularForm::INPUT_RAW,
],
'attributes' => [
'test' => [
'type' => Form::INPUT_WIDGET,
'widgetClass' => Select2::className(),
'options' => [
'name' => 'test',
'options' => [
'class' => 'test-to-select',
],
'pluginOptions' => [
'allowClear' => true,
'minimumResultsForSearch' => 'Infinity',
'ajax' => [
'url' => Url::to(['/test/get-list']),
'dataType' => 'json',
'data' => new JsExpression('function(term,page) {
return {term : term.term};
}'),
'results' => new JsExpression('function(data,page) {
return {results:data.results};
}'),
'cache' => true
]
],
'initValueText' => 'Selected Text' /// how can I set this in gridview or Tabularform?
],
],
]
]) ?>
Of course this is not working,
'initValueText' => function($model){
retur $model->textValue;
}
Any help would be appreciated.
Into tabularform if you want dynamic initValueText, you can use options closure in this manner:
'test' => [
'type' => Form::INPUT_WIDGET,
'widgetClass' => Select2::className(),
'options' => function($model, $key, $index, $widget) {
$initValueText = empty($model['textValue']) ? '' : $model['textValue'];
return [
'name' => 'test',
'options' => [
'class' => 'test-to-select',
],
'initValueText' => $initValueText,
'pluginOptions' => [
'allowClear' => true,
'minimumResultsForSearch' => 'Infinity',
'ajax' => [
'url' => Url::to(['/test/get-list']),
'dataType' => 'json',
'data' => new JsExpression('function(term,page) {
return {term : term.term};
}'),
'results' => new JsExpression('function(data,page) {
return {results:data.results};
}'),
'cache' => true
]
],
];
}
],
If for example attribute for city, so try this..
$cityDesc = empty($model->city) ? '' : City::findOne($model->city)->description;
'initValueText' => $cityDesc, // set the initial display text
For init value first assign value to $model attribute, if you should not assign so this attribute can take value.
Set the data parameter with the array including the option you want to show. For example for cities:
'options' => [
'data' => \yii\helpers\ArrayHelper::map(\app\models\City::find()->orderBy('id')->asArray()->all(), 'id', 'name'),
]
try to put inside the options instead ouside
'widgetClass' => Select2::className(),
'options' => [
'initValueText' => 'Selected Text'
Don't use isset it return error if more the one filter are use there.
[
'attribute' => 'ad_partner_id',
'value' => function ($model, $key, $index, $widget) {
return $model->partner->name;
},
'filter' => Select2::widget([
'model' => $searchModel,
'initValueText' => !empty($searchModel->ad_partner_id) ? $searchModel->partner->name : "",
'attribute' => 'ad_partner_id',
'options' => ['placeholder' => Yii::t('app', 'Search Partner ...')],
'pluginOptions' => ['allowClear' => true, 'autocomplete' => true,
'ajax' => ['url' => Url::base() . '/partner/get-partners',
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }'),
],
],
]),
],

Get Parameters Not returning correctly when using desired urlformat

I am having a bit of trouble with get params in Yii2. I have code like the following:
Url::to(['support/about', 'id' => 100]);
And this returns the below:
/support/about.php?id=100
Which is exactly what I was after. But when I then try to reverse engineer this by entering that into the address bar and trying to get the value of id using the below:
echo Yii::$app->request->getQueryParam('id');
echo Yii::$app->request->get('id');
echo $_GET['id'];
I get nothing at all.
I do however get the correct value when I use:
/support/about/100.php
My url manager is like below:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'suffix' => '.php',
//'cache' => 'cache',
//'scriptUrl' => '',
//'baseUrl' => '/',
//'hostInfo' => 'http://www.yourhost.com.au',
'routeParam' => 'r',
'ruleConfig' => [
'class' => 'yii\web\UrlRule'
],
'rules' => array(
[
'pattern' => '',
'route' => 'site/index',
'suffix' => '',
],
[
'pattern' => '<action:\w+>',
'route' => 'site/<action>',
'suffix' => '.php',
],
[
'pattern' => '<controller:support>',
'route' => '<controller>/index',
'suffix' => '/',
],
[
'pattern' => '<controller:support>/<action:\w+>',
'route' => '<controller>/<action>',
'suffix' => '.php',
],
[
'pattern' => '<module:\w+>/<action:\w+>',
'route' => '<module>/default/<action>',
'suffix' => '.html',
],
[
'pattern' => 'gii',
'route' => 'gii',
'suffix' => '',
],
[
'pattern' => '/<controller:\w+>/<action:\w+>',
'route' => 'gii/<controller>/<action>',
'suffix' => '',
],
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
],
Let's narrow down question a bit.
Since you have issue with particular URL we can remove stuff that doesn't matter for the case from URL manager config:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'pattern' => '<controller:support>',
'route' => '<controller>/index',
'suffix' => '/',
],
[
'pattern' => '<controller:support>/<action:\w+>',
'route' => '<controller>/<action>',
'suffix' => '.php',
],
],
],
I've removed values that are the same by default, rules that never apply and global prefix since you're setting it per
rule anyway.
Now test controller:
<?php
namespace app\controllers;
use yii\web\Controller;
class SupportController extends Controller
{
public function actionIndex()
{
return 'Hello, I am index.';
}
public function actionAbout()
{
echo \yii\helpers\Html::a(\yii\helpers\Url::to(['support/about', 'id' => 10]), ['support/about', 'id' => 10]);
echo '<br>';
echo \yii\helpers\VarDumper::dump(\Yii::$app->request->get(), 10, true);
}
}
Make sure that you webserver rewrite rules are correct for .php that aren't index.php. To verify that you may
change all suffixes to .html. I did since my server is configured to serve .php directly.
When following http://example.com/support/about.html?id=10 I'm getting the following:
/support/about.html?id=10
[
'id' => '10'
]
That means Yii works fine and the problem is about webserver config.

Yii2 kartik typeahead - get number of suggestions

I'm using kartik's typeahead widget for Yii2 in a view:
echo \kartik\typeahead\Typeahead::widget([
'name' => 'serial_product',
'options' => [
'placeholder' => 'Filter as you type ...',
'autofocus' => "autofocus"
],
'scrollable' => TRUE,
'pluginOptions' => [
'highlight' => TRUE,
'minLength' => 3
],
'dataset' => [
[
'remote' => Url::to(['transfers/ajaxgetinventoryitemsnew']) . '?search=%QUERY',
'limit' => 10
]
],
'pluginEvents' => [
"typeahead:selected" => "function(obj, item) { add_item(item.id); return false;}",
],
]);
How can i get the number of loaded suggestions after the remote dataset is retrieved to execute a javascript function like:
displaynumber(NUMBEROFSUGGESTIONS);
After checking through the source of kartiks widget i came up with the following solution:
echo \kartik\typeahead\Typeahead::widget([
'name' => 'serial_product',
'options' => [
'placeholder' => 'Filter as you type ...',
'autofocus' => "autofocus",
'id' => 'serial_product'
],
'scrollable' => TRUE,
'pluginOptions' => [
'highlight' => TRUE,
'minLength' => 3
],
'dataset' => [
[
'remote' => [
'url' => Url::to(['transfers/ajaxgetinventoryitemsnew']) . '?search=%QUERY',
'ajax' => ['complete' => new JsExpression("function(response)
{
jQuery('#serial_product').removeClass('loading');
checkresult(response.responseText);
}")]
],
'limit' => 10
]
],
'pluginEvents' => [
"typeahead:selected" => "function(obj, item) { checkresult2(item); return false;}",
],
]);
where response.responseText is containing the response from server (json).
function checkresult(response) {
var arr = $.parseJSON(response);
console.log(arr.length);
}
With this function i can get then count of suggestions delivered from server.