/** * is the variable a data container that we can read from? * * @param mixed $item * the item to check * @return boolean * TRUE if the item is a data container * FALSE otherwise */ public static function check($item) { if (IsAssignable::check($item) || IsIndexable::check($item)) { return true; } return false; }
/** * throws exceptions if $item is not an indexable 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 string if (!IsIndexable::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; }
/** * merge their data into one of our data's properties * * @param mixed $ours * the data 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 of(&$ours, $property, $value) { if (IsIndexable::check($ours)) { return self::ofArray($ours, $property, $value); } if (IsAssignable::check($ours)) { return self::ofObject($ours, $property, $value); } throw new E4xx_UnsupportedType(SimpleType::from($ours)); }
/** * merge their data into our data, using dot.notation.support to * find the point where the merge starts * * @param object $ours * 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 into(&$ours, $path, $value, $extendingItem = null) { if (IsAssignable::check($ours)) { return self::intoObject($ours, $path, $value, $extendingItem); } if (IsIndexable::check($ours)) { return self::intoArray($ours, $path, $value, $extendingItem); } throw new E4xx_UnsupportedType(SimpleType::from($ours)); }
/** * merge a single key into our object * * @param object $ours * the object to merge into * @param mixed $key * the array key to merge into * @param mixed $value * the data to merge in * @return void */ private static function mergeKeyIntoAssignable($ours, $key, $value) { // general case - overwrite because merging isn't possible if (ShouldOverwrite::intoObject($ours, $key, $value)) { $ours->{$key} = $value; return; } // special case - we are merging into an array if (IsIndexable::check($ours->{$key})) { MergeIntoIndexable::from($ours->{$key}, $value); return; } // at this point, we are merging into an object, using recursion // for which I am going to hell MergeIntoAssignable::from($ours->{$key}, $value); }
/** * should we overwrite $ours[$key] with the value of $theirs? * * @param array $ours * the array where $key may exist * @param string $key * the index on $ours whose fate we are deciding * @param mixed $theirs * the data we want to assign to the index * @return boolean * TRUE if we should overwrite the index's existing value * with $value * TRUE if $key currently has no value * FALSE if we should merge $value into the index's exist * value */ public static function intoArray($ours, $key, $theirs) { // robustness! if (!IsIndexable::check($ours)) { throw new E4xx_UnsupportedType(SimpleType::from($ours)); } return self::checkArray($ours, $key, $theirs); }