Tuesday, January 20, 2015

Re: Cakephp 3.0 Get and Modify Query conditions in beforeFind function

Hi Josh,

Thanks for your answer.

I tried both PlumSearch and Search Plugin in my application and they are not working as expected.

They are adding search argumentsin existing conditions in query object.

Failing Situation.
Existing condition has Users.active = 1 and If new condition array has Users.active = 0 so this way merged conditions will have Users.active = 1 AND Users.active = 0 //No Result

If you think I am trying to complicate it then what about failure cases? It is not a good idea to match each new condition in original conditions by traverse the query.

I believe this would be helpful to every programmers if we find out a simple and perfect solution.

Thanks in advance.

On Monday, January 19, 2015 at 11:35:57 PM UTC+5:30, José Lorenzo wrote:
I don't think it is possible in an easy way, I also think you are trying to complicate the problem, given the existence of other clean solutions that already work.

There are two methods that clause('where') object has that can be used to traverse the query. They are iterateParts() and traverse(). iterateParts() will call the passed function for each of the conditions in the same level of depth. traverse() will call the passed function for all the conditions that are stored in a ExpressionInterface object.

There are basically 2 types of interesting ExpressionInterface objects. QueryExpression (contains multiple conditions in the same level and you can call iterateParts() on it) and Comparison, which is a single condition.

With a bit (maybe  a lot) of work you can traverse each of the levels of conditions and build an array out of it. Again, sounds like something complicated for something that can be done differently in a simpler way.

On Monday, January 19, 2015 at 5:45:55 PM UTC+1, Cake Developer wrote:
Hi Jose,

I gone through both of the plugin links you provided, It seems they are complicated and do not meet my requirements.

I am trying to write a generic solution to filter records with less code. Is there any way to get original conditions from query object as an array format.

For e.g.

$this->paginate = ['conditions'=>['Users.active'=>1]];

I want original conditions in beforeFind method like

function beforeFind(Event $event, Query $query, $options, $primary) {
    $orgCondtions = $query->clause('where'); //it returns Expression Object

    $orgCondtions = convertExpressionObjectToArray($orgCondtions);
    pr($orgCondtions);
    output should be  array('Users.active'=>1)
}


I am looking for a way to convert Expression Object to Array. Please help me if possible.

Thanks in advance.



On Mon, Jan 19, 2015 at 4:22 PM, José Lorenzo <jose...@gmail.com> wrote:
Sorry, I forgot to answer... What you are doing sounds similar to what some plugins are doing as well. Please try these:



As for the second case. I suggest doing as I suggested at the beginning, use the query options to hint the beforeFind() or any other finder method on what to do or overwrite. That way you can avoid traversing the conditions tree.

If you are in absolute need of inspecting the where clause and modifying stuff, you will need to do as follows:

$query->clause('where')->traverse(function ($expression) {
    if ($expression instanceof \Cake\Database\Expression\Comparison) {
        if ($expression->getField() === 'Users.active' && $expression->getValue() === true) {
             $expression->setValue(false);
        }
    }
});

But that can get a bit complicated and difficult to read. Hence my suggestion to treat the Query as a command by passing options to it.


On Monday, January 19, 2015 at 10:32:22 AM UTC+1, Cake Developer wrote:
Hi Experts,

any help?

Thanks in advance.

On Friday, January 16, 2015 at 12:47:39 AM UTC+5:30, José Lorenzo wrote:
Even though that is possible you are tying to do it the hard way. The easiest way you can implement the same is by using the query as a "command" object,
thus instructing the custom finders to do stuff based on the passed options. An example

$table->find('forUser', ['user' => $user])->find('withStatus', ['status' => 'active']);

Then in your table you would create your finders this way:

public function finWithStatus($query, $options) {
    if (!empty($options['user'])) {
         // The user is available from the previous finder, I can add more conditions here based on that
    }
}


I guess the best way I can help you find the best strategy is if you mention what exactly you are trying to do :D
On Thursday, January 15, 2015 at 3:26:09 PM UTC+1, Cake Developer wrote:
Hello,

I am trying to get and modify query conditions in beforeFind function of Behaviour.

function beforeFind(Event $event, Query $query, $options, $primary) {
   // here is what I tried so far.
$conditions = $query->clause('where');
// this gives me Object of Expression Interface and I am not able to convert it in condition array like we have in cakephp 2.x

//what I want to achieve... 
//I want to modify existing conditions in query.
//I want to add new condition in query

}

I spent last 2 days but could not figure out any solution.
Thanks for any help you may be able to provide regarding this.

--
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+u...@googlegroups.com.
To post to this group, send email to cake...@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/d/optout.

--
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+unsubscribe@googlegroups.com.
To post to this group, send email to cake-php@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/d/optout.

No comments: