/**
  * merge data from a container, using dot.notation.support to identify
  * the data to remove
  *
  * @param  mixed $container
  *         the container we want to remove from
  * @param  string $path
  *         the dot.notation.support path to the data to remove
  * @return void
  */
 public static function from(&$container, $path)
 {
     // defensive programming!
     RequireAnyOneOf::check([new IsAssignable(), new IsIndexable()], [$container], E4xx_UnsupportedType::class);
     RequireDotNotationPath::check($path);
     // find the point where we want to remove the data from
     list($firstPart, $finalPart) = self::splitPathInTwo($path);
     $leaf =& DescendDotNotationPath::into($container, $firstPart);
     // remove it
     RemoveProperty::from($leaf, $finalPart);
 }
 /**
  * throws an exception if $item isn't an absolute path to a folder,
  * and it isn't NULL
  *
  * @param  string|null $item
  *         the folder path to examine
  * @return void
  *
  * @throws E4xx_UnsupportedType
  */
 public static function check($item)
 {
     // defensive programming!!
     static $requirements = [[IsNull::class, 'check'], [IsStringy::class, 'check']];
     RequireAnyOneOf::check($requirements, [$item], E4xx_UnsupportedType::class);
     if ($item === null) {
         return;
     }
     // make sure we have what we need
     if (!IsFolder::check($item)) {
         throw new E4xx_InvalidPath($item);
     }
     if (!IsAbsoluteFolder::check($item)) {
         throw new E4xx_NotAbsoluteFolder($item);
     }
 }
 /**
  * search and replace on data
  *
  * @param  mixed $data
  *         the data to be changed
  * @param  array|string $match
  *         the item(s) to search for
  * @param  array|string $replacement
  *         the item(s) to replace with
  * @return mixed
  *         the (possibly) changed data
  */
 public static function in($data, $match, $replacement)
 {
     // defensive programming!
     RequireAnyOneOf::check([new IsStringy(), new IsArray()], [$match], E4xx_UnsupportedType::class);
     RequireAnyOneOf::check([new IsStringy(), new IsArray()], [$replacement], E4xx_UnsupportedType::class);
     $method = self::lookupMethodFor($data, self::$dispatchTable);
     return self::$method($data, $match, $replacement);
 }
 /**
  * is $data compatible with $constraint?
  *
  * @param  string $data
  *         the class name to check
  * @param  string|object $constraint
  *         the class or object that $data must be compatible with
  * @return boolean
  *         TRUE if $data is compatible
  *         FALSE otherwise
  */
 public static function checkString($data, $constraint)
 {
     // defensive programming!
     RequireStringy::check($data, E4xx_UnsupportedType::class);
     RequireAnyOneOf::check([new IsObject(), new IsStringy()], [$constraint], E4xx_UnsupportedType::class);
     $compatibleTypes = AllMatchingTypesList::from($data);
     if (is_object($constraint)) {
         $constraint = get_class($constraint);
     }
     // is our constraint in the list of data types that $data can be?
     if (in_array($constraint, $compatibleTypes)) {
         return true;
     }
     // if we get here, we have run out of ideas
     return false;
 }
 /**
  * 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;
     }
 }
 /**
  * throws exceptions if $data isn't a value we can use as a timeout,
  * or is not null
  *
  * @param  mixed $data
  *         the data to check
  * @return void
  */
 public static function check($data)
 {
     static $requirements = [[IsNull::class, 'check'], [IsNumeric::class, 'check']];
     RequireAnyOneOf::check($requirements, [$data], E4xx_UnsupportedType::class);
 }
 /**
  * @covers ::check
  * @dataProvider provideBadRequirementData
  * @expectedException GanbaroDigital\Defensive\Exceptions\E4xx_BadRequirementData
  */
 public function testMustProvideAnArrayOfRequirementData($data)
 {
     // ----------------------------------------------------------------
     // setup your test
     $requirements = [new RequireAnyOneOfTest_CheckNull(), new RequireAnyOneOfTest_CheckNumeric()];
     // ----------------------------------------------------------------
     // perform the change
     RequireAnyOneOf::check($requirements, $data);
 }