/** * throws exceptions if $item is not a traversable data type * * @param mixed $item * the container to check * @param string $exception * the class to use when throwing an exception * @return void */ public static function check($item, $exception = E4xx_UnsupportedType::class) { // make sure we have a traversable type if (!IsTraversable::check($item)) { throw new $exception(SimpleType::from($item)); } }
/** * does it make sense to attempt to merge the contents of $theirs into * $ours? * * @param mixed $ours * where we want to merge to * @param mixed $theirs * where we want to merge from * @return boolean * true if merging makes sense * false otherwise */ public static function into($ours, $theirs) { // we can't merge non-arrays, non-objects if (!IsTraversable::check($theirs) && !IsAssignable::check($theirs)) { return false; } // if we have arrays or databag-type objects, we're good if (IsIndexable::check($ours) || IsAssignable::check($ours)) { return true; } // if we get here, then $ours is a complex object, which // we do not know how to merge // // or it is a scalar, which doesn't support merging at all return false; }
/** * @covers ::getCachedResult * @covers ::getCacheKey * @covers ::check * @covers ::checkMixed */ public function testReadsFromStaticCache() { // ---------------------------------------------------------------- // setup your test // force a nonsense result into the cache $expectedResult = 100; $data = 3.1415927; InvokeMethod::onClass(IsTraversable::class, 'setCachedResult', [$data, $expectedResult]); // ---------------------------------------------------------------- // perform the change $actualResult = IsTraversable::check($data); // ---------------------------------------------------------------- // test the results $this->assertEquals($expectedResult, $actualResult); }
/** * merge their data into our array * * @param array &$ours * the array that we want to merge into * @param array|object $theirs * the data that we want to merge from * @return void */ public static function from(&$ours, $theirs) { if (IsAssignable::check($theirs)) { return self::fromObject($ours, $theirs); } if (IsTraversable::check($theirs)) { return self::fromArray($ours, $theirs); } // at this point, we want to append onto the end of $ours $ours[] = $theirs; }
/** * descend inside a container, using dot.notation.support, and optionally * extending the container if the end of the dot.notation.path is missing * * @param mixed &$item * the container to dig into * @param string $property * the dot.notation.support path to descend * @param array|callable|string|null $extendingItem * if we need to extend, what data type do we extend using? * @return mixed */ public static function &into(&$item, $property, $extendingItem = null) { if (IsAssignable::check($item)) { $retval =& self::intoObject($item, $property, $extendingItem); return $retval; } if (IsTraversable::check($item)) { $retval =& self::intoArray($item, $property, $extendingItem); return $retval; } throw new E4xx_UnsupportedType(SimpleType::from($item)); }
/** * merge their data into our object * * @param object $ours * the object that we want to merge into * @param array|object $theirs * the data that we want to merge from * @return void */ public static function from($ours, $theirs) { if (IsAssignable::check($theirs)) { return self::fromObject($ours, $theirs); } if (IsTraversable::check($theirs)) { return self::fromArray($ours, $theirs); } // cannot merge anything that reaches here! throw new E4xx_UnsupportedType(SimpleType::from($ours)); }
/** * convert an array (or traversable object) into an array * * this will do a deep conversion * * @param Traversable $data * the data to convert * @return array */ private static function fromTraversable($data) { // our return value $retval = []; // walk the array foreach ($data as $key => $value) { if (IsTraversable::check($value)) { // array, object - deep copy required $retval[$key] = self::from($value); } else { // it is either opaque, or a simple type $retval[$key] = $value; } } // all done return $retval; }