/**
  * Serialize according to the rules set up in the template into an array
  *
  * @param array $template Seriplater template
  * @param array $toSerialize Raw data to serialize
  * @return array Serialized data
  */
 public function serialize(array $template, array $toSerialize)
 {
     $entityData = [];
     // Find id field
     foreach ($template as $field => $rule) {
         if ($rule instanceof RuleInterface && $rule->isId() && isset($toSerialize[$field])) {
             $entityData["_id"] = $this->idFactory->get($rule->getValue(), $toSerialize[$field]);
             $entityData[$field] = $toSerialize[$field];
         }
     }
     return $entityData;
 }
Example #2
0
 /**
  * Serialize the given data
  *
  * @param array $toSerialize The unserialized raw data from a database
  * @return array The serialized array
  * @throws IntegrityException
  */
 public function serialize(array $toSerialize)
 {
     $container = [];
     foreach ($this->template as $key => $rule) {
         if ($rule instanceof RuleInterface && $rule->isId()) {
             if (isset($toSerialize[$key])) {
                 $container["_id"] = $this->idFactory->get($rule->getValue(), $toSerialize[$key]);
                 break;
             } else {
                 throw new IntegrityException("Couldn't find the id rule for the serialization");
             }
         }
     }
     return $container;
 }
Example #3
0
 /**
  * Go through the unserialized data recursively
  *
  * @param mixed $template Seriplater template/rule
  * @param mixed $data Scope data
  * @param string $dotPath Dot path to scope
  * @return array Serialized results
  * @throws IntegrityException when illegal structures or missing pieces are encountered
  */
 private function walkUnserializedData($template, $data, $dotPath = "")
 {
     if (is_array($template)) {
         $serialized = [];
         foreach ($template as $field => $content) {
             if ($content instanceof RuleInterface) {
                 if (!isset($data[$field]) && $content->isOptional() || $content->isHasMany() || $content->isInherited()) {
                     // Skip serializing if field is missing & optional, or a hasMany field, or field is inherited
                     continue;
                 } elseif ($content->isId()) {
                     // If it's an id field set the _id and keep going
                     $serialized["_id"] = $this->idFactory->get($content->getValue(), $data[$field]);
                     continue;
                 } elseif (!array_key_exists($field, $data)) {
                     // Missing field with no excuses
                     throw new IntegrityException("Required field '{$field}' missing");
                 }
             } elseif (!array_key_exists($field, $data)) {
                 // Missing field with no excuses
                 throw new IntegrityException("Required field '{$field}' missing");
             }
             $fieldValue = $this->walkUnserializedData($content, $data[$field], $this->mergeDotPaths($dotPath, $field));
             if ($fieldValue !== ["_null"]) {
                 $serialized[$field] = $fieldValue;
             }
         }
         return $serialized;
     } else {
         if (is_scalar($template)) {
             // Scalar value, just save it as is
             return $template;
         } elseif ($template->isValue()) {
             // Regular value
             return $data;
         } elseif ($template->isInherited() || $template->isIncrementing() || $template->isHasMany()) {
             // Skip fields with inheritance, increments or hasMany
             return ["_null"];
         } elseif ($template->isReference()) {
             // Reference
             if ($data === null) {
                 // Reference to a null value
                 if ($template->isNullable()) {
                     // Allowed
                     return null;
                 } else {
                     // Not allowed
                     throw new IntegrityException("Encountered NULL when parsing a '" . $template->getValue()["entityName"] . "'' reference");
                 }
             }
             if ($template->isCollection()) {
                 // An array of references
                 $refs = [];
                 foreach ($data as $dbId) {
                     $refs[] = ["_ref" => $this->idFactory->get($template->getValue()["entityName"], $dbId)];
                 }
                 return $refs;
             } else {
                 // A single reference
                 return ["_ref" => $this->idFactory->get($template->getValue()["entityName"], $data)];
             }
         } elseif ($template->isConditions()) {
             // Conditions rule
             $value = $template->getValue();
             $field = $value["field"];
             $cases = $value["cases"];
             $defaultCase = $value["defaultCase"];
             if (!isset($this->toSerialize[$field])) {
                 throw new IntegrityException("Required conditions field '{$field}' missing'");
             }
             foreach ($cases as $case => $rule) {
                 if ($this->toSerialize[$field] == $case) {
                     return $this->walkUnserializedData($rule, $data, $dotPath);
                 }
             }
             if (is_null($defaultCase)) {
                 throw new IntegrityException("No conditions matched, and no default case provided");
             } else {
                 return $this->walkUnserializedData($rule, $data, $dotPath);
             }
         } elseif ($template->isDeep()) {
             // Regexp deep rule
             $finders = $template->getValue();
             $newData = $data;
             $dotData = Arr::dot($data);
             foreach ($finders as $pattern => $rule) {
                 foreach ($dotData as $innerDotPath => $innerDotValue) {
                     if (preg_match($pattern, $innerDotPath) === 1) {
                         Arr::set($newData, $innerDotPath, $this->walkUnserializedData($rule, $innerDotValue, $this->mergeDotPaths($dotPath, $innerDotPath)));
                     }
                 }
             }
             return $newData;
         } else {
             throw new IntegrityException("Invalid template rule");
         }
     }
 }