public function __call($method, $arguments) { $key = $method . '('; foreach ($arguments as $i => $argument) { if ($i !== 0) { $key .= ', '; } if (is_array($argument) || is_object($argument)) { $key .= serialize($argument); } elseif (is_string($argument)) { $key .= "'" . $argument . "'"; } else { $key .= $argument; } } $key .= ')'; $path = $this->cachePath . '[' . PropertyPath::escape($key) . ']'; $object = $this->object; $value = \Sledgehammer\cache($path, $this->expires, function () use($object, $method, $arguments) { return call_user_func_array(array($object, $method), $arguments); }); if (is_object($value)) { $value = new self($value, $path, $this->expires); } return $value; }
public function current() { $value = parent::current(); if ($this->valueField === null) { return $value; } return PropertyPath::get($value, $this->valueField); }
/** * Replace the placeholder with the referenced object. */ private function __replacePlaceholder() { if (is_string($this->__placeholder) === false) { // Is the placeholder already replaced? // Multiple lookups are valid use-case. // The property (as placeholder) could be passed to another function as a value. return; } $parts = explode('/', $this->__placeholder); $repositoryId = array_shift($parts); $model = array_shift($parts); $property = implode('/', $parts); $self = PropertyPath::get($property, $this->__container); if ($self !== $this) { notice('This placeholder belongs to an other object', 'Did you clone the object?'); $this->__placeholder = $self; return; } $repo = Repository::instance($repositoryId); $this->__placeholder = $repo->resolveProperty($this->__container, $property, array('model' => $model)); }
/** * Return the instance the Placeholder points to. * * @param BelongsToPlaceholder|Junction $wrapper * @param ModelConfig $config */ protected function resolveInstance($wrapper, $config) { if ($wrapper instanceof BelongsToPlaceholder === false && $wrapper instanceof Junction === false) { throw new Exception('Parameter $placeholder must be a BelongsToPlaceholder or Junction'); } if ($wrapper instanceof Junction && PropertyPath::get($config->properties[$config->id[0]], $wrapper) === null) { foreach ($this->created[$config->name] as $index => $created) { $isAMatch = true; foreach (get_object_vars($created) as $property => $value) { if ($wrapper->{$property} !== $value) { $isAMatch = false; break; } } if ($isAMatch) { return $created; } } } $index = $this->resolveIndex($wrapper, $config); if (empty($this->objects[$config->name][$index]['instance'])) { throw new Exception('Placeholder "' . $model . ' ' . $index . '" not loaded'); } $instance = $this->objects[$config->name][$index]['instance']; foreach (get_object_vars($instance) as $property => $value) { if ($wrapper->{$property} !== $value) { throw new Exception('Placeholder belongs to another model'); } } return $instance; }
/** * Instead of deleting set the flag. * * @param array $data * @param array $config */ public function delete($data, $config) { $old = $data; PropertyPath::set($this->path, 1, $data); parent::update($data, $old, $config); }
public function test_map() { $source = array('deep' => array('nested' => 1), 'value' => 2); $target = []; $mapping = array('dn' => 'deep.nested', 'meta[value]' => 'value'); PropertyPath::map($source, $target, $mapping); $this->assertSame(array('dn' => 1, 'meta' => array('value' => 2)), $target, ''); }
public function add($data, $config) { $key = PropertyPath::get($config['key'], $data); if ($key === null) { $this->items[] = $data; $keys = array_keys($this->items); $key = array_pop($keys); $key = PropertyPath::set($config['key'], $key, $data); return $data; } $this->getKey($data, $config); return $data; }
/** * Convert a path to a (escaped) columnname. * * @param string $path */ private function convertPathToColumn($path) { $compiled = PropertyPath::parse($path); if (count($compiled) > 1) { return false; } if (in_array($compiled[0][0], array(PropertyPath::TYPE_ANY, PropertyPath::TYPE_ELEMENT))) { $db = Connection::instance($this->dbLink); return $db->quoteIdentifier($compiled[0][1]); } return false; }
/** * Return a new collection sorted by the given field in ascending order. * * @param string|Closure $selector * @param int $method The sorting method, options are: SORT_REGULAR, SORT_NUMERIC, SORT_STRING or SORT_NATURAL * * @return Collection */ public function orderBy($selector, $method = SORT_REGULAR) { $sortOrder = []; $items = []; $indexed = true; $counter = 0; if (\Sledgehammer\is_closure($selector)) { $closure = $selector; } else { $closure = PropertyPath::compile($selector); } // Collect values foreach ($this as $key => $item) { $items[$key] = $item; $sortOrder[$key] = $closure($item, $key); if ($key !== $counter) { $indexed = false; } ++$counter; } // Sort the values if ($method === SORT_NATURAL) { natsort($sortOrder); } elseif ($method === \Sledgehammer\SORT_NATURAL_CI) { natcasesort($sortOrder); } else { asort($sortOrder, $method); } $sorted = []; foreach (array_keys($sortOrder) as $key) { if ($indexed) { $sorted[] = $items[$key]; } else { // Keep keys intact $sorted[$key] = $items[$key]; } } return new self($sorted); }
/** * Compile a path into a closure function. * The generated function expected 1 parameter (The $data for the property get). * * @param string $path * return Closure */ public static function compile($path) { static $cache = []; if (isset($cache[$path])) { return $cache[$path]; } $cache[$path] = function ($data) use($path) { return PropertyPath::get($path, $data); }; return $cache[$path]; }