Can't set property of object if this property is array - php

yii advanced 2.0.13
#property $content keeps array (before saving in DB it will be encoded in json in database.)
#property string $name
So in ActiveForm I have inputs with names like content[image] or content[anykey], also I have not-array properties like name; I want to put new values after Post, well:
echo $model->name; // output: Test
$model->name = 'any new name';
echo $model->name; // any new name
It works, but
print_r($model->content);
/* output
Array
(
[title] => bla
[anykey] =>
[seo-title] => bla-bla
)*/
$model->content['anykey'] = 'bla-bla-bla';
echo $model->content['anykey']; // null output:
It doesn't. We can not set new value in array property, so I tried next tip:
$content = $model->content;
$content['anykey'] = 'bla-bla-bla';
$model->content = $content;
echo $model->content['anykey']; // bla-bla-bla
It works
Can somebody explain, why is this happening?
Controller
<?php
namespace backend\controllers;
use Yii;
use common\models\Categories;
use backend\models\CategoriesCRUD;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\UploadedFile;
/**
* CategoriesController implements the CRUD actions for Categories model.
*/
class CategoriesController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
...
/**
* Updates an existing Categories model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
// here I put code above
$model->content['anykey'] = 'bla-bla-bla';
echo $model->content['anykey']; // old value
// die();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
}
Model
<?php
namespace common\models;
use Yii;
use yii\web\UploadedFile;
/**
* This is the model class for table "{{%categories}}".
*
* #property integer $id
* #property string $name
* #property integer $status
* #property integer $sort_order
* #property integer $parent_id
* #property string $content
*
* #property Categories $parent
* #property Categories[] $categories
* #property CategoriesRelationships[] $categoriesRelationships
* #property CategoriesRelationships[] $categoriesRelationships0
* #property ProductsToCategories[] $productsToCategories
*/
class Categories extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return '{{%categories}}';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['name'], 'required'],
[['status', 'sort_order'], 'integer'],
['content', 'each', 'rule' => ['trim']],
[['name'], 'string', 'max' => 255],
[['parent_id'], 'exist', 'skipOnError' => true, 'targetClass' => Categories::className(), 'targetAttribute' => ['parent_id' => 'id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Заголовок',
'status' => 'Показывать',
'sort_order' => 'Порядок сортировки',
'parent_id' => 'Родительская категория',
'content' => 'Содержание',
];
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
/* Обработка данных перед занесением в базу
в content содержится любая контентная информация
*/
// #TODO добавить собственную валидацию изображений и свои методы для их обработки (Для категорий, аватарок и прч)
// here I put solution, but before I found it I've been trying in Controller
$content = (array) $this->content;
$content['image'] = $this->uploadImage($this, $content, 'image', 'content[image]');
$this->content = $content;
$this->content = json_encode($this->content, JSON_UNESCAPED_UNICODE);
return true;
}
return false;
}
}

Although it is not directly an answer to your question:
I'd suggest to use different attributes for the serialized value, say serializedContent. This way - content is always an array, and serializedContent is always a json string.
Then create a setter and a getter in your model:
public function setContent($value) {
$this->serializedContent = json_encode($value);
}
public function getContent() {
return json_decode($this->serializedContent,true);
}

Related

Search Filtering users by FK in gridview

I have users table containing : PK - id, username, password.
i have three tables ( laptop, display, phone) - id - FK, series, model
I have userequipmentmapping table containing : id - PK , user_id - FK( id from users table), laptop_id - FK (id from laptop table), phone_id - FK (id from phone table), display_id(id from dislpay table), start_date, end_date.
I want to search by user in my gridview from UserEquipmentMapping, but don't know where should i implement the search model, considering the username is passed from the users table by foreign key.
If you have any suggestions are appreciated. Thank You in advance !
Controller :
<?php
namespace app\controllers;
use Yii;
use app\models\UserEquipmentMapping;
use app\models\UserequipmentmappingSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use app\models\User;
use app\models\Laptop;
use app\models\Phone;
use app\models\Display;
/**
* UserequipmentmappingController implements the CRUD actions for UserEquipmentMapping model.
*/
class UserequipmentmappingController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all UserEquipmentMapping models.
* #return mixed
*/
public function actionIndex()
{
$usermodel = new UserEquipmentMapping();
$userquery = $usermodel->getUsers();
$displaymodel = new UserEquipmentMapping();
$displayquery = $displaymodel->getDisplays();
$phonemodel = new UserEquipmentMapping();
$phonequery = $phonemodel->getPhones();
$laptopmodel = new UserEquipmentMapping();
$laptopquery = $laptopmodel->getLaptops();
#foreach($query as $q)
# print_r($q);
#
# die;
$searchModel = new UserequipmentmappingSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'userquery' => $userquery,
'displayquery' => $displayquery,
'laptopquery'=> $laptopquery,
'phonequery'=> $phonequery,
]);
}
/**
* Displays a single UserEquipmentMapping model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new UserEquipmentMapping model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new UserEquipmentMapping();
$usermodel = User::find()->all();
$laptopmodel = Laptop::find()->all();
$phonemodel = Phone::find()->all();
$displaymodel = Display::find()->all();
#print_r(Yii::$app->request->post()); die;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
'usermodel' => $usermodel,
'laptopmodel' => $laptopmodel,
'phonemodel' => $phonemodel,
'displaymodel' => $displaymodel,
]);
}
/**
* Updates an existing UserEquipmentMapping model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
$usermodel = User::find()->all();
$laptopmodel = Laptop::find()->all();
$phonemodel = Phone::find()->all();
$displaymodel = Display::find()->all();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
'usermodel' => $usermodel,
'laptopmodel' => $laptopmodel,
'phonemodel' => $phonemodel,
'displaymodel' => $displaymodel,
]);
}
/**
* Deletes an existing UserEquipmentMapping model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the UserEquipmentMapping model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return UserEquipmentMapping the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = UserEquipmentMapping::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}
Model :
<?php
namespace app\models;
use Yii;
use app\models\User;
use app\models\UserQuery;
use yii\db\ActiveQuery;
/**
* This is the model class for table "user_equipment_mapping".
*
* #property int $id
* #property int $user_id
* #property int|null $laptop_id
* #property int|null $phone_id
* #property int|null $display_id
* #property string|null $start_date
* #property string|null $stop_date
*
* #property Display $display
* #property Laptop $laptop
* #property Phone $phone
* #property User $user
*/
class UserEquipmentMapping extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'user_equipment_mapping';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['user_id'], 'required'],
[['user_id', 'laptop_id', 'phone_id', 'display_id'], 'integer'],
[['start_date', 'stop_date'], 'safe'],
[['display_id'], 'exist', 'skipOnError' => true, 'targetClass' => Display::className(), 'targetAttribute' => ['display_id' => 'id']],
[['laptop_id'], 'exist', 'skipOnError' => true, 'targetClass' => Laptop::className(), 'targetAttribute' => ['laptop_id' => 'id']],
[['phone_id'], 'exist', 'skipOnError' => true, 'targetClass' => Phone::className(), 'targetAttribute' => ['phone_id' => 'id']],
[['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'user_id' => 'User ID',
'laptop_id' => 'Laptop ID',
'phone_id' => 'Phone ID',
'display_id' => 'Display ID',
'start_date' => 'Start Date',
'stop_date' => 'Stop Date',
];
}
/**
* Gets query for [[Display]].
*
* #return \yii\db\ActiveQuery|DisplayQuery
*/
public function getDisplay()
{
return $this->hasOne(Display::className(), ['id' => 'display_id']);
}
/**
* Gets query for [[Laptop]].
*
* #return \yii\db\ActiveQuery|LaptopQuery
*/
public function getLaptop()
{
return $this->hasOne(Laptop::className(), ['id' => 'laptop_id']);
}
/**
* Gets query for [[Phone]].
*
* #return \yii\db\ActiveQuery|PhoneQuery
*/
public function getPhone()
{
return $this->hasOne(Phone::className(), ['id' => 'phone_id']);
}
/**
* Gets query for [[User]].
*
* #return \yii\db\ActiveQuery|UserQuery
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
public function getUsers()
{
return $this->hasMany(User::className(),['user_id', 'id']);
}
public function getLaptops()
{
return $this->hasMany(Laptop::className(),['laptop_id', 'id']);
}
public function getDisplays()
{
return $this->hasMany(Display::className(),['dislpay_id', 'id']);
}
public function getPhones()
{
return $this->hasMany(Phone::className(),['phone_id', 'id']);
}
/**
* {#inheritdoc}
* #return UserEquipmentMappingQuery the active query used by this AR class.
*/
public static function find()
{
return new UserEquipmentMappingQuery(get_called_class());
}
}
ModelSearch :
<?php
namespace app\models;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\UserEquipmentMapping;
/**
* UserequipmentmappingSearch represents the model behind the search form of `app\models\UserEquipmentMapping`.
*/
class UserequipmentmappingSearch extends UserEquipmentMapping
{
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['id', 'user_id', 'laptop_id', 'phone_id', 'display_id'], 'integer'],
[['start_date', 'stop_date'], 'safe'],
];
}
/**
* {#inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = UserEquipmentMapping::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'user_id' => $this->user_id,
'laptop_id' => $this->laptop_id,
'phone_id' => $this->phone_id,
'display_id' => $this->display_id,
'start_date' => $this->start_date,
'stop_date' => $this->stop_date,
]);
return $dataProvider;
}
}
Index :
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel app\models\UserequipmentmappingSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'User Equipment Mappings';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="user-equipment-mapping-index">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Create User Equipment Mapping', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'formatter' => [
'class' => 'yii\i18n\Formatter',
'nullDisplay' => '-',],
'columns' => [
['class' => 'yii\grid\SerialColumn'],
#'id',
'user.username',
#'laptop.laptop_model',
'laptop.laptop_series',
#'laptop_id',
#'phone.phone_model',
'phone.phone_series',
#'phone_id',
#'display.display_model',
'display.display_series',
#'display_id',
'start_date',
'stop_date',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
Uncomment in your index view _search view. There are all fields from UserequipmentmappingSearch model. You can replace input fields with select fields for user, laptop and etc. Search model will do the other thing, all is in search function that fills your dataprovider

Yii2 tagging 2amigos is not saving tags to the table

I am trying to implement tagged articles for my new small CMS written with yii2.
This is what i have tried https://forum.yiiframework.com/t/how-to-create-tags-for-posts-in-yii2/123890
Everything is working the tagging machanism is fetching data from the tag table but it is not saving data to the table tag_assign.
This is my form.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
//Using for Wysiwig editor
use dosamigos\ckeditor\CKEditor;
//Using for Tagging
use dosamigos\selectize\SelectizeTextInput;
/* #var $this yii\web\View */
/* #var $model common\models\Articles */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="articles-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'content')->widget(CKEditor::className(), [
'options' => ['height' => 800],
'preset' => 'basic',
'clientOptions' => ['height' => 400]
]) ?>
<?= $form->field($model, 'tags')->widget(SelectizeTextInput::className(), [
// calls an action that returns a JSON object with matched
// tags
'loadUrl' => ['tag/list'],
'options' => ['class' => 'form-control'],
'clientOptions' => [
'plugins' => ['remove_button'],
'valueField' => 'name',
'labelField' => 'name',
'searchField' => ['name'],
'create' => true,
],
])->hint('Use commas to separate tags') ?>
<?= $form->field($model, 'date')->textInput() ?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
And this is my tag model
<?php
namespace common\models;
use Yii;
use dosamigos\taggable\Taggable;
/**
* This is the model class for table "tags".
*
* #property int $id
* #property string $frequency
* #property string $name
*/
class Tag extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'tags';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['frequency', 'name'], 'required'],
[['frequency'], 'string', 'max' => 500],
[['name'], 'string', 'max' => 250],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'frequency' => 'Frequency',
'name' => 'Name',
];
}
//For Tagging
public function behaviors() {
return [
[
'class' => Taggable::className(),
],
];
}
public function findAllByName($name)
{
return Tag::find()->where('name LIKE :query')
->addParams([':query'=>"%$name%"])
->all();
}
}
Tag controller.
<?php
namespace backend\controllers;
use Yii;
use common\models\Tag;
use common\models\searchTag;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\Response;
/**
* TagController implements the CRUD actions for Tag model.
*/
class TagController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Tag models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new searchTag();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Tag model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Tag model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Tag();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
]);
}
public function actionList($query)
{
$models = Tag::findAllByName($query);
$items = [];
foreach ($models as $model) {
$items[] = ['name' => $model->name];
}
// We know we can use ContentNegotiator filter
// this way is easier to show you here :)
Yii::$app->response->format = Response::FORMAT_JSON;
return $items;
}
/**
* Updates an existing Tag model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
]);
}
/**
* Deletes an existing Tag model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Tag model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Tag the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Tag::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}
And the articles
<?php
namespace common\models;
use Yii;
//For Taggable
use dosamigos\taggable\Taggable;
/**
* This is the model class for table "articles".
*
* #property int $id
* #property string $title
* #property string $content
* #property string $tags
* #property string $date
*/
class Articles extends \yii\db\ActiveRecord
{
//For taggable
public function behaviors() {
return [
[
'class' => Taggable::className(),
],
];
}
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'articles';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['title', 'content', 'tags', 'date'], 'required'],
[['content'], 'string'],
[['date'], 'safe'],
[['title', 'tags'], 'string', 'max' => 250],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
'content' => 'Content',
'tags' => 'Tags',
'date' => 'Date',
];
}
public function getTags()
{
return $this->hasMany(Tag::className(), ['id' => 'tag_id'])->viaTable('tag_assign', ['article_id' => 'id']);
}
}
What I am missing? How can I trouble shoot at least what is going wrong?

Show Related Data in View Yii 2

I'm new in Yii 2, and I'm creating an inventory system for the library of my school, but I had a problem.
First, I have a relation like this:
I want to show all the adqs (a unique number for each book - that way we don't need to capture the book again for every copy) of a book in his view, but only the adqs related to the book id obviously at the bottom.
My View:
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
use yii\helpers\Url;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $model app\models\Libros */
/* #var $searchModel app\models\LibrosSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = $model->lib_titulo;
$this->params['breadcrumbs'][] = ['label' => 'Libros', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="libros-view">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Modificar', ['update', 'id' => $model->lib_id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Borrar', ['delete', 'id' => $model->lib_id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
</p>
<div class="row" align="center">
<?php
if ($model->lib_image_web_filename!='') {
echo '<br /><p><img width="500" src="'.Url::to('#web/', true). '/uploads/libros/'.$model->lib_image_web_filename.'"></p>';
}
?>
</div>
<div class="row" style="
text-align: center;
font: normal normal bold 15px/1 'lato';
color: rgba(7,7,7,1);
text-align: center;
">
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'lib_id',
'lib_titulo',
'lib_autor',
//'lib_edicion',
'editorialNombre',
'ubicacionNombre',
'lib_isbn',
'lib_clasificacion',
'lib_seccion',
//'lib_image_src_filename',
//'lib_image_web_filename',
],
]) ?>
</div>
</div>
My Controller (LibrosController):
<?php
namespace backend\controllers;
use Yii;
use app\models\Libros;
use app\models\LibrosSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\UploadedFile;
/**
* LibrosController implements the CRUD actions for Libros model.
*/
class LibrosController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Libros models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new LibrosSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Libros model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionCreate()
{
$model = new Libros();
if ($model->load(Yii::$app->request->post())) {
$image = UploadedFile::getInstance($model, 'image');
if (!is_null($image)) {
$model->lib_image_src_filename = $image->name;
$ext = end((explode(".", $image->name)));
// generate a unique file name to prevent duplicate filenames
$model->lib_image_web_filename = Yii::$app->security->generateRandomString().".{$ext}";
// the path to save file, you can set an uploadPath
// in Yii::$app->params (as used in example below)
Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/web/uploads/libros/';
$path = Yii::$app->params['uploadPath'] . $model->lib_image_web_filename;
$image->saveAs($path);
}
if ($model->save()) {
return $this->redirect(['view', 'id' => $model->lib_id]);
} else {
var_dump ($model->getErrors()); die();
}
}
return $this->render('create', [
'model' => $model,
]);
}
/**
* Updates an existing Libros model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$image = UploadedFile::getInstance($model, 'image');
if (!is_null($image)) {
$model->lib_image_src_filename = $image->name;
$ext = explode(".", $image->name);
$ext_final = end($ext);
// generate a unique file name to prevent duplicate filenames
$model->lib_image_web_filename = Yii::$app->security->generateRandomString().".{$ext_final}";
// the path to save file, you can set an uploadPath
// in Yii::$app->params (as used in example below)
Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/web/uploads/libros/';
$path = Yii::$app->params['uploadPath'] . $model->lib_image_web_filename;
$image->saveAs($path);
}
if ($model->save()) {
return $this->redirect(['view', 'id' => $model->lib_id]);
} else {
var_dump ($model->getErrors()); die();
}
}
return $this->render('create', [
'model' => $model,
]);
}
/**
* Deletes an existing Libros model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Libros model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Libros the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Libros::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}
My Model (Libros.php):
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "libros".
*
* #property int $lib_id
* #property string $lib_titulo
* #property string $lib_autor
* #property string $lib_edicion
* #property int $lib_ubi
* #property int $lib_editorial_id
* #property string $lib_isbn
* #property string $lib_clasificacion
* #property string $lib_seccion
* #property string $lib_image_src_filename
* #property string $lib_image_web_filename
*
* #property Adq[] $adqs
* #property Editorial $libEditorial
* #property Ubicacion $libUbi
* #property LibrosCarreras[] $librosCarreras
* #property Carreras[] $licCarreras
*/
class Libros extends \yii\db\ActiveRecord
{
const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20;
public $image;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'libros';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['lib_titulo', 'lib_autor', 'lib_ubi', 'lib_isbn', 'lib_clasificacion', 'lib_seccion', 'lib_image_src_filename', 'lib_image_web_filename'], 'required'],
[['lib_ubi', 'lib_editorial_id'], 'integer'],
[['lib_titulo'], 'string', 'max' => 120],
[['lib_autor', 'lib_clasificacion'], 'string', 'max' => 64],
//[['lib_edicion'], 'string', 'max' => 3],
[['lib_isbn'], 'string', 'max' => 32],
[['lib_seccion'], 'string', 'max' => 2],
[['lib_editorial_id'], 'exist', 'skipOnError' => true, 'targetClass' => Editorial::className(), 'targetAttribute' => ['lib_editorial_id' => 'edi_id']],
[['lib_ubi'], 'exist', 'skipOnError' => true, 'targetClass' => Ubicacion::className(), 'targetAttribute' => ['lib_ubi' => 'ubil_id']],
[['lib_image_src_filename', 'lib_image_web_filename'], 'string', 'max' => 100],
[['image'], 'safe'],
[['image'], 'file', 'extensions'=>'jpg, gif, png'],
[['image'], 'file', 'maxSize'=>'1000000'],
[['lib_image_src_filename', 'lib_image_web_filename'], 'string', 'max' => 255], ];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'lib_id' => 'ID',
'lib_titulo' => 'Titulo',
'lib_autor' => 'Autor',
//'lib_edicion' => 'Edicion',
'lib_editorial_id' => 'Editorial',
'lib_isbn' => 'ISBN',
'lib_clasificacion' => 'Clasificacion',
'lib_ubi' => 'Ubicacion',
'lib_seccion' => 'Seccion',
'image' => 'Captura',
'lib_image_src_filename' => Yii::t('app', 'Nombre de Archivo'),
'lib_image_web_filename' => Yii::t('app', 'Nombre del Directorio'),
'editorialNombre' => 'Editorial',
'ubicacionNombre' => 'Ubicacion',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getAdqs()
{
return $this->hasMany(Adq::className(), ['adq_libro_id' => 'lib_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
/**
* #return \yii\db\ActiveQuery
*/
public function getLibrosCarreras()
{
return $this->hasMany(LibrosCarreras::className(), ['lic_libros_id' => 'lib_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getEditorial0()
{
return $this->hasOne(Editorial::className(), ['edi_id' => 'lib_editorial_id']);
}
public function getEditorialNombre()
{
return $this->editorial0->edi_nombre;
}
public function getLibUbi()
{
return $this->hasOne(Ubicacion::className(), ['ubil_id' => 'lib_ubi']);
}
public function getUbicacionNombre()
{
return $this->libUbi->ubil_nombre; }
}
My Search Model (LibrosSearch.php):
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Libros;
/**
* LibrosSearch represents the model behind the search form of `app\models\Libros`.
*/
class LibrosSearch extends Libros
{
public $editorialNombre;
public $ubicacionNombre;
/**
* #inheritdoc
*/
public function rules()
{
return [
[['lib_id', 'lib_ubi', 'lib_editorial_id'], 'integer'],
[['lib_titulo', 'lib_autor', 'lib_isbn', 'lib_clasificacion', 'lib_seccion', 'lib_image_src_filename', 'lib_image_web_filename'], 'safe'],
[['editorialNombre'],'safe'],
[['ubicacionNombre'],'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = Libros::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->setSort([
'attributes'=>[
'editorialNombre'=>[
'asc'=>['editorial.edi_nombre'=>SORT_ASC],
'desc'=>['editorial.edi_nombre'=>SORT_DESC],
'label'=>'Editorial Nombre'
]
]
]);
$dataProvider->setSort([
'attributes'=>[
'ubicacionNombre'=>[
'asc'=>['ubicacion.ubil_nombre'=>SORT_ASC],
'desc'=>['ubicacion.ubil_nombre'=>SORT_DESC],
'label'=>'Ubicacion Nombre'
]
]
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'lib_id' => $this->lib_id,
'lib_ubi' => $this->lib_ubi,
'lib_editorial_id' => $this->lib_editorial_id,
]);
$query->andFilterWhere(['like', 'lib_titulo', $this->lib_titulo])
->andFilterWhere(['like', 'lib_autor', $this->lib_autor])
//->andFilterWhere(['like', 'lib_edicion', $this->lib_edicion])
->andFilterWhere(['like', 'lib_isbn', $this->lib_isbn])
->andFilterWhere(['like', 'lib_clasificacion', $this->lib_clasificacion])
->andFilterWhere(['like', 'lib_seccion', $this->lib_seccion])
->andFilterWhere(['like', 'lib_image_src_filename', $this->lib_image_src_filename])
->andFilterWhere(['like', 'lib_image_web_filename', $this->lib_image_web_filename]);
$query->joinWith(['editorial0'=>function($q)//creamos un nuevo filtro
{
$q->where('editorial.edi_nombre LIKE "%' . $this->editorialNombre . '%"');
}]);
$query->joinWith(['libUbi'=>function($q)//creamos un nuevo filtro
{
$q->where('ubicacion.ubil_nombre LIKE "%' . $this->ubicacionNombre . '%"');
}]);
return $dataProvider;
}
}
How can I accomplish this task?
[
'attribute' => 'adq_libro_id',
'value' => implode(', ', \yii\helpers\ArrayHelper::map($model->Adqs, 'id',
function ( $model )
{
return $model['adq'];
}
)),
'format' => 'raw'
],
try like this. Check the right name of attributes
In your model Libros.php you have this function.
public function getAdqs()
{
return $this->hasMany(Adq::className(), ['adq_libro_id' => 'lib_id']);
}
This means you can access the relations of Libros like:
// where $model is an instance of Libros
$model->adqs->property_name
Or as a function
$model->getAdqs();

Yii2 multiple table in gridview

I have 2 tables with strategy and risk_colors .
I generated Model and CRUD with GII and modified it just a little to get risk_value column in my GridView widget.
Here is my Strategy.php
<?php
namespace backend\models;
use Yii;
use yii\db\ActiveRecord;
use yii\helpers\Url;
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use yii\db\Expression;
/**
* This is the model class for table "strategy".
*
* #property int $id
* #property string $strategy_title
* #property string $strategy_description
* #property string $strategy_current_money
* #property int $risk_colors_id
*
* #property SelectedStrategies[] $selectedStrategies
* #property RiskColors $riskColors
*/
class Strategy extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'strategy';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['strategy_title', 'strategy_description', 'strategy_current_money', 'risk_colors_id'], 'required'],
[['strategy_current_money', 'risk_colors_id'], 'integer'],
[['strategy_title'], 'string', 'max' => 255],
[['strategy_description'], 'string', 'max' => 2055],
[['risk_colors_id'], 'exist', 'skipOnError' => true, 'targetClass' => RiskColors::className(), 'targetAttribute' => ['risk_colors_id' => 'id']],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'strategy_title' => 'Strategy Title',
'strategy_description' => 'Strategy Description',
'strategy_current_money' => 'Strategy Current Money',
'risk_colors_id' => 'Risk Color ID',
'riskValue' => Yii::t('app', 'Risk'),
'colorNumber' => 'Color Number',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getSelectedStrategies()
{
return $this->hasMany(SelectedStrategies::className(), ['strategy_id' => 'id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getRiskColors()
{
return $this->hasOne(RiskColors::className(), ['id' => 'risk_colors_id']);
}
/**
* #return risk value
*/
public function getRiskValue()
{
return $this->riskColors->risk_value;
}
/**
* #return Get risk value list for dropdown
*/
public function getRiskValueList()
{
$droptions = RiskColors::find()->asArray()->all();
return ArrayHelper::map($droptions, 'id', 'risk_value');
}
/**
* #return Get risk value list for dropdown
*/
public function getColorNumberList()
{
$droptions = RiskColors::find()->asArray()->all();
return ArrayHelper::map($droptions, 'id', 'color_number');
}
}
here is my index.php.
After all i got risk_value column in my GridView, but it looks like i cant sort my table by this field. Here is .
Here is my Search Model
So my question is what should i do to make this field sortable?
In your StrategySearch.php
public function search($params)
{
$query = Strategy::find()->joinWith(['riskColors']);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->sort->attributes['risk_colors_id'] = [
'asc' => ['risk_colors.risk_value' => SORT_ASC],
'desc' => ['risk_colors.risk_value' => SORT_DESC],
];
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'strategy_current_money' => $this->strategy_current_money,
// 'risk_colors_id' => $this->risk_colors_id,
'risk_colors.risk_value' => $this->risk_colors_id
]);
$query->andFilterWhere(['like', 'strategy_title', $this->strategy_title])
->andFilterWhere(['like', 'strategy_description', $this->strategy_description]);
return $dataProvider;
}
Refere GridView Sorting

on calling new created controller function it navigates to 404 error page

in yii2 advanced template site Controller is working fine. When calling a function in new controller it is navigating to 404 error page.
I created model using model generator and create a crude for the model.
This is my controller
namespace backend\Controllers;
use Yii;
use common\models\PackageTable;
use common\models\PackageTableSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* PackageTableController implements the CRUD actions for PackageTable model.
*/
class PackageTableController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all PackageTable models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new PackageTableSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single PackageTable model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new PackageTable model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new PackageTable();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->package_id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
/**
* Updates an existing PackageTable model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->package_id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing PackageTable model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the PackageTable model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return PackageTable the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = PackageTable::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
This is my model
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "package_table".
*
* #property integer $package_id
* #property string $package_name
* #property string $description
* #property integer $amount
* #property integer $status
* #property string $created_on
* #property string $updated_on
*/
class PackageTable extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'package_table';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['package_name', 'description', 'amount', 'status'], 'required'],
[['description'], 'string'],
[['amount', 'status'], 'integer'],
[['created_on', 'updated_on'], 'safe'],
[['package_name'], 'string', 'max' => 250],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'package_id' => 'Package ID',
'package_name' => 'Package Name',
'description' => 'Description',
'amount' => 'Amount',
'status' => 'Status',
'created_on' => 'Created On',
'updated_on' => 'Updated On',
];
}
}
This is my model search
<?php
namespace common\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\PackageTable;
/**
* PackageTableSearch represents the model behind the search form about `common\models\PackageTable`.
*/
class PackageTableSearch extends PackageTable
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['package_id', 'amount', 'status'], 'integer'],
[['package_name', 'description', 'created_on', 'updated_on'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = PackageTable::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'package_id' => $this->package_id,
'amount' => $this->amount,
'status' => $this->status,
'created_on' => $this->created_on,
'updated_on' => $this->updated_on,
]);
$query->andFilterWhere(['like', 'package_name', $this->package_name])
->andFilterWhere(['like', 'description', $this->description]);
return $dataProvider;
}
}
Although php namespaces are case-insensitive, autoloader in your case is likely case-sensitive.
At the top of your controller namespace mentioned as
namespace backend/Controllers;
but in advanced template all directories are in lower case. So try to change this line to
namespace backend/controllers;

Categories