yii2 SluggableBehavior is applied to only emty slug field - yii2

I am using SluggableBehavior in such way
public function behaviors()
{
return [
[
'class' => SluggableBehavior::className(),
'attribute' => 'name',
'slugAttribute' => 'alias',
],
];
}
It works nice If field 'alias' in form is empty.
How to ignore this behaviors If field alias is not empty on form submitting ?
thanks in advance !

Add 'immutable'=>true in the behavour config.
The behaviour works in such way, that if the slugAttribute is not empty when immutable is on, that attribute will not be changed.

Try something like:
Configure this behavior with specific name:
return [
'slug' => [
'class' => SluggableBehavior::className(),
'attribute' => 'name',
'slugAttribute' => 'alias',
],
];
In controller load attributes from the form (before validation).
Check if alias attribute is empty.
If it is not - detach this behavior ($this->detachBehavior('slug')).
Validate model.

Related

Using Yii2 TimestampBehavior returns 'created_at' doesn't have a default value error

Trying to use the Yii2 TimestampBehavior but when saving it will return a doesn't have default value error.
The values are not required in the rules. The DB column is a INT(11).
As I needed to save several rows I use batchInsert() for this.
When I add a the value with time() it will save everything to the DB.
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'created_at',
ActiveRecord::EVENT_BEFORE_UPDATE => 'updated_at',
],
'value' => new Expression('NOW()'),
],
'blameable' => [
'class' => BlameableBehavior::className(),
'createdByAttribute' => 'created_by',
'updatedByAttribute' => 'updated_by',
],
];
}
Yii::$app->db->createCommand()->batchInsert( 'table_cms',
[
//all fields but not the timestamps
],
[
//rows here
])
->execute();
batchInsert() does not support ActiveRecord features, so TimestampBehavior has no effect here. TimestampBehavior will be used if you call save(). In your case you need to pass timestamp manually.
doesn't have default value probably means that you're using MySQL in strict mode - it will warn you if you will try to add record without specifying all fields without default values.

How to display values according to it's name in DetailView yii2?

I'm trying to display category values according to it's name, not id. I'm trying to do like so:
[
'attribute' => 'category_id',
'value' => 'category.name',
],
But then attribute doesn't get displayed. It displays: name instead of Category. Category name is displayed correctly.
Also tried 'category.name' ,but it's displaying same values, and 'category_id' is displaying label correctly, but the name - according to id's.
How should I solve that?
Are you define relation for category, like this?
public function getCategory()
{
return $this->hasOne(Category::className(),['id'=>'category_id']);
}
If you want to display in GridView, you can do it like you
[
'attribute' => 'category_id',
'value' => 'category.name',
],
If you want to display in DetailView, you can do it like this
[
'attribute' => 'category_id',
'value' => $model->category ? $model->category->name : '',
],
seems you need a label.
the simplest way is add the label direcly in the detail view item
[
'label' => 'Category',
'attribute' => 'category_id',
'value' => ....,
],

Yii2 HTML purifier

I've got a question about Yii2's validation. So, my model validation rule's something like this:
return [
['status', 'required', 'on' => 'update'],
[['status'], function ($attribute) {
$this->$attribute = \yii\helpers\HtmlPurifier::process($this->$attribute);
}],
];
The problem is that if the content is <script>alert('something')</script>, it will be blank due to purifier and the content will pass the required validation.
So how can I revalidate the content for require? Or what is the good way to do it?
Validation rules are processed one after another so just put the second one as first.
return [
['status', 'filter', 'filter' => function ($value) {
return \yii\helpers\HtmlPurifier::process($value);
}],
['status', 'required', 'on' => 'update'],
];

Handle Image update in yii2

Hi everyone i am using FileInput kartik widget in yii2 project and uploading and saving works fine but i am having problem while updating the images
I can get the images path on the update form and create and array and display in as initialpreview in the widget but the problem is that my files field is required field so even there are some values in initialpreview the form gives error to upload image as its required field. So what should i do here?
I only want to give preview of their uploaded pics to the user but if they dont make any changes than i dont want to update anything for images
Following is my view code and model code
return [
[[ 'price', 'created_date', 'created_by', 'updated_date', 'updated_by','file','address'], 'required'],
[['price'], 'number'],
[['address'], 'string', 'max' => 255],
[['file'], 'file', 'extensions'=>'jpg, gif, png', 'maxFiles' => 4],
];
<?php
$initalpreview = array();
foreach($model->adsImages as $images) {
$initalpreview[] = Html::img('/upload/'.$images->image, ['class'=>'file-preview-image']);
}
?>
<?=$form->field($model, 'file[]')->widget(FileInput::classname(), [
'options' => ['accept' => 'image/*',
'multiple'=>true],
'pluginOptions' => [
'maxFileCount' => 5,
'initialPreview'=> $initalpreview,
'showUpload' => false,
]
]); ?>
So what should i do here?
Thank you
try this
In Model create a scenario named 'update' and mention the fields that are required when update action works
return [
[['price', 'created_date', 'created_by','updated_date','updated_by','address'], 'required', 'on' => 'update'],
];
Now inside controller action update call the scenario
public function actionUpdate(){
//Model Declaration
$model->scenario = 'update';
// update code
}

Yii2 create user friendly URL with parameters

Hi I've to create user friendly URL but when using with parameters it's not working.
Url:
Url::to(['site/index', 'id' => 1]);
url looks like :
localhost/testApplication/frontend/web/index.php/site/index?id=1
/forntend/config/main.php
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
//'showScriptName' => false,
'rules' => [
],
],
I want a output like
localhost/testApplication/frontend/web/index.php/site/index/id/1
and after that how to access id value in controller.
'rules' => [
'site/index/id/<id:\d+>' => 'site/index'
//'site/index/<id:\d+>' => 'site/index' Better solution
//'<controller>/<action>/<id:\d+>' => '<controller>/<action>' Will be applied for all controllers and actions
],
Routing Doc.
And after in your action :
public function actionIndex($id)
{
...
}
Is really strange, for me using the parameter 'id' always show errors, I needed to change the parameter to 'user_id', but in other parts of the code I could use, really don't know why, but try to rename the parameter.