/** * merge their data into one of our object's properties * * @param object &$obj * the object that we want to merge into * @param string $property * the property to merge into * @param mixed $value * the data that we want to merge from * @return void */ public static function ofObject($obj, $property, $value) { // robustness! RequireAssignable::check($obj, E4xx_UnsupportedType::class); // easiest case - no clash if (ShouldOverwrite::intoObject($obj, $property, $value)) { $obj->{$property} = $value; return; } // special case - we are merging into an object if (is_object($obj->{$property})) { MergeIntoAssignable::from($obj->{$property}, $value); return; } // if we get here, then we must be merging into an array MergeIntoIndexable::from($obj->{$property}, $value); }
/** * merge their object into our array * * @param array &$ours * the array that we want to merge into * @param object $theirs * the object that we want to merge from * @return void */ public static function fromObject(&$ours, $theirs) { // robustness! RequireAssignable::check($theirs, E4xx_UnsupportedType::class); self::fromArray($ours, get_object_vars($theirs)); }
/** * merge their data into our object, using dot.notation.support to * find the point where the merge starts * * @param object $obj * the object that we want to merge into * @param string $path * the dot.notation.support path to where the merge should start * @param mixed $value * the data that we want to merge from * @param array|callable|string|null * if $path goes beyond what exists in $ours, how do we want to * extend $ours? * @return void */ public static function intoObject($obj, $path, $value, $extendingItem = null) { // robustness! RequireAssignable::check($obj, E4xx_UnsupportedType::class); RequireDotNotationPath::check($path); // find the point where we want to merge list($firstPart, $finalPart) = self::splitPathInTwo($path); if ($firstPart !== null) { $leaf =& DescendDotNotationPath::intoObject($obj, $firstPart, $extendingItem); } else { $leaf = $obj; } // merge it MergeIntoProperty::of($leaf, $finalPart, $value); }
/** * does $path point to a valid piece of data inside $container? * * @param object $container * the container to look inside * @param string $path * the dot.notation.support path to walk * @return boolean * TRUE if $path points to a vlaid piece of data * FALSE otherwise */ public static function inObject($container, $path) { // defensive programming! RequireAssignable::check($container, E4xx_UnsupportedType::class); RequireAnyOneOf::check([new IsDotNotationPath(), new IsStringy()], [$path], E4xx_NotDotNotationPath::class); try { DescendDotNotationPath::intoObject($container, $path); return true; } catch (E4xx_NoSuchIndex $e) { return false; } catch (E4xx_NoSuchProperty $e) { return false; } }
/** * extract a value from an object, using dot.notation.support * * @param object $obj * the object to extract from * @param string $property * the dot.notation.support path to walk * @return mixed * whatever we find when we walk the path */ public static function fromObject($obj, $property) { // robustness! RequireAssignable::check($obj, E4xx_UnsupportedType::class); return DescendDotNotationPath::intoObject($obj, $property); }
/** * descend inside an object, using dot.notation.support, and optionally * extending the object if the end of the dot.notation.path is missing * * @param object $obj * the object 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 &intoObject($obj, $property, $extendingItem = null) { // robustness! RequireAssignable::check($obj, E4xx_UnsupportedType::class); RequireStringy::check($property, E4xx_UnsupportedType::class); if (strlen($property) === 0) { throw new \InvalidArgumentException("'\$property' cannot be empty string"); } $retval =& self::getPathFromRoot($obj, $property, $extendingItem); return $retval; }
/** * @covers ::check * @covers ::checkMixed * @dataProvider provideNonAssignables * @expectedException GanbaroDigital\Reflection\Exceptions\E4xx_UnsupportedType */ public function testRejectsNonAssignablesWhenCalledStatically($item) { // ---------------------------------------------------------------- // setup your test // ---------------------------------------------------------------- // perform the change RequireAssignable::check($item); }