Yii2: Sorting by calculated column - yii2

I have one table like:
name
startDate
endDate
units
price
and I show them in a gridview for a given year as follows (index.php in views):
$gridColumns = [
'name',
[
'attribute' => 'january',
'format' => 'currency',
'value' => function ($data) {
if(date("m", strtotime($data["startDate"])) == 1) {
return ($data["price"]*$data["units"]);
}
else {
return "";
}
},
'options' => ['style' => 'max-width:20px;'],
'pageSummary' => true,
],
[
'attribute' => 'february',
'format' => 'currency',
'value' => function ($data) {
if(date("m", strtotime($data["startDate"])) == 2) {
return ($data["price"]*$data["units"]);
}
else {
return "";
}
},
'pageSummary' => true,
],
... until month 12
];
In my search model i have defined:
public $january, $february, $march, $april, $may, $june, $july, $august, $september, $october, $november, $december;
placed them as safe in rules and defining attributes in order to get grid header with sortable items
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 0,
],
'sort' => [
'defaultOrder' => [
'name' => SORT_ASC,
],
'attributes' => [
'name',
'units',
'price',
'january',
'february',
'march',
'april',
'may',
'june',
'july',
'august',
'september',
'october',
'november',
'december',
],
],
]);
but when i try to sort by one of the months it gives an error like:
exception 'PDOException' with message 'SQLSTATE[42S22]: Column not
found: 1054 Unknown column 'january' in 'order clause''
How could I sort by these calculated columns that doesnt exist in the database?
Thanks

Related

How to extract the Day, Month and Year from the date?

I just cant figure out how to get the day, the months and the year from the dates.
Here it is the eloquent
public function query(Detail $model)
{
return $model->newQuery()->leftjoin('fishers','fishers.id', '=','details.fisher_id')
->leftjoin('species','species.id', '=', 'details.species_id')
->leftjoin('purposes','purposes.id', '=', 'details.purpose_id')
->leftjoin('islands','islands.id', '=', 'fishers.island_id')
->leftjoin('preservations','preservations.id', '=', 'details.preservation_id')
->select('fishers.*','details.*','details.indate','islands.island_name','fishers.fisher_first_name','fishers.fisher_last_name','details.weight','species.species_name','purposes.purpose_name','preservations.preservation_name');
}
I have tried to use Month(details.indate) as Month, Year(details.indate) as Year but seems not working. I used date as the datatype for indate and when I do Month(details.indate) as Month I get this error:
SQLSTATE[42S22]: COLUMN NOT FOUND: 1054 UNKNOWN COLUMN 'Month(details.indate)' IN 'field list' (SQL: SELECT fishers.* , details.* , MONTH(details.indate) AS MONTH
This is my datatable columns
protected function getColumns()
{
return [
[ 'data' => 'purpose_name', 'name' => 'purposes.purpose_name', 'title' => 'Purpose' ],
[ 'data' => 'fisher_first_name', 'name' => 'fishers.fisher_first_name', 'title' => 'Fisher Name' ],
[ 'data' => 'preservation_name', 'name' => 'preservations.preservation_name', 'title' => 'Preservation Methods' ],
[ 'data' => 'species_name', 'name' => 'species.species_name', 'title' => 'Species Name' ],
[ 'data' => 'island_name', 'name' => 'islands.island_name', 'title' => 'Island Name' ],
[ 'data' => 'weight', 'name' => 'details.weight', 'title' => 'Weight' ],
[ 'data' => 'indate', 'name' => 'details.indate', 'title' => 'Month' ],
[ 'data' => 'indate', 'name' => 'details.indate', 'title' => 'Year' ],
];
}
can someone help me how to do it?
You need to use the DB::raw function to select expressions using Laravel Eloquent.
For example:
return $model->newQuery()->...
->select(DB::raw('Month(details.indate) as Month'), DB::raw('Year(details.indate) as Year'), 'fishers.*','details.*', ...)
Be sure to add use DB; at the top of your file.

Yii2 formatting boolean field in GridView

I remember to have done this before, but now it does not work and I can't get it out.
[
'label' => 'Sex',
'attribute' => 'gan_sex',
'filter' => [
'1' => 'Male',
'2' => 'Female'
]
],
The output is
1
2
2
1
instead of
Male
Female
Female
Male
What is the problem now? I'd swear I used it just the same way but ...
I do it like this
[
'label' => 'Sex',
'attribute' => 'gan_sex',
'filter' => [
'1' => 'Male',
'2' => 'Female'
],
// translate lookup value
'value' => function ($model) {
$gender = [
'1' => 'Male',
'2' => 'Female'
];
return $gender[$model->gan_sex];
}
]
Possible values for gan_sex must be restricted to 1 and 2.

validation error on patchEntity telling field is not unique

I update an entity (so same id) and I get a validation error on a field which has a 'unique' rule.
I verified in the db that there is no an existing identical field and so I don't understand why I have this error as I update the record so obviously the field exists already because it's itself!
Is it a problem to have a 'unique' rule on patchEntity()?
[
'site_name' => '...',
'datas' => object(App\Model\Entity\User) {
'id' => (int) 653,
'owner_id' => (int) 611,
'extraemails' => [
],
'owner' => object(App\Model\Entity\Owner) {
'id' => (int) 611,
'company' => 'This is the Company name',
'created' => object(Cake\I18n\Time) {
'time' => '2015-06-06T18:07:17+0000',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\Time) {
'time' => '2015-06-17T02:44:36+0000',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'[new]' => false,
'[accessible]' => [
'email' => true,
'phone' => true,
'phone2' => true,
'fax' => true,
'company' => true,
'tva_number' => true,
'address' => true,
'postcode' => true,
'city' => true,
'country_id' => true,
'users' => true,
'username' => true,
'origin' => true
],
'[dirty]' => [
'email' => true,
'phone' => true,
'postcode' => true,
'city' => true
],
'[original]' => [
'email' => '...',
'phone' => '...',
'postcode' => '...',
'city' => '...'
],
'[virtual]' => [],
'[errors]' => [
'company' => [
'unique' => 'This company name exists already.'
]
],
'[repository]' => 'Owners'
},
....
EDIT patchEntity() call added
$user = $this->Users->patchEntity($site->users[0], [
'email' => $this->siteDatas['userEmail'],
'phone' => $this->siteDatas['ownerPhone'],
'role' => 'owner',
'active' => 1,
'extraemails' => $this->siteDatas['extraemails'],
'owner' => [
'company' => $this->siteDatas['ownerName'],
'email' => $this->siteDatas['ownerEmail'],
'phone' => $this->siteDatas['ownerPhone'],
'address' => $this->siteDatas['ownerAddress'],
'postcode' => $this->siteDatas['ownerPostcode'],
'city' => $this->siteDatas['ownerCity'],
'country_id' => $this->siteDatas['countryId'],
'web' => $this->siteDatas['ownerWeb'],
'origin' => 'sitra',
],
],
[
'validate' => 'import',
'associated' => [
'Extraemails',
'Owners' => [
'validate' => 'import'
]
]
]);
if ($user->errors()) {
// Here is where I get the 'unique' error
}
So again I verified that no other record in the table have the same 'company' name.
and as you can see in the debug() at the begining of my post, I have a owner->id and it's really the one I want to modify.
Here is the validator
public function validationImport(Validator $validator) {
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create')
->notEmpty('company')
->add('company', 'unique', ['rule' => 'validateUnique', 'provider' => 'table', 'message' => __("This company exists already.")])
...
])
;
return $validator;
}

Unable to fetch result Cakephp association

//in my model
public function initialize (array $config)
{
$this->addBehavior('Timestamp');
$this->belongsTo('Users');
}
//in my controller
$query = $this->Articles->find('all')->contain(['users']);
/src/Controller/ArticlesController.php (line 39)
object(Cake\ORM\Query) {
'sql' => 'SELECT Articles.id AS `Articles__id`, Articles.title AS `Articles__title`, Articles.body AS `Articles__body`, Articles.created AS `Articles__created`, Articles.modified AS `Articles__modified`, Articles.is_delete AS `Articles__is_delete`, Articles.user_id AS `Articles__user_id`, Users.id AS `Users__id`, Users.username AS `Users__username`, Users.password AS `Users__password`, Users.role AS `Users__role`, Users.created AS `Users__created`, Users.modified AS `Users__modified` FROM articles Articles LEFT JOIN users Users ON Users.id = (Articles.user_id)',
'params' => [],
'defaultTypes' => [
'Articles.id' => 'integer',
'id' => 'integer',
'Articles.title' => 'string',
'title' => 'string',
'Articles.body' => 'text',
'body' => 'text',
'Articles.created' => 'datetime',
'created' => 'datetime',
'Articles.modified' => 'datetime',
'modified' => 'datetime',
'Articles.is_delete' => 'integer',
'is_delete' => 'integer',
'Articles.user_id' => 'integer',
'user_id' => 'integer'
],
'decorators' => (int) 0,
'executed' => false,
'hydrate' => true,
'buffered' => true,
'formatters' => (int) 0,
'mapReducers' => (int) 0,
'contain' => [
'users' => []
],
'matching' => [],
'extraOptions' => [],
'repository' => object(App\Model\Table\ArticlesTable) {
'table' => 'articles',
'alias' => 'Articles',
'entityClass' => 'App\Model\Entity\Article',
'associations' => [
(int) 0 => 'users'
],
'behaviors' => [
(int) 0 => 'Timestamp'
],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
}
You are debugging the query and not the result. To see the contents you can try:
debug($query->toArray())

Doctrine 1 saving a row not giving back saved property

I am finding problem in getting the saved property after new insertion in model.
Model :
<?php
abstract class BaseTeacher extends Doctrine_Record
{
public function setTableDefinition()
{
$this->setTableName('teacher');
$this->hasColumn('id', 'integer', null, array(
'unique' => true,
'primary' => true,
'type' => 'integer',
'autoincrement' => true,
));
$this->hasColumn('website', 'string', 512, array(
'type' => 'string',
'autoincrement' => true,
'length' => '512',
));
$this->hasColumn('doj', 'date', null, array(
'primary' => true,
'type' => 'date',
));
$this->hasColumn('isPermanent', 'boolean', null, array(
'default' => 0,
'type' => 'boolean',
));
$this->hasColumn('isTeaching', 'boolean', null, array(
'default' => 0,
'type' => 'boolean',
));
$this->hasColumn('empId', 'string', 512, array(
'type' => 'string',
'length' => '512',
));
$this->hasColumn('qualification', 'string', 512, array(
'type' => 'string',
'length' => '512',
));
$this->hasColumn('prevExperience', 'clob', null, array(
'type' => 'clob',
));
$this->hasColumn('status', 'string', 32, array(
'type' => 'string',
'length' => '32',
));
$this->hasColumn('college_id', 'integer', null, array(
'type' => 'integer',
));
$this->hasColumn('user_id', 'integer', null, array(
'type' => 'integer',
));
}
public function setUp()
{
parent::setUp();
$softdelete0 = new Doctrine_Template_SoftDelete(array(
'name' => 'deleted',
'type' => 'boolean',
'options' =>
array(
'default' => 0,
'notnull' => true,
),
));
$timestampable0 = new Doctrine_Template_Timestampable(array(
'created' =>
array(
'name' => 'created_at',
'type' => 'timestamp',
),
'updated' =>
array(
'name' => 'updated_at',
'type' => 'timestamp',
),
));
$this->actAs($softdelete0);
$this->actAs($timestampable0);
}
}
**Here is my code : **
$teacher = new Teacher();
$teacher->college_id = $collegeId;
$teacher->user_id = $user->id;
$teacher->save();
print_r($teacher->id);
It's pushing new entry in DB but not giving me the new generated row's property.
This is a weird query but honestly this killed my time.
How aweful, I just regenerated models with YML and it worked.