/** * Builds the Meta object * * @param mixed $metaOrName Can be a string or an array or a Meta object that will be used to define this object. * If a string, then it's assumed to be the Name for the meta. * If an array, the keys expected should match the {@link $fields} * If a Meta object, then it will be cloned. * @param string $value (optional) The value for this meta * @param string $sectionID (optional) The section ID for this meta */ public function __construct($metaOrName, $value = '') { if ($metaOrName instanceof Meta) { $this->fields = $metaOrName->toArray(); } else { if (is_array($metaOrName)) { foreach ($metaOrName as $key => $val) { $this->fields[$key] = $val; unset($key); unset($val); } } else { if (is_string($metaOrName)) { // assume first param is element if (strpos($metaOrName, '=') === false || !empty($value)) { $this->fields['MetaName'] = $metaOrName; $this->fields['MetaValue'] = $value; } else { throw new MetaException('Creating meta using strings is deprecated, please use array or parameters'); } } } } if (isset($this->fields['NoValidation'])) { return; } if (empty($this->fields['MetaName'])) { throw new MetaException('Invalid meta: No MetaName was specified'); } $this->fields['MetaName'] = strtolower($this->fields['MetaName']); if (!SlugUtils::isSlug($this->fields['MetaName'])) { throw new MetaException('Invalid meta: "' . $this->fields['MetaName'] . '" must be valid slug'); } }
/** * Builds the MetaPartial object * * @param mixed $metaOrName Can be a string or an array or a Meta/MetaPartial object that will be used to define this object. * If a string, then it's assumed to be the Name for the meta. * If an array, the keys expected should match the {@link $fields} * If a Meta or MetaPartial object, then it will be used to build the MetaPartial * @param string $value (optional) The value for this meta * @param string $sectionID (optional) The section ID for this meta */ public function __construct($metaOrName, $value = '') { $this->fields = array('MetaName' => ''); if ($metaOrName instanceof MetaPartial || $metaOrName instanceof Meta) { $this->fields = $metaOrName->toArray(); } else { if (is_array($metaOrName)) { $this->fields = array_merge($this->fields, $metaOrName); } else { if (is_string($metaOrName)) { if (strpos($metaOrName, '#') === false) { // assume first param is element $this->fields['MetaName'] = $metaOrName; if ($value != '') { $this->fields['MetaValue'] = $value; } } else { // assume first param is tag string if (preg_match("/(meta)?#([a-z0-9-]+)?(=((\")?([^\"]*)(\")?))?\$/", $metaOrName, $valuematch)) { $this->fields['MetaName'] = $valuematch[2]; if (isset($valuematch[6])) { $this->fields['MetaValue'] = $valuematch[6]; } } } } } } if (empty($this->fields['MetaName'])) { throw new MetaException('Invalid MetaPartial: No name was specified'); } $this->fields['MetaName'] = strtolower($this->fields['MetaName']); if (!SlugUtils::isSlug($this->fields['MetaName'])) { throw new MetaException('Invalid MetaPartial: "' . $this->fields['MetaName'] . '" must be valid slug'); } if (!empty($this->fields['MetaValue'])) { $this->fields['MetaValue'] = preg_replace("/\\s+/s", ' ', $this->fields['MetaValue']); } }
public function __construct($tagOrElement, $slug = '', $role = '', $value = '') { if ($tagOrElement instanceof TagPartial || $tagOrElement instanceof Tag) { $this->fields = $tagOrElement->toArray(); return; } $this->fields = array_merge($this->fields, array('TagElement' => '', 'TagAspect' => '', 'TagSlug' => '', 'TagRole' => '', 'TagValue' => '')); if (is_array($tagOrElement)) { $this->fields = array_merge($this->fields, $tagOrElement); } else { if (is_string($tagOrElement)) { // assume first param is element if (!empty($slug) || !empty($role) || !empty($value)) { if (substr($tagOrElement, 0, 1) == '@') { $this->fields['TagAspect'] = substr($tagOrElement, 1); } else { $this->fields['TagElement'] = $tagOrElement; } $this->fields['TagSlug'] = $slug; $this->fields['TagRole'] = $role; $this->fields['TagValue'] = $value; // assume first param is tag string } else { $expressions = StringUtils::smartSplit($tagOrElement, ".", '"', '\\"', 2); if (preg_match("/^(((?P<ai>@)?(?P<el>[a-z0-9-]+))?(:(?P<s>[a-z0-9\\/\\-]+)?)?)?(#(?P<r>[a-z0-9-]+)?)?(=(?P<v>.+?))?\$/", array_shift($expressions), $m)) { if (!empty($m['ai'])) { $this->fields['TagAspect'] = !empty($m['el']) ? $m['el'] : ''; } else { $this->fields['TagElement'] = !empty($m['el']) ? $m['el'] : ''; } $this->fields['TagSlug'] = !empty($m['s']) ? $m['s'] : ''; $this->fields['TagRole'] = !empty($m['r']) ? $m['r'] : ''; $this->fields['TagValue'] = !empty($m['v']) ? $m['v'] : ''; if (!empty($expressions)) { // if(count($expressions) > 1) $this->fields['ChildPartials'] = current($expressions); // else // $this->fields['ChildPartial'] = $expressions[0]; } } } } else { throw new Exception('Invalid parameter to TagPartial: ' . ClassUtils::getQualifiedType($tagOrElement)); } } if (empty($this->fields['TagElement']) && empty($this->fields['TagAspect']) && empty($this->fields['TagRole'])) { throw new TagException('Invalid partial: No element, aspect, or role was specified [' . print_r($tagOrElement, true) . ']'); } if (!empty($this->fields['TagAspect'])) { // $this->fields['TagAspect'] = strtolower($this->fields['TagAspect']); if (!preg_match("/[a-z0-9-]+/", $this->fields['TagAspect'])) { throw new TagException('Invalid partial: Aspect "' . $this->fields['TagAspect'] . '" must contain only characters or dash'); } } if (!empty($this->fields['TagSlug'])) { $this->fields['TagSlug'] = strtolower($this->fields['TagSlug']); if (!SlugUtils::isSlug($this->fields['TagSlug'], true)) { throw new TagException('Invalid tag: "' . $this->fields['TagSlug'] . '" must be valid slug'); } } if (!empty($this->fields['TagRole']) && !SlugUtils::isSlug($this->fields['TagRole'])) { $this->fields['TagRole'] = SlugUtils::createSlug($this->fields['TagRole']); } if (!empty($this->fields['TagValue']) && !SlugUtils::isSlug($this->fields['TagValue'])) { $this->fields['TagValue'] = SlugUtils::createSlug($this->fields['TagValue']); } // lowercase all parts foreach (array('TagElement', 'TagAspect', 'TagSlug', 'TagRole', 'TagValue') as $name) { $this->fields[$name] = strtolower($this->fields[$name]); } }
/** * Returns TRUE if the given value passes validation. * * @param string $value A value to test * * @return boolean */ public function isValid($value) { if ($this->skipValidation) { return true; } $datatype = $this->validation['datatype']; //NULL check, empty strings are considered null if (in_array($datatype, array('string', 'url', 'email', 'slug', 'slugwithslash', 'html', 'binary', 'json')) && strlen(trim($value)) == 0) { $value = null; } if ($this->validation['nullable'] === false && $value === null && $datatype != 'boolean') { $this->failureCode = 'nullable'; $this->failureMessage = 'cannot be empty'; return false; } //Nothing more to validate if the value is null... if ($value === null) { return true; } //Check date makes sense if ($datatype === 'date') { //todo: not sure how to check validity of date... it's already a DateTime instance. if (false) { $this->failureCode = 'invalid'; $this->failureMessage = 'is an invalid date'; return false; } } //Validate MIN $min = $this->validation['min']; if ($min != null) { if ($datatype === 'float') { if ($value < floatval($min)) { $this->failureCode = 'min'; $this->failureMessage = 'is less than the minimum value'; return false; } } else { if ($datatype === 'int') { if ($value < intval($min)) { $this->failureCode = 'min'; $this->failureMessage = 'is less than the minimum value'; return false; } } else { if (is_string($value) && strlen($value) < intval($min)) { $this->failureCode = 'minlength'; $this->failureMessage = 'must be at least ' . $min . ' characters'; return false; } } } } //Validate MAX $max = $this->validation['max']; if ($max != null) { if ($datatype === 'float') { if ($value > floatval($max)) { $this->failureCode = 'max'; $this->failureMessage = 'is more than the maximum value'; return false; } } else { if ($datatype === 'int') { if ($value > intval($max)) { $this->failureCode = 'max'; $this->failureMessage = 'is more than the maximum value'; return false; } } else { $maxbytes = intval($max); if (intval($max) < 255) { // count characters if (is_string($value) && StringUtils::charCount($value) > intval($max)) { $this->failureCode = 'maxlength'; $this->failureMessage = 'must be a maximum of ' . $max . ' characters'; return false; } $maxbytes = 255; } // count bytes if (is_string($value) && StringUtils::byteCount($value) > intval($maxbytes)) { $this->failureCode = 'maxlength'; $this->failureMessage = 'must be a maximum of ' . $maxbytes . ' bytes'; return false; } } } } if ($datatype === 'slug') { if (!SlugUtils::isSlug($value, false)) { $this->failureCode = 'invalid'; $this->failureMessage = 'is not a valid slug, cannot contain slashes'; return false; } } if ($datatype === 'slugwithslash') { if (!SlugUtils::isSlug($value, true)) { $this->failureCode = 'invalid'; $this->failureMessage = 'is not a valid slug'; return false; } } if ($datatype === 'url') { if (!URLUtils::isUrl($value)) { $this->failureCode = 'invalid'; $this->failureMessage = 'is not a valid URL'; return false; } } if ($datatype === 'email') { if (!EmailUtils::isEmailAddress($value)) { $this->failureCode = 'invalid'; $this->failureMessage = 'is not a valid email address'; return false; } } if ($datatype === 'json') { if (!JSONUtils::isValid($value)) { $this->failureCode = 'invalid'; $this->failureMessage = 'is not a valid json string'; return false; } } //Validate MATCH expression $match = $this->validation['match']; if ($match != null) { // Automatically escape unescaped slashes in the match before running it $match = preg_replace('/([^\\\\])\\//', '$1\\/', $match); if (preg_match('/' . $match . '/s', $value) === 0) { $this->failureCode = 'invalid'; //$this->failureMessage = 'is invalid (' . substr($value, 0, 255) . ')'; $this->failureMessage = 'is invalid'; return false; } } // Validate all custom functions foreach ($this->validation['callback'] as $callback) { if (!empty($callback) && call_user_func($callback, $value) === false) { $this->failureCode = $callback; $this->failureMessage = 'is invalid'; return false; } } return true; }
protected function validateMetas(array $metas) { foreach ($metas as $meta) { $role = 'unknown id'; try { // Required attributes foreach (array('id') as $attr) { if ($meta->attribute($attr) == null) { throw new SchemaException("Required attribute '{$attr}' not found for meta: " . htmlentities($meta->asPrettyXML())); } } $role = ltrim($meta->attribute('id'), '#'); if (!SlugUtils::isSlug($role)) { throw new SchemaException("Meta ID is in an invalid format. Must be in valid slug format. Meta: " . $meta->attribute('id')); } if (in_array($role, $this->allRoles)) { throw new SchemaException("Meta id [" . $role . "] already used in schema"); } $this->allRoles[] = $role; // Required children foreach (array('title', 'validation') as $required_child) { if (!$meta->{$required_child}) { throw new SchemaException("Required child element '{$required_child}' not found for meta: " . $meta->attribute('id')); } } // Validate we have some text for the title if (strlen((string) $meta->title) == 0) { throw new SchemaException("Meta title must have a value. Meta: " . $meta->attribute('id')); } // Check that the <validation> tag is sane, if it exists $this->validationCheck($meta->validation); if ($meta->validation->attribute('datatype') == 'boolean' && empty($meta->default)) { throw new SchemaException('Meta boolean datatype must specify a default value: ' . $meta->attribute('id')); } } catch (SchemaException $e) { throw new SchemaException("Unable to parse meta definition [{$role}]:\n" . $e->getMessage()); } } }