Sorting in Yii2 - sorting

i'm trying to get data from joined tables sorted by specific column. This column is a varchar column but contain only numbers.
The sorting is not working and i have done a lot of research. Please can anyone help me.
what i need is to sort an ActiveDataProvider instance.
this is my code :
$dataProviderItems = new ActiveDataProvider([
'query' => Products::find()->innerJoin('products_trans', 'products_trans.PRODUCT_ID=products.PRODUCT_ID')->innerJoin('items', 'items.PRODUCT_ID=products.PRODUCT_ID')->innerJoin('items_supplieirs', 'items.ITEM_ID=items_supplieirs.ITEM_ID')->innerJoin('suppliers', 'items_supplieirs.SUPPLIER_ID=suppliers.SUPPLIER_ID')->innerJoin('items_trans', 'items_trans.ITEM_ID=items.ITEM_ID')->andFilterWhere(['products_trans.PRODUCT_ID' =>$productID]) ,
'pagination' => false,
'sort'=> ['defaultOrder' => ['cast(items_supplieirs.PRICE as unsigned)'=>SORT_ASC]]
]);
thanks in advance, best regards.

Related

unique between 2 columns

i need to create a validation to my table "candidate_knowledges", basically in this table it accepts to columns (candidate_id, software_id), i cannot let create user_id and software more then one. but i think my validation is wrong or im not doing it right.
What im trying to say in validation is that can only exist one software_id and one candidate_id on the table, this way the candidate dont have duplicate entries.
Ex: 'software_id' => 'required|integer|unique:candidate_knowledges,candidate_id,'.$candidate->id,
Here is a way to allow only one software for each candidate:
$rules = [
'software_id' =>
'required',
'integer',
'min:1',
Rule::unique('candidate_knowledges')->where('candidate_id', $candidate->id),
],
];
In general I would suggest using fluent validation syntax (it's match easier to use and update), but if you can't (laravel < 5.3 or any other reasons):
'software_id' => 'required|integer|unique:candidate_knowledges,NULL,NULL,candidate_id,' . $candidate->id,
Hope it helps.

Laravel validation: unique with multiple columns and soft_delete

I am trying to do a Laravel validation rules as follow:
"permalink" => "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
The explanation to the rules is:
I have a table "Posts" in my system with the following fields (among others): hotel_id, permalink, deleted_at. If MySQL would allow make an unique index with null values, the sql would be:
ALTER TABLE `posts`
ADD UNIQUE `unique_index`(`hotel_id`, `permalink`, `deleted_at`);
So: I just add a new row IF: the combination of hotel_id, permalink and deleted_atfield (witch must be NULL) are unique.
If there is already a row where the permalink and hotel_id field are the same and 'deleted_at' field is NULL, the validation would return FALSE and the row wouldnt be inserted in the database.
Well. I don't know why, but the query Laravel is building looks like:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `hotel_id` = the-permalink-value AND `NULL` <> deleted_at)
What the heck...
The query I was hoping Laravel build to validation is:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `permalink` = 'the-permalink-value' AND `hotel_id` = ? AND `deleted_at` IS NULL
Could someone explain me how this effectively works? Because everywhere I look it looks like this:
$rules = array(
'field_to_validate' =>
'unique:table_name,field,anotherField,aFieldDifferentThanNull,NULL',
);
Does anyone could help me?
Thank you
all.
Finally, I got a proper understanding of the validation (at least, I think so), and I have a solution that, if it is not beautiful, it can helps someone.
My problem, as I said before, was validate if a certain column (permalink) is unique ONLY IF other columns values had some specific values. The problem is the way Laravel validation string rules works. Lets get to it:
First I wrote this:
"permalink" => "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
And it was generating bad queries. Now look at this:
'column_to_validate' => 'unique:table_name,column_to_validate,id_to_ignore,other_column,value,other_column_2,value_2,other_column_N,value_N',
So. The unique string has 3 parameters at first:
1) The table name of the validation
2) The name of the column to validate the unique value
3) The ID of the column you want to avoid (in case you are editing a row, not creating a new one).
After this point, all you have to do is put the other columns in sequence like "key,value" to use in your unique rule.
Oh, easy, an? Not so quickly, paw. If you're using a STATIC array, how the heck you will get your "currently" ID to avoid? Because $rules array in Laravel Model is a static array. So, I had to came up with this:
public static function getPermalinkValidationStr() {
$all = Input::all();
# If you are just building the frozenNode page, just a simple validation string to the permalink field:
if(!array_key_exists('hotel', $all)) {
return 'required|alpha_dash|max:255';
}
/* Now the game got real: are you saving a new record or editing a field?
If it is new, use 'NULL', otherwise, use the current id to edit a row.
*/
$hasId = isset($all['id']) ? $all['id'] : 'NULL';
# Also, check if the new record with the same permalink belongs to the same hotel and the 'deleted_at' field is NULL:
$result = 'required|alpha_dash|max:255|unique:posts,permalink,' . $hasId . ',id,hotel_id,' . $all['hotel'] . ',deleted_at,NULL';
return $result;
}
And, in the FrozenNode rules configuration:
'rules' => array(
'hotel_id' => 'required',
'permalink' => Post::getPermalinkValidationStr()
),
Well. I dont know if there is a easiest way of doing this (or a much better approach). If you know something wrong on this solution, please, make a comment, I will be glad to hear a better solution. I already tried Ardent and Observer but I had some problems with FrozenNode Administrator.
Thank you.

Seeding and pivot tables?

I'm trying to popular a pivot table with ids in a seed.
$id = DB::table('products')->insertGetId(array(
array(
'title' => 'Product A',
'published' => 1
)
));
DB::table('product_user')->insert(array(
array(
'product_id' => $id,
'user_id' => '9999999999'
)
));
Is the above the best way to do it? By getting an id via insertGetId and then putting it in the pivot table Is there a better way?
Also the above way gives an error:
[ErrorException]
preg_replace(): Parameter mismatch, pattern is a string while replacement i
s an array
I suspect $id is an array, how can i get InsertGetId to return an int?
Well, you can print_r it and seek for the id attribute, and then call $id->attribute on the second insert.
But...
"Me myself", I like to use Eloquent. The mainly reason is: 'Cause it too god damm FUN. Really, Eloquent it's one of the most beautful things I've ever seen in the programming world. I use to thought that .NET was a master piece of software (I was young and naive, though) but once a came across Laravel/Eloquent, I became so AMAZED!
That being said, in my humble opinion, use Eloquent is the best way of doing it!
I'm assuming that you have a table called products and another called users, and you have a product_user table to make the connection. Using Eloquent, you can simply do this:
$user = User::find($user_id);
$product = Product::find($product_id);
$product->user->attach($user);
...I reacomend this approach for several reasons, but the first one is: is way more readable.
Well, I hope I ain't been too prolixous on my answer, and that it hope you and others.

Yii - sort dataprovider with more than one field

I am using DataProvider to show some data. The data is related to shows in the theater. I want to show the shows which are "On Season" first and then the shows that are not on season. And all the shows should be ordered alphabetically. I tried to use CSort but I am getting an error. Here is my code:
$dataProviderFiaba = new CActiveDataProvider('Show',
array(
'criteria'=>array(
'condition'=>'show_type= '.Show::TYPE_FIABA,
),
'sort'=>array(
'defaultOrder'=>'on_season', //TO SHOW THE ON SEASON SHOWS FIRST
'asc'=>'title', // TO ORDER ALPHABETICALLY
),
));
And the error is Property "CSort.asc" is not defined. So I think I am not using CSort with the correct format. What is the right way to do this kind of sorting?
You can only use "asc" in the context of attributes for CSort. For example:
$mCSort->attributes = array('title'=>array('asc'=>'title', 'desc' => 'title DESC'));
To solve your sorting problem, the following should be sufficent though:
$dataProviderFiaba = new CActiveDataProvider('Show',
array(
'criteria'=>array(
'condition'=>'show_type= '.Show::TYPE_FIABA,
'order'=>'on_season, title'
),
));

Multiple Queries in Codeigniter [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
MYSQL multiple insert in codeigniter
I would like to execute multiple insert queries simultaneously using codeignitor framework in PHP.There is any simple ways to do this without writing multiple insert queries.Already tried something like
$this->db->query('INSERT INTO students (first_name, last_name) VALUES
('teejay', 'obazee')'
('maev', 'shadowsong')'
('jaina', 'proudmore')', FALSE)
.There is any ways like this.Which is not working.If anybody knows;please help me.
You can use codeignitor native active record
$data = array(
array(
'first_name' => 'teejay', 'last_name' => 'obazee'
),
array(
'first_name' => 'maev', 'last_name' => 'shadowsong'
),
array(
'first_name' => 'jaina', 'last_name' => 'proudmore'
)
);
$this->db->insert_batch('students', $data);
It will produce query
INSERT INTO students (first_name,last_name) VALUES ('teejay', 'obazee'),('maev', 'shadowsong'),('jaina', 'proudmore');
I also had problem with sending multi queries in CodeIgniter.
In your specific situation, you could send multi rows in one INSERT query, but in many other situations this is not possible because you have different commands (eg LOCK TABLE... SELECT... INSERT... UPDATE... UNLOCK TABLES)
At that point in codeigniter you should user:
mysqli_multi_query($this->db->conn_id, $sql);
I didn't even know the answer, the answer was originally posted as a comment by Kumar (https://stackoverflow.com/users/523794/kumar) at Codeigniter - how to run multiple/batch queries?
Note: You have to set you database driver to mysqli in /application/config/database.php
Hope it helps some one.
Unfortunately, you need to do something like:
$this->db->query("INSERT INTO `students` (`first_name`,`last_name`) VALUES ('teejay', 'obazee'),('maev', 'shadowsong'),('jaina', 'proudmore')");
Or use someone else's class to build the query:
http://codefury.net/2009/12/insert-multiple-rows-into-a-database-with-codeigniter/

Resources