/** * Checks whether if an item exists on the queried path or not * @param string $query * @return bool */ public function exists($query) { if (empty($query)) { throw new \InvalidArgumentException('Argument 1 should not be empty.'); } $keyExists = 'exists' . $this->type; $key = ''; $result = null; while (strlen($key .= $this->shiftKey($query)) > 0 and $result === null) { $realKey = $this->parseKey($key); if ($this->{$keyExists}($realKey)) { switch ($this->type) { case static::TYPE_ARRAY: $result =& $this->object[$realKey]; break; case static::TYPE_ACCESS: if ($key[0] !== '@' and $key[0] !== '!' and $this->object->offsetExists($realKey)) { $result =& $this->object->offsetGet($realKey); break; } case static::TYPE_OBJECT: if ($key[0] === '@') { $call = $this->object[$realKey]; if (!$call instanceof Provider) { throw new \RuntimeException('"' . $key . '" is not a Provider. Using "@" (service-getter) prefix only allowed on Provider item.'); } $result = $call($this->object); } else { if ($key[0] == '!') { $call = $this->object[$realKey]; if (!$call instanceof Provider) { throw new \RuntimeException('"' . $key . '" is not a Provider. Using "!" (mutation-getter) prefix only allowed on Provider item.'); } if (!$call->isMutated()) { throw new \RuntimeException('Provider "' . $key . '" is not mutated.'); } $result =& $call->getMutatedItem(); } else { $result =& $this->object->{$realKey}; } } break; } if ($query !== '' and (is_array($result) or is_object($result))) { $q = new static($result); if ($q->exists($query)) { $result =& QueryParser::Create($result)->find($query); } else { return false; } } } else { if ($query === '') { return false; } } } return true; }