getkirby-v2 / toolkit

This is the deprecated toolkit for Kirby v2.
http://getkirby.com
81 stars 50 forks source link

db: passing function in ->where() does not work #209

Closed sebsel closed 7 years ago

sebsel commented 7 years ago

(I feel like I'm way to deep in this Toolkit all the time :P)

According to database/query.php, line 290+:

  /**
   * Attaches an additional where clause
   *
   * All available ways to add where clauses
   *
   * ->where('username like "myuser"');                        (args: 1)
   * ->where(array('username' => 'myuser'));                   (args: 1)
   * ->where(function($where) { $where->where('id', '=', 1) }) (args: 1)
   * ->where('username like ?', 'myuser')                      (args: 2)
   * ->where('username', 'like', 'myuser');                    (args: 3)
   *
   * @param list
   * @return object
   */
  public function where() {

I can pass a function to ::where(). The only problem is: it does not work.

The function gets called here:

database/query.php, line 831

        } else if(is_callable($args[0])) {

          $query = clone $this;
          call_user_func($args[0], $query);
          $result = '(' . $query->where . ')';

        }

But: $query is not passed by reference (and can't be, my PHP complains...) and nothing is expected to return. Since PHP complains about passing by reference, I think this is the best solution:

        } else if(is_callable($args[0])) {

          $query = call_user_func($args[0], $this);
          $result = '(' . $query->where . ')';

        }

But then we also need a return in the example in the comment above (linen 297). This does potentially break existing code, but since it doesn't work at this moment, probably nobody is using it.

Or am I missing something?

lukasbestle commented 7 years ago

Hm, that's a very good question. To be honest I have no idea how this was supposed to work. @bastianallgeier?

sebsel commented 7 years ago

My original problem is now solved in a different way btw, so no hurry, but it's still a question of how it works.

bastianallgeier commented 7 years ago

The bindings from the nested where clause have not been copied over to the query builder. I just fixed this and now it works. Here's an example query:

$rows = $db->mytable()->where(function($query) {
  $query->where('id', '<', '10');
  $query->where('id', '>', '1');
})->all();