示例#1
0
 /**
  * @param string $valueSet
  * @param mixed $data
  * @param bool|false $null
  * @return StringS
  */
 public static function StringS($valueSet = null, $data = null, $null = false)
 {
     $string = new StringS();
     $string->setValueSet($valueSet);
     $string->setData($data);
     $string->setNull($null);
     return $string;
 }
示例#2
0
 /**
  * Returns an array of closures that can check and format
  * to the $string type
  *
  * @param $string
  * @return array
  * @throws \Exception
  */
 function compileString($string)
 {
     /**
      * Examples:
      *  numeric[-10, 30)
      *  integer(0, inf)
      *  float[0,1]
      */
     $numeric = '/^(numeric|float|integer|int)((\\(|\\[).+,[^\\]\\)]+(\\)|\\]))$/';
     /**
      * Examples:
      *  string{pendent, payed, ready, cancelled}
      *  integer{10, 100, 1000}
      *  scalar{0, false}
      *  {0, false} //same as the previous one
      */
     $valueSetScalar = '/^(scalar|string|float|integer|int|str|boolean|bool|numeric)?(\\{[^}]*\\})$/';
     /**
      * Examples:
      *  string(5..10)
      *  string(5..)
      *  string(..10)
      *  string(5..5) // strict length
      *  string(..) // pointless, but valid
      */
     $lengthString = '/^string(\\(\\d*\\.\\.\\d*\\))$/';
     /**
      * Examples:
      *  (string|integer)[]
      *  (string|integer{0,1})[]
      *  (bool{true}|integer[1,inf))[]
      */
     $quickArray = "/^(\\(.+(\\|.+)+\\)|[^\\|]*)\\[(\\d+|\\d*\\+|\\*|\\d*\\.\\.\\d*)?\\]\$/";
     $identityStructure = array("check" => function ($data, $null, &$failed) {
         return true;
     }, "format" => function ($data) {
         return $data;
     });
     // allow "type1|type2|..."
     $types = explode("|", $string);
     if (preg_match($quickArray, $string)) {
         $structure = new ArrayS();
         $structure->setFormat($string);
         $structure->setCountStrict($this->countStrict);
         $arrayStructure = true;
         $objects = array($structure);
         $i = count($types) + 1;
     } else {
         /** @var Structure[] $objects */
         $objects = array();
         // Use a do-while to check always $type[0]
         $i = 0;
     }
     while (count($types) > $i) {
         $type = $types[$i];
         if (preg_match($numeric, $type, $matches)) {
             switch ($type[0]) {
                 case "n":
                     $structure = new NumericS();
                     break;
                 case "f":
                     $structure = new FloatS();
                     break;
                 case "i":
                     $structure = new IntegerS();
                     break;
             }
             /** @var NumericS $structure */
             $structure->setRange($matches[2]);
         } else {
             if (preg_match($valueSetScalar, $type, $matches)) {
                 switch ($type[0] . $type[1]) {
                     default:
                         //fall through to _scalar_
                     //fall through to _scalar_
                     case "sc":
                         $structure = new ScalarS();
                         break;
                     case "st":
                         $structure = new StringS();
                         break;
                     case "nu":
                         $structure = new NumericS();
                         break;
                     case "fl":
                         $structure = new FloatS();
                         break;
                     case "in":
                         $structure = new IntegerS();
                         break;
                     case "bo":
                         $structure = new BooleanS();
                         break;
                 }
                 /** @var ScalarS $structure */
                 $structure->setValueSet($matches[2]);
             } else {
                 if (preg_match($lengthString, $type, $matches)) {
                     $structure = new StringS();
                     $structure->setLength($matches[1]);
                 } else {
                     if (preg_match($quickArray, $type, $matches)) {
                         $structure = new ArrayS();
                         $structure->setFormat($type);
                         $structure->setCountStrict($this->countStrict);
                         $arrayStructure = true;
                     } else {
                         switch ($type) {
                             case "scalar":
                                 $structure = new ScalarS();
                                 break;
                             case "string":
                                 // fall through to _str_
                             // fall through to _str_
                             case "str":
                                 $structure = new StringS();
                                 break;
                             case "numeric":
                                 $structure = new NumericS();
                                 break;
                             case "integer":
                                 // fall through to _int_
                             // fall through to _int_
                             case "int":
                                 $structure = new IntegerS();
                                 break;
                             case "float":
                                 $structure = new FloatS();
                                 break;
                             case "boolean":
                                 // fall through to _bool_
                             // fall through to _bool_
                             case "bool":
                                 $structure = new BooleanS();
                                 break;
                             case "array":
                                 $structure = new ArrayS();
                                 $structure->setFormat("array");
                                 $structure->setCountStrict($this->countStrict);
                                 break;
                             case "*":
                             case "any":
                                 // set structure:identity
                                 $structure = $identityStructure;
                                 break;
                             case "null":
                             case null:
                                 // set structure:null
                                 $structure = array("check" => function ($data, $null, &$failed) {
                                     $valid = is_null($data);
                                     if (!$valid) {
                                         $failed = Structure::typeof($data);
                                     }
                                     return $valid;
                                 }, "format" => function () {
                                     return null;
                                 });
                                 break;
                             default:
                                 if (class_exists($string)) {
                                     // todo: create ObjectS class
                                     $structure = array("check" => function ($data, $null, &$failed) use($string) {
                                         if (is_null($data)) {
                                             $valid = $null;
                                         } else {
                                             $valid = $data instanceof $string;
                                         }
                                         if (!$valid) {
                                             $failed = Structure::typeof($data);
                                         }
                                         return $valid;
                                     }, "format" => $identityStructure["format"]);
                                 } else {
                                     // maybe $format is a simple array (type[] or type[int])
                                     $structure = new ArrayS();
                                     $structure->setFormat($type);
                                     $structure->setCountStrict($this->countStrict);
                                     $arrayStructure = true;
                                 }
                                 break;
                         }
                         //prevent errors
                         if (!isset($structure)) {
                             $structure = $identityStructure;
                         }
                     }
                 }
             }
         }
         // Add the Structure to use it after the loop
         $objects[] = $structure;
         $i++;
     }
     /**
      * Define return functions, depending on the number of $objects
      * (1 or more)
      */
     $ret = array();
     if ($i == 1) {
         if ($objects[0] instanceof Structure) {
             $check = function ($data, $null, &$failed) use($objects) {
                 $objects[0]->setNull($null);
                 return $objects[0]->check($data, $failed);
             };
             $format = function ($data, $null) use($objects) {
                 $objects[0]->setNull($null);
                 return $objects[0]->format($data);
             };
         } else {
             $check = $objects[0]["check"];
             $format = function ($data) use($objects) {
                 return call_user_func($objects[0]["format"], $data);
             };
         }
     } else {
         $check = function ($data, $null, &$failed) use($objects) {
             foreach ($objects as $obj) {
                 if ($obj instanceof Structure) {
                     $obj->setNull($null);
                     if ($obj->check($data, $failed)) {
                         return true;
                     }
                 } else {
                     if (is_array($obj) && isset($obj["check"])) {
                         $check = $obj["check"];
                         if ($check($data, $null, $failed)) {
                             return true;
                         }
                     }
                 }
             }
             return false;
         };
         $format = function ($data, $null) use($objects) {
             foreach ($objects as $obj) {
                 try {
                     if ($obj instanceof Structure) {
                         $obj->setNull($null);
                         return $obj->format($data);
                     } else {
                         return call_user_func($obj["format"], $data);
                     }
                 } catch (\Exception $e) {
                 }
             }
             throw new \Exception("Unable to format \$data");
         };
     }
     $ret["check"] = $check;
     $ret["format"] = $format;
     if (isset($arrayStructure) && $arrayStructure) {
         $ret["meta"] = "array";
     }
     return $ret;
 }