Skip to content

Commit 4a7f863

Browse files
committed
fix: add recursive normalizeWhere helper, address CodeRabbit review
- Add normalizeWhere() recursive helper that walks full condition tree - Collapses sole $eq_pointer to raw pointer, rewrites mixed cases to $eq - Both _getOptions() and distinct() now use normalizeWhere() - Fix verify_equalto.php autoloader to use __DIR__ (portable) - Update Test 5 to test same-key mixed constraint case
1 parent 01b83e6 commit 4a7f863

2 files changed

Lines changed: 43 additions & 21 deletions

File tree

src/Parse/ParseQuery.php

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,40 @@ public function fullText($key, $value)
498498
return $this;
499499
}
500500

501+
/**
502+
* Recursively normalize the where clause, collapsing $eq_pointer sentinel
503+
* values to raw pointers (for ParseObject equality) or rewriting mixed
504+
* same-key cases to $eq. Handles nested condition trees (or/and/nor queries).
505+
*
506+
* @param mixed $value
507+
* @return mixed
508+
*/
509+
private function normalizeWhere($value)
510+
{
511+
if (!is_array($value)) {
512+
return $value;
513+
}
514+
515+
if (array_key_exists('$eq_pointer', $value)) {
516+
$pointer = $value['$eq_pointer'];
517+
unset($value['$eq_pointer']);
518+
519+
if (count($value) === 0) {
520+
// Sole condition: collapse to raw pointer
521+
return $pointer;
522+
}
523+
524+
// Mixed same-key case: rewrite to $eq alongside other operators
525+
$value['$eq'] = $pointer;
526+
}
527+
528+
foreach ($value as $k => $v) {
529+
$value[$k] = $this->normalizeWhere($v);
530+
}
531+
532+
return $value;
533+
}
534+
501535
/**
502536
* Returns an associative array of the query constraints.
503537
*
@@ -507,14 +541,7 @@ public function _getOptions()
507541
{
508542
$opts = [];
509543
if (!empty($this->where)) {
510-
$where = $this->where;
511-
// Collapse $eq_pointer to raw pointer for array value queries
512-
foreach ($where as $key => $conditions) {
513-
if (is_array($conditions) && array_key_exists('$eq_pointer', $conditions) && count($conditions) === 1) {
514-
$where[$key] = $conditions['$eq_pointer'];
515-
}
516-
}
517-
$opts['where'] = $where;
544+
$opts['where'] = $this->normalizeWhere($this->where);
518545
}
519546
if (count($this->includes)) {
520547
$opts['include'] = implode(',', $this->includes);
@@ -646,13 +673,7 @@ public function distinct($key)
646673
}
647674
$opts = [];
648675
if (!empty($this->where)) {
649-
$where = $this->where;
650-
foreach ($where as $k => $conditions) {
651-
if (is_array($conditions) && array_key_exists('$eq_pointer', $conditions) && count($conditions) === 1) {
652-
$where[$k] = $conditions['$eq_pointer'];
653-
}
654-
}
655-
$opts['where'] = $where;
676+
$opts['where'] = $this->normalizeWhere($this->where);
656677
}
657678
$opts['distinct'] = $key;
658679
$queryString = $this->buildQueryString($opts);

verify_equalto.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
spl_autoload_register(function ($class) {
33
$prefix = 'Parse\\';
4-
$base = '/root/parse-php-sdk/src/Parse/';
4+
$base = __DIR__ . '/src/Parse/';
55
if (strpos($class, $prefix) !== 0) return;
66
$relative = substr($class, strlen($prefix));
77
$file = $base . str_replace('\\', '/', $relative) . '.php';
@@ -68,16 +68,17 @@ function check($name, $condition) {
6868
echo " where = $encoded4\n";
6969
check('foo should have both $eq and $gt', strpos($encoded4, '$eq') !== false && strpos($encoded4, '$gt') !== false);
7070

71-
// Test 5: ParseObject + another constraint on same key (order-dependent case)
72-
echo "\nTest 5: ParseObject with other constraints\n";
71+
// Test 5: ParseObject + another constraint on SAME key (mixed case)
72+
echo "\nTest 5: ParseObject with other constraints on same key\n";
7373
$query5 = new ParseQuery('TestClass');
74-
$query5->greaterThan('count', 5);
7574
$query5->equalTo('users', $user);
75+
$query5->exists('users');
7676
$opts5 = $query5->_getOptions();
7777
$encoded5 = json_encode($opts5['where'] ?? []);
7878
echo " where = $encoded5\n";
79-
check('count should have $gt', strpos($encoded5, '$gt') !== false);
80-
check('users should be direct pointer', strpos($encoded5, '"__type":"Pointer"') !== false);
79+
check('should NOT have $eq_pointer in output', strpos($encoded5, '$eq_pointer') === false);
80+
check('users should still contain the pointer payload', strpos($encoded5, '"__type":"Pointer"') !== false);
81+
check('users should still contain the sibling operator', strpos($encoded5, '$exists') !== false);
8182

8283
echo "\n=== Results: $passed passed, $failed failed ===\n";
8384
exit($failed > 0 ? 1 : 0);

0 commit comments

Comments
 (0)