Multiple categories in Url - yii2

I want to create links something like that:
http://example.com/cat1/itemname-1
http://example.com/cat1/cat2/itemname-2
http://example.com/cat1/cat2/cat3/itemname-3
http://example.com/cat1/cat2/cat3/[..]/cat9/itemname-9
How rule looks like in yii2 UrlManager and how to create links for this?
Url::to([
'param1' => 'cat1',
'param2' => 'cat2',
'param3' => 'cat3',
'slug' => 'itemname',
'id' => 3
]);
Above code is really bad for multiple category params.
I add that important is only last param it means ID.
Controller looks like that:
public function actionProduct($id)
{
echo $id;
}

The below url rule would to this trick but you have to build the "slug" with the categories within your controller:
'rules' => [
['route' => 'module/controller/product', 'pattern' => '<slug:(.*)+>/<id:\d+>', 'encodeParams' => false],
]
Generate the Url:
yii\helpers\Url::toRoute(['/module/controller/product', 'slug' => 'cat1/cat2/cat3', 'id' => 1])
The output would be:
example.com/cat1/cat2/cat3/1

Related

Don't create field in database

I hava code like below. It creates a field in database and show in another places. I would like to block create a database field if message field is not exit. Rest fields are taken from system. What is wrong in my code.
$delivery->comments_buro()->create([
'name' => auth()->user()->firstname,
'user_id' => auth()->user()->id,
'message' => $request['repair_report_buro'],
'icon' => 'fa fa-commenting-o',
'style' => $position->style,
]);
Thanks for help.
You need Laravel Validations for that. Please read this: https://laravel.com/docs/5.8/validation
For example:
//controller
public function index(Request $request)
{
$validator = Validator::make($request->all(), [
'message' => 'required|string',
]);
if ($validator->fails()) {
//do validation error handling here
}
// create new row in database.
}
I have a right code. It works with it. I close this question. The right code is:
if(isset($request['repair_report_buro']) && !empty($request['repair_report_buro'])){
$delivery->comments_buro()->create([
'name' => auth()->user()->firstname,
'user_id' => auth()->user()->id,
'message' => $request['repair_report_buro'],
'icon' => 'fa fa-commenting-o',
'style' => $position->style,
]);
}

data-* attributes do not work with Html::a() in Yii 2

I have the following:
Html::a('Link', ['some/route'], [
'class' => 'btn btn-lg btn-primary', // WORKS
'style' => 'padding: 100px;', // WORKS
'data-id' => 123, // DOES NOT WORK
'data' => [
'id' => 123, // DOES NOT WORK
],
]);
As per docs, both of the specified data-* attributes in Html::a helper should render their respective attributes in the HTML output, but they do not, and I do not understand why.
Yii 2 documentation on renderTagAttributes also states the following:
Renders the HTML tag attributes.
Attributes whose values are of boolean type will be treated as boolean
attributes.
Attributes whose values are null will not be rendered.
The values of attributes will be HTML-encoded using encode().
The "data" attribute is specially handled when it is receiving an
array value. In this case, the array will be "expanded" and a list
data attributes will be rendered. For example, if 'data' => ['id' =>
1, 'name' => 'yii'], then this will be rendered: data-id="1"
data-name="yii". Additionally 'data' => ['params' => ['id' => 1,
'name' => 'yii'], 'status' => 'ok'] will be rendered as:
data-params='{"id":1,"name":"yii"}' data-status="ok".
EDIT: I am trying to do this inside GridView column.
Okay, since I have used Html::a inside a GridView column, you will have to change the output format of that column. html will not work for data attributes, so you will need to switch to raw:
[
'label' => 'Actions',
'format' => 'raw',
'value' => function($model) {
return Html::a('Link', ['some/route'], [
'class' => 'btn btn-lg btn-primary', // WORKS
'style' => 'padding: 100px;', // WORKS
'data-id' => 123, // WORKS
'data' => [
'id-second' => 123, // WORKS
],
]);
},
]

Yii2: How to use map() to show two fields in a Select2?

I am using a Select2 widget for Yii2. It shows a list with the ids of the users.
I need to show two fields defined in my model called Users: first_name_user and last_name_user. Like this:
Daniel Gates
John Connor
John Doe
Maria Key
But I don't know how use map() to show more than one field.
<?= $form
->field($model, 'id_user')
->widget(\common\widgets\Select2::classname(), [
'items' => \yii\helpers\ArrayHelper::map(\app\models\Users::find()->orderBy('name_user')->all(), 'id_user', 'name_user')
])
?>
Model
Add use app\models\Users; and use yii\helpers\ArrayHelper; at top.
public function userList()
{
$userList = [];
$users = Users::find()->orderBy('first_name_user')->all();
$userList = ArrayHelper::map($users, 'id_user', function ($user) {
return $user->first_name_user.' '.$user->last_name_user;
});
return $userList;
}
_form
<?= $form->field($model, 'id_user')->widget(Select2::className(), [
'data' => $model->userList(),
'options' => ['placeholder' => 'Select User'],
]) ?>
You need to use data option instead of items for Select2.
You need to modify your query to show the concatenated first_name_user and last_name_user as an alias and then return it along with the id column to be used in Select2 by ArrayHelper::map().
It's better to add a function to the model you are using to populate the form and return the results from there to the ArrayHelper::map().
Your query should look like
function userList(){
return \app\models\Users::find()
->select([new \yii\db\Expression('[[id_user]],CONCAT([[first_name_user]]," ",[[last_name_user]]) as full_user_name')])
->orderBy('name_user')
->all();
}
Your form field should look like below
<?=
$form->field($model, 'id_user')->widget(Select2::className(), [
'data' => \yii\helpers\ArrayHelper::map($model->userList(), 'id_user', 'full_user_name'),
'options' => [
'placeholder' => 'Select User',
'id' => 'id_user'
],
'theme' => Select2::THEME_DEFAULT,
'pluginOptions' => [
'allowClear' => true
],
]);
?>

Customize prestashop web service

I want to customize Prestashop web service for my own usage but I don't know how and I can't find any tutorial. I have a mobile application that want to retrieve data from website but the default web service is useless.
For example I want the list of categories (in a language) with they're pictures but It seems I should call two different service to retrieve categories and images separately.
Assume I want to have a JSON array of categories that a category is a JSON object that have these fields {id,title,imageUrl} but It seems I should get {id,title} with a method and after that I can get images on by one by another method!
I couldn't find any guide for extending or customizing web service in the documentation.
I'm a bit late but:
Prestashop version requier : > 1.6
If you want to customize a web service and return specific fields with a JSON format output. You need to do it this way:
First
In override :
Create a class : myClassForWs that extends myClassCore
Override WebserviceRequest in webservice/WebserviceRequest.php
In webservice/WebserviceRequest.php : Add myClassForWs to
ressources:
public static function getResources()
{
$resources = parent::getResources();
$resources['myClassForWs'] = array('description' => 'The class','class' => 'myClassForWs');
ksort($resources);
return $resources;
}
}
In myClassForWs : redefine $webserviceParameters and $definition with the fields you need:
protected $definition = array(
'table' => 'category',
'primary' => 'id_category',
'multilang' => true,
'multilang_shop' => true,
'fields' => array(
'name' =>array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
'link_rewrite' =>array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
'description' =>array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
),
);
protected $webserviceParameters = array(
'objectsNodeName' =>'categories',
'hidden_fields'=>array('nleft', 'nright', 'groupBox'),
'fields' => array(
'level_depth' => array('setter' => false),
),
'associations' => array(
'images' => array(
'resource' => 'image',
'fields' => array('id' => array())
),
),
);
Then
Go in your admin tab :
in performance : clear cache
in advanced settings > Web service: active a api Key and set myClassForWs for this key
Finally
Access to your web service with url :
my.prestashop/api/myClassForWs/{id_class}?output_format=**JSON**
And it returns your datas
I hope it helps.

CakePHP 3.0 cannot get 2 items from 1 table

In a football match i have 2 clubs "Home-Club" and "Away-Club" . I have created table "match" and "club" in MySQL. In "match" table has 2 foreign key "home_id" and "away_id". I'm using cakePHP to show list matches, match information contain names of "Home-Club" and "Away-Club". How to get name of "Home-Club" and "Away-Club" in template file ( .ctp file ).
For now I using this code in the template file:
$match->club->name
Code in Controller:
public function index()
{
$this->paginate = [
'contain' => ['Club']
];
$this->set('match', $this->paginate($this->Match));
$this->set('_serialize', ['match']);
}
It always show name of "Away-Club". I don't known how to get name of "Home-Club"
Please tell me how to do it
Thanks very much!
Problem is in definition of belongsTo associations. Try to redefine it this way:
$this->belongsTo('HomeClub', [
'className' => 'Club',
'foreignKey' => 'home_id',
'propertyName' => 'home_club'
]);
$this->belongsTo('AwayClub', [
'className' => 'Club',
'foreignKey' => 'away_id',
'propertyName' => 'away_club'
]);
Names of belongsTo associations have to be unique. Now contain them in the controller
// ...
$this->paginate = [
'contain' => ['HomeClub', 'AwayClub']
];
$this->set('matches', $this->paginate($this->Match));
And then in the template use
<?= $match->home_club->name ?>
<?= $match->away_club->name ?>