php-imap icon indicating copy to clipboard operation
php-imap copied to clipboard

Query does not works with array of search criterias

Open EthraZa opened this issue 4 years ago • 3 comments

Array of multiple search criteria is not working, just the first one works.

// Does not works, just the subject criteria is respected -(
$folder->query()->where([['subject' => 'foo'], ['UNSEEN']]);

// Works, all criterias are respected -)
$folder->query()->where(['subject' => 'foo'])->where(['UNSEEN']);

Looking the docs at Custom search criteria, since it uses an array of arrays, I came to the conclusion that multiple search criterias shoud work but, it may be not true. Yet, it would be cool if it works.

EthraZa avatar Feb 12 '21 11:02 EthraZa

Loos like the where method just return the first instead to push it to the array.

So, as a quick solution I did my own function to increment wheres:

public function addWhere(object $query, array $search): object
    {
        foreach ($search as $k => $v) {
            if (is_array($v)) {
                $query = $this->addWhere($query, $v);
            } else if (is_numeric($k)) {
                $query->where($v);
            } else {
                $query->where([$k => $v]);
            }
            
        }

        return $query;
}

// Usage
$query = $this->addWhere($folder->query(), [['subject' => 'foo'], ['UNSEEN']]);

Maybe this logic can be imported to the where method itself in the future. ;)

EthraZa avatar Feb 12 '21 17:02 EthraZa

Hi @EthraZa , what do you think of replacing https://github.com/Webklex/php-imap/blob/23c80eb698e9f9d3c10297a8ff54e1965a58e0fb/src/Query/WhereQuery.php#L126-L146 with this:

public function where($criteria, $value = null) {
    if (is_array($criteria)) {
        foreach ($criteria as $key => $value) {
            if (is_numeric($key)) {
                $this->where($value);
            }
            $this->where($key, $value);
        }
    } else {
        $criteria = $this->validate_criteria($criteria);
        $value = $this->parse_value($value);

        if ($value === null || $value === '') {
            $this->query->push([$criteria]);
        } else {
            $this->query->push([$criteria, $value]);
        }
    }

    return $this;
}

I believe this would work as well and would allow multiple search criteria as long as the provider accepts them:

$query = $folder->query()->where([['subject' => 'foo'], ['UNSEEN']]);

Best regards,

Update 2021-11-04: I just pushed https://github.com/Webklex/php-imap/commit/ae26ff560e552ca185dccdbd53aa0ff75d9f5539 which solved a stupid little problem in my suggestion from above and also works with all old formats. So everybody wins :) Thanks for your suggestion!

Webklex avatar Nov 03 '21 21:11 Webklex

Hi @EthraZa , this change is now available via the v3.0.0-alpha release.

Best regards,

Webklex avatar Nov 04 '21 15:11 Webklex