Example #1
0
 public function current()
 {
     $value = parent::current();
     if ($this->valueField === null) {
         return $value;
     }
     return PropertyPath::get($value, $this->valueField);
 }
Example #2
0
 /**
  * Retrieve non-deleted model-data by id.
  *
  * @return mixed data
  */
 public function get($id, $config)
 {
     $data = $this->backend->get($id, $config);
     if (PropertyPath::get($this->path, $data)) {
         throw new Exception('Record was deleted');
     }
     return $data;
 }
 /**
  * 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));
 }
Example #4
0
 /**
  * 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;
 }
Example #5
0
 public function test_PropertyPath_get()
 {
     $array = array('id' => '1');
     $object = (object) array('id' => '2');
     $this->assertSame(PropertyPath::get('.', 'me'), 'me', 'Path "." should return the input');
     // autodetect type
     $this->assertSame(PropertyPath::get('id', $array), '1', 'Path "id" should work on arrays');
     $this->assertSame(PropertyPath::get('id', $object), '2', 'Path "id" should also work on objects');
     // force array element
     $this->assertSame(PropertyPath::get('[id]', $array), '1', 'Path "[id]" should work on arrays');
     // force object property
     $this->assertSame(PropertyPath::get('->id', $object), '2', 'Path "->id" should work on objects');
     $object->property = array('id' => '3');
     $this->assertSame(PropertyPath::get('property[id]', $object), '3', 'Path "property[id]" should work on objects');
     $this->assertSame(PropertyPath::get('->property[id]', $object), '3', 'Path "->property[id]" should work on objects');
     $object->object = (object) array('id' => '4');
     $this->assertSame(PropertyPath::get('object->id', $object), '4', 'Path "object->id" should work on objects in objects');
     $this->assertSame(PropertyPath::get('->object->id', $object), '4', 'Path "->object->id" should work on objects in objects');
     $object->property['element'] = (object) array('id' => '5');
     $this->assertSame(PropertyPath::get('property[element]->id', $object), '5');
     $this->assertSame(PropertyPath::get('->property[element]->id', $object), '5');
     $array['object'] = (object) array('id' => 6);
     $this->assertSame(PropertyPath::get('object->id', $array), 6);
     $this->assertSame(PropertyPath::get('[object]->id', $array), 6);
     // optional
     $this->assertSame(PropertyPath::get('id?', $array), '1', 'Path "id?" should work on arrays');
     $this->assertSame(PropertyPath::get('id?', $object), '2', 'Path "id?" should work on objects');
     $this->assertSame(PropertyPath::get('undefined?', $array), null, 'Path "id?" should work on arrays');
     $this->assertSame(PropertyPath::get('undefined?', $object), null, 'Path "id?" should work on objects');
     $this->assertSame(PropertyPath::get('[id?]', $array), '1', 'Path "->id?" should work on arrays');
     $this->assertSame(PropertyPath::get('->id?', $object), '2', 'Path "->id?" should work on objects');
     //		$this->assertSame(PropertyPath::get($array, 'undefined?'), null, 'Path "id?" should work on arrays');
     //		$this->assertSame(PropertyPath::get($object, 'undefined?'), null, 'Path "id?" should work on objects');
     // @todo Add UnitTest for method notation "getFilename()"
     $sequence = array(array('id' => 1), array('id' => 3), array('id' => 5));
     $this->assertSame(PropertyPath::get('[*].id', $sequence), array(1, 3, 5));
     PHPUnit_Framework_Error_Notice::$enabled = false;
     $error_log = ini_get('error_log');
     ini_set('error_log', '/dev/null');
     ob_start();
     $this->assertSame(PropertyPath::get('->property->element', $object), null);
     $this->assertRegExp('/Unexpected type: array, expecting an object/', ob_get_clean());
     ob_start();
     $this->assertSame(PropertyPath::get('->id', $array), null, 'Path "->id" should NOT work on arrays');
     $this->assertRegExp('/Unexpected type: array, expecting an object/', ob_get_clean());
     ob_start();
     $this->assertSame(PropertyPath::get('[id]', $object), null, 'Path "[id]" should NOT work on objects');
     $this->assertRegExp('/Unexpected type: object, expecting an array/', ob_get_clean());
     //		PropertyPath::get('->id?', $array)
     //		PropertyPath::get('[id?]', $object)
     PHPUnit_Framework_Error_Notice::$enabled = true;
     ini_set('error_log', $error_log);
 }
 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;
 }
Example #7
0
 /**
  * Build a closure which validates an item with the gives $conditions.
  *
  * @param mixed $conditions array|Closure|expression  See Collection::where() for condition options
  *
  * @return callable
  */
 protected function buildFilter($conditions)
 {
     if (\Sledgehammer\is_closure($conditions)) {
         return $conditions;
     }
     if (is_array($conditions)) {
         // Create filter that checks all conditions
         $logicalOperator = \Sledgehammer\extract_logical_operator($conditions);
         if ($logicalOperator === false) {
             if (count($conditions) > 1) {
                 \Sledgehammer\notice('Conditions with multiple conditions require a logical operator.', "Example: array('AND', 'x' => 1, 'y' => 5)");
             }
             $logicalOperator = 'AND';
         } else {
             unset($conditions[0]);
         }
         $operators = [];
         foreach ($conditions as $path => $expectation) {
             if (preg_match('/^(.*) (' . \Sledgehammer\COMPARE_OPERATORS . ')$/', $path, $matches)) {
                 unset($conditions[$path]);
                 $conditions[$matches[1]] = $expectation;
                 $operators[$matches[1]] = $matches[2];
             } else {
                 $operators[$path] = false;
             }
         }
         // @todo Build an optimized closure for when a single conditions is given.
         if ($logicalOperator === 'AND') {
             return function ($item) use($conditions, $operators) {
                 foreach ($conditions as $path => $expectation) {
                     $actual = PropertyPath::get($path, $item);
                     $operator = $operators[$path];
                     if ($operator) {
                         if (\Sledgehammer\compare($actual, $operator, $expectation) === false) {
                             return false;
                         }
                     } elseif (\Sledgehammer\equals($actual, $expectation) === false) {
                         return false;
                     }
                 }
                 return true;
                 // All conditions are met.
             };
         } elseif ($logicalOperator === 'OR') {
             return function ($item) use($conditions, $operators) {
                 foreach ($conditions as $path => $expectation) {
                     $actual = PropertyPath::get($path, $item);
                     $operator = $operators[$path];
                     if ($operator) {
                         if (\Sledgehammer\compare($actual, $operator, $expectation) !== false) {
                             return true;
                         }
                     } elseif (\Sledgehammer\equals($actual, $expectation) !== false) {
                         return true;
                     }
                 }
                 return false;
                 // None of conditions are met.
             };
         } else {
             throw new Exception('Unsupported logical operator "' . $logicalOperator . '", expecting "AND" or "OR"');
         }
     }
     //'<= 5' or '10'
     // Compare the item directly with value given as $condition.
     if (is_string($conditions) && preg_match('/^(' . \Sledgehammer\COMPARE_OPERATORS . ') (.*)$/', $conditions, $matches)) {
         $operator = $matches[1];
         $expectation = $matches[2];
     } else {
         $expectation = $conditions;
         $operator = '==';
     }
     return function ($value) use($expectation, $operator) {
         return \Sledgehammer\compare($value, $operator, $expectation);
     };
 }
Example #8
0
 /**
  * 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];
 }