CakePhp Where does not take action in deeply nested associations - php

I can not use where in deeply nested associations.
I have tried in many ways, but in every case where I use where it doesn't take action
Actually, my case is like in Documentation
https://book.cakephp.org/3.0/en/orm/query-builder.html#using-innerjoinwith
What I have tried until now
$query = $itemTable
->find('all')
->contain(
[
'Products',
'ItemGroups',
'ItemGroups.FeaturesItemGroups.Features',
'Products.ProductCategories.ProductFractions',
'Products.ProductVessels',
'ItemCancellationReasons',
'Features',
'Users',
'Users.Groups',
'Orders',
'ItemPrices.ItemPricesBillingDocuments.RecyclerPrices.ProductFractions' => [
'conditions' => [
'ItemPricesBillingDocuments.id IS NOT NULL',
'ItemPricesBillingDocuments.billing_document_id' => $billingDocumentToRevert->id,
'ItemPricesBillingDocuments.billing_document_type_id' => BillingDocumentTypes::CREDIT_INDEX,
'ItemPricesBillingDocuments.active' => 1
]
]
]
);
Second example
->innerJoinWith(
'ItemPrices.ItemPricesBillingDocuments',
function ($q) use ($billingDocumentToRevert) {
return $q->where(
[
'ItemPricesBillingDocuments.id IS NOT NULL',
'ItemPricesBillingDocuments.billing_document_id' => $billingDocumentToRevert->id,
'ItemPricesBillingDocuments.billing_document_type_id' => BillingDocumentTypes::CREDIT_INDEX,
'ItemPricesBillingDocuments.active' => 1
]
)
->contain(['RecyclerPrices.ProductFractions']);
}
)
3.
$query->where([
'ItemPricesBillingDocuments.id IS NOT NULL',
'ItemPricesBillingDocuments.billing_document_id' => $billingDocumentToRevert->id,
'ItemPricesBillingDocuments.billing_document_type_id' => BillingDocumentTypes::CREDIT_INDEX,
'ItemPricesBillingDocuments.active !=' => false
]);
And as result in my debugging I am getting results where active flag is false.
Each relation from Items table is 1:many
ItemsPrices.ItemPricesBillingDocuments is also 1:many

Related

How to combine fulltext search with other optinals matches in MongoDb?

I try to query my collection with only one query and 3 potentials search method:
fulltext search
classic search
search regex
This 3 matches can be executed at the same time or just one of them.
The fulltext search is the first stage pipeline as we know. Does this fulltext search can be optional in my aggregate? Because if my default value of search is "", my query returns any data. And I need data to perform my other optionals matches.
Here is my Laravel 8 controller :
Product::raw(function ($collection) use($filters, $fullText, $likeKey, $likeValue){
return $collection->aggregate([
[
'$match' =>
[
'$text' =>['$search' => $fullText],
],
],
[
'$match' => $filters
],
[
'$match' =>
[
$likeKey =>
[
'$regex' => $likeValue,
'$options' => "i"
]
]
],
[
'$addFields' =>
[
'avgReviews' => ['$avg' => '$reviews.ranking'],
'price' => ['$min' => '$variants.price'],
'equipmentsList' => [
'$reduce' => [
'input' => '$equipments.list.list',
'initialValue' => [],
'in' =>
[
'$concatArrays' => [
'$$value',
'$$this'
]
]
]
]
],
]
]);
})
->when($operations, function($products) use ($operations){
foreach($operations as $key => $operation){
return $products
->where($operation[0],$operation[1],$operation[2]);
}
})
->forPage($page,$limit)
->sortBy($sortBy, SORT_REGULAR, $order == 'desc')
->values();
$filters is an array and works fine when it's the only one match. But if I want to use $filters without $text, it returns any data. And with the third match, nothing works. Can somebody help me with this?

laravel eloquent count with a groupby

If I'd have the following table structure
ID name type
1 John Admin
2 Johan Admin
3 Sam User
4 Rick User
How would I use Laravels Eloquent with a groupBy query, but still grab each record, and also sum up per type how many records each type has?
Example result would be as follow
[
'type' => 'Admin',
'records' => 2
'data' => [
0 => [
'name' => 'John'
],
1 => [
'name' => 'Johan'
]
]
],
[
'type' => 'User',
'records' => 2
'data' => [
0 => [
'name' => 'Sam'
],
1 => [
'name' => 'Rick'
]
]
]
Since you are querying all the users you should be doing the grouping after the query instead of grouping in query like:
$users = User::all()->groupBy('type');
Then you can do:
foreach ($allUsers as $type => $users) {
$type; // 'Admin'
$users->count(); // Record Count
foreach ($users as $user) {
$user->name; //
}
}
If you want the data EXACTLY like your example then it would be:
User::all()
->groupBy('type')
->map(function($users, $type) {
return [
'type' => $type,
'records' => $users->count(),
'data' => $users->pluck('name')
];
})
->values();
I think the best way to achieve this is to have a table with types related through hasMany() to your data.
Then you can use standard Eloquent tools without restructuring the data manually:
$data = Type::with('users')->withCount('users')->get();
Also, you can use DB::select('select * from xxx group by yyy') to execute the query.

how to write MySQL queries in cakephp 3

I am trying to do login system in cakephp 3.
Here is the query:
$user_details = $this->User->find('first', ['conditions'=>['email_id'=$email, 'password'=>$password]]);
if(!empty($user_details)){
$this->request->session()->write('user_email'=>$user_details['email_id']);
$this->request->session->write('user_id'=>$user_details['id');
}
Can you tell the differences from cakephp 2 to cakephp 3 about writing queries?
try this query its work fine for you...
$user_details = $this->User->find('first', ['conditions'=>['User.email_id'=$email, 'User.password'=>$password]]);
otherwise you get help from http://book.cakephp.org/3.0/en/controllers/components/authentication.html
For authenticating users you should use the Authentication component. This serves as the best implementation within CakePHP as it automatically binds all the data to the server and request.
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
'plugin' => 'Users'
],
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => [
'Form' => [
'fields' => ['username' => 'email']
]
],
'storage' => 'Session'
]);
}
Please refer to the documentation: http://book.cakephp.org/3.0/en/controllers/components/authentication.html
To answer your original question
Cake 2 uses an automagical function with an array structure for building queries which is quite devious. The query is executed directly on call.
array(
'conditions' => array('Model.field' => $thisValue), //array of conditions
'recursive' => 1, //int
//array of field names
'fields' => array('Model.field1', 'DISTINCT Model.field2'),
//string or array defining order
'order' => array('Model.created', 'Model.field3 DESC'),
'group' => array('Model.field'), //fields to GROUP BY
'limit' => n, //int
'page' => n, //int
'offset' => n, //int
'callbacks' => true //other possible values are false, 'before', 'after'
)
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
Within Cake 3 the query is built using a query builder object. This modifies the SQL on every subsequent call. It is only executed after you call it to.
$query = $articles->find('all')
->where(['Articles.created >' => new DateTime('-10 days')])
->contain(['Comments', 'Authors'])
->limit(10);
Here the an object is manipulated with a referenced SQL on every call (where, contain, limit).
The query is executed after you apply execute(), first(), toArray() etc, where toArray() returns the data set as an array and others as an object.
Further reading: http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html

Laravel 5 execute aggregation with mongodb on where clause

Laravel 5 Eloquent sum of multiplied columns for mongo DB
This was my previous question and it got solved with the help of #Alex, now i need to add a where clause of $field != '0'
Here I am stuck I tried with the match but still I have no option left to get help from here.
Thanks
Using the aggregation pipeline where the $ne comparison query operator is in the $match pipeline:
DB::connection($this->MongoSchemaName)
->collection($this->InvoicesTable)
->raw(function($collection) use ($customer){
return $collection->aggregate([
['$match' => [
'ContactID' => (int)$customer->ContactID,
'Type' => 'PAYMENT',
'AmountDue' => [ '$ne' => 0 ]
]
],
['$group' => [
'_id' => '$ContactID',
'TotalInBaseCurrency' => [
'$sum' => ['$multiply' => ['$Total', '$CurrencyRate']]
]
]
]
]);
})

Compound key relationship with fuelphp orm

I am trying to get FuelPHP's orm to use a compound key when using the related() method.
I have a db setup with two tables and I'd like to relate them based on their compound keys.
For example I would normally use a relation like this in my orm model:
protected static $_has_one = [
'message_flag' => [
'key_from' => 'object_id',
'model_to' => '\ModelClass',
'key_to' => 'object_id',
'cascade_save' => false,
'cascade_delete' => false,
],
];
But instead of using key_from => 'id and key_to => 'object_id, I'd like to join them on their composite key, which might look something like this:
protected static $_has_one = [
'message_flag' => [
'key_from' => ['object_id', 'other_key'],
'model_to' => '\ModelClass',
'key_to' => ['object_id', 'other_key',
'cascade_save' => false,
'cascade_delete' => false,
],
];
To clarify, the top example, which is the one recommended in FuelPHP's docs, creates a query that looks like this:
SELECT `t0`.`object_id` AS `t0_c0`, `t0`.`other_key` AS `t0_c1` FROM `myTable` AS `t0` LEFT JOIN `otherTable` AS `t1` ON (`t0`.`object_id` = `t1`.`object_id`);
But the query that I'd like to build with the ORM would look like this:
SELECT `t0`.`object_id` AS `t0_c0`, `t0`.`other_key` AS `t0_c1` FROM `myTable` AS `t0` LEFT JOIN `otherTable` AS `t1` ON (`t0`.`object_id` = `t1`.`object_id` AND `t0`.`other_key` = `t1`.`other_key`);
Actually, I just tried my hopeful, but undocumented example above
protected static $_has_one = [
'message_flag' => [
'key_from' => ['object_id', 'other_key'],
'model_to' => '\ModelClass',
'key_to' => ['object_id', 'other_key',
'cascade_save' => false,
'cascade_delete' => false,
],
];
Surprised to say this actually worked. Still, if anyone else has a similar problem, I hope they find this answer.

Categories