Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if table is already has a where clause in Laravel Query Builder?

Here is an example of how can we detect if a table is already joined in a query in Laravel or not.

public static function isJoined($query, $table)
    {
        $joins = $query->getQuery()->joins;
        if($joins == null) {
            return false;
        }

        foreach ($joins as $join) {
            if ($join->table == $table) {
                return true;
            }
        }

        return false;
    }

What I need is to extract the where clauses in a query.

I have a query that has some join and some where conditions, I need to use one of those where conditions in a nested select.

Now what I need is to extract that where clause from the query and use it once more. The question is how can I determine does my query contains any where condition on a specific column of a table (e.g. org.id) in my Eloquent query or not?

I tried to extract the wheres from query as follows but was not like what we have for joins

$wheres = $query->getQuery()->wheres;
  foreach ($wheres as $where) {
    dd(array_keys($where));
  }

And what I received is:

array:3 [
  0 => "type"
  1 => "query"
  2 => "boolean"
]

The value of type is nested and if I try the following code:

$wheres = $query->getQuery()->wheres;
  foreach ($wheres as $where) {
     dd($where['query']->wheres);
  }

Then I have:

array:1 [
  0 => array:5 [
    "type" => "Basic"
    "column" => "org.path"
    "operator" => "LIKE"
    "value" => "/202001/10000000/12400000%"
    "boolean" => "and"
  ]
]

Now why the first wheres return different object? I expected this result in the first $where!

like image 935
MJBZA Avatar asked Oct 28 '25 16:10

MJBZA


1 Answers

You can do pretty much the same with the ->wheres property of the query builder. It will contain an array of where clauses in the following format:

    ["type"] => string(5) "Basic"
    ["column"] =>string(1) "q"
    ["operator"] => string(1) "="
    ["value"] => int(2)
    ["boolean"] => string(3) "and"

From this, looks like the column property is what you could use.

UPD: Basically you could create a recursive function that will check it for you:

  ...
  $wheres = $query->getQuery()->wheres;
  foreach ($wheres as $where) {
     if( $checkColumn($where, 'myColumn) ) { 
        // found it
        break;
     }
  }

  function checkColumn($where, $column) {
     if( $where['type'] == 'nested' ) {
         return checkColumn($where['query'], $column);
     }
     else {
        return $where['column'] == $column;
    }
  }
like image 69
Pavel Lint Avatar answered Oct 30 '25 07:10

Pavel Lint