/** * Compare Restrictions * * This allows restrictions to be compared despite their configurations * This comes up when trying to compare restrictions like so: * * $this->restrictions == $that->restrictions * * This takes into count configurations, so this avoids that. * * @param Falcraft\Data\Types\Restrictions The first restriction * @param Falcraft\Data\Types\Restrictions The second restriction * * @return bool Equal? * */ public static function compare(Restrictions $R1, Restrictions $R2) { $types1 = $R1->getAllowedTypes(); $types2 = $R2->getAllowedTypes(); if (!array_diff($types1, $types2) && !array_diff($types2, $types1)) { $classes1 = $R1->getAllowedClasses(); $classes2 = $R2->getAllowedClasses(); if (!array_diff($classes1, $classes2) && !array_diff($classes2, $classes1)) { return true; } } return false; }
/** * Set the offset in the list to the provided value * * @param int $key The index to the list item * @param mixed $value The value to set to * * @return int|Falcraft\Data\Types\Null New number of list elements, or * Null otherwise * * @throws \InvalidArgumentException if the value doesn't meet * restrictions * */ public function offsetSet($key, $value) { if (Restrictions::checkRestrictedValues(array($value), $this->restrictions, $this->conf->strict)) { if ($key) { $this->list[$key] = $value; } else { // no key means new element $this->list[] = $value; } } else { if ($this->conf->strict) { throw new Exception\InvalidArgumentException('RestrictedList->offsetSet: Value not in restrictions.'); } else { return; } } }
/** * UnorderedNode Class Constructor * * It takes three RestrictedSets, whose restrictions have to match the * UnorderedNode restrictions (VertexInterface). In this vertex model * (unordered node) incoming connections are parents, outgoing connections * are children, and mutual connections are siblings. These are all in * any order, so unlike an HTML document for instance, it can't be put * 'in order'. * * This initializes the restrictions member for the interface * VertexInterface (supported in Falcraft\Data\Types\Restrictions 1.3) * * NOTE: Mutual connections are made one way, not in the constructor * * @param Falcraft\Data\Types\RestrictedSet $parents The initial parent vertices * @param Falcraft\Data\Types\RestrictedSet $children The initial children vertices * @param Falcraft\Data\Types\RestrictedSet $siblings The initial sibling vertices * * @throws Falcraft\Data\Types\Exception\InvalidArgumentException * If a given RestrictedSet has non-matching restrictions * */ public function __construct(RestrictedSet $parents = null, RestrictedSet $children = null, RestrictedSet $siblings = null) { $this->initializeIdentifier(); /* Initialize restrictions, anything that is an instanceof (implements) VertexInterface) */ $this->restrictions = new Restrictions(array(Type::TYPED_OBJECT), array('Falcraft\\Data\\Types\\Resource\\VertexInterface'), array('autoload' => true)); // Map the parameters to the AbstractVertex lingo $params = array('incoming' => 'parents', 'outgoing' => 'children', 'mutual' => 'siblings'); // Cycle through parameters, replacing 'incoming' with 'parents' etc. // This whole mixup is done so that people won't be confused about where // to put parents, children, and siblings. (incoming, outgoing, mutual) foreach ($params as $key => $param) { if (is_null(${$param})) { $this->{$key} = RestrictedSet::build(array(), $this->restrictions, array('strict' => true, 'unique' => true)); /* Make sure the restrictions on the RestrictedSet match with our own restrictions */ } else { if (Restrictions::compare($this->restrictions, ${$param}->getRestrictions())) { $this->{$key} = ${$param}; } else { throw new TypesException\InvalidArgumentException('UnorderedNode->__construct: Improper RestrictedSet ' . 'At Constructor: ' . $param); } } } // Connect actual nodes Set::map(array($this, 'connectIncoming'), $this->incoming); foreach ($this->incoming->iterate() as $vertex) { $vertex->connectOutgoing($this); } Set::map(array($this, 'connectOutgoing'), $this->outgoing); foreach ($this->outgoing->iterate() as $vertex) { $vertex->connectIncoming($this); } }
/** * Add a value to the set as a reference * * Runs the value by the restrictions, only triggering if set is strict * otherwise doing nothing and exiting the function * * @param mixed $value Value to add to the set, must be of allowed type * * @return string|false The datum identifier, false otherwise * * @throws Exception\InvalidArgumentException if 'strict' option is set * and type is not in Restrictions * */ public function addReference(&$value) { try { $valid = Restrictions::checkElements(array($value), $this->restrictions, $this->conf->strict); } catch (Exception\InvalidArgumentException $e) { if ($this->conf->strict) { throw new Exception\InvalidArgumentException('RestrictedSet->addReference: Restricted Value'); } else { return false; } } // Passes restrictions, but safety check if ($valid) { return parent::addReference($value); } }
/** * Is the given restriciton object registered? * * @static * * @param Falcraft\Data\Types\Restrictions * The restrictions possibly registered * * @return bool True on success, False on failure * */ public static function isRestrictionObjectRegistered($restrictions) { if (self::$registry === null) { self::$registry = new Map(); self::initRegsitry(); } $values = self::$registry->getValues(); foreach ($values as $value) { if (Restrictions::compare($restrictions, $value)) { return true; } } return false; }
/** * Set the offset in the list to the provided value * * @param int $key The index to the list item * @param mixed $value The value to set to * * @return int|Falcraft\Data\Types\Null New number of list elements, * or Null otherwise * * @throws Exception\InvalidArgumentException if the value doesn't meet * restrictions * */ public function offsetSet($key, $value) { if (Restrictions::checkElements(array($value), $this->restrictions, $this->conf->strict)) { $this->list->offsetSet($key, $value); } else { if ($this->conf->strict) { throw new Exception\InvalidArgumentException('RestrictedStack->offsetSet: type not allowed'); } else { return; } } }
/** * Checks a value to see if it is in restrictions * * @param mixed $values,.. The values to check * * @return boolean Allowed or not? * * @throws Exception\InvalidArgumentException if value not in * restrictions, and strict option is set * */ private function check() { if (!Types\Restrictions::checkElements(func_get_args(), $this->restrictions, $this->conf->strict)) { if ($this->conf->strict) { throw new Exception\InvalidArgumentException('AbstractRestrictedList->check: Value not in ' . 'restrictions'); } else { return false; } } return true; }
/** * The Leaf Constructor * * This accepts an array of leaves (LeafInterface) * * Options - identifier: Instantiate the leaf with a specific identifier * prefix: set the identifier prefix * strict: throw errors * NOTE: There is no check for duplicate identifiers * * @param array $leaves A plain array of LeafInterface compatible objects * @param array $options StandardObject options, see above * */ public function __construct(array $leaves = array(), $options = array()) { // Set default options if (is_array($options)) { $options = array_change_key_case($options); } // default values $options = array_merge(array('identifier' => false, 'prefix' => 'Leaf', 'strict' => false), $options); $this->configure($options); if ($this->conf->identifier) { $this->identifier = $this->conf->identifier; } if ($this->conf->prefix) { $this->identityPrefix = $this->conf->prefix; } $leafRestrictions = new Types\Restrictions(array(Type::TYPED_OBJECT), array('Falcraft\\Data\\Types\\Resource\\LeafInterface'), array('strict' => true)); $allowed = Types\Restrictions::checkElements($leaves, $leafRestrictions, array('strict' => true)); if ($allowed) { $this->leaves = new Types\RestrictedList(array(), $leafRestrictions, array('strict' => true)); foreach ($leaves as $leaf) { $this->leaves[$leaf->getIdentifier()] = $leaf; } } else { if ($this->conf->strict) { throw new Exception\InvalidArgumentException('AbstractLeaf->__construct(): Illegal Value'); } } }
$success = false; } if ($success) { echo "Success!\n\nAllowed Types -- \n\n"; var_dump($defaultRestrictions->getAllowedTypes()); echo "\n"; } else { echo "Failure...\n"; } echo "Predicate Retrieval -> "; $success = true; $testRestrictions = $allowedTypes = $allowedClasses = null; require_once '../../../Data/Types/Set.php'; require_once '../../../Data/Types/Range.php'; try { $testRestrictions = new Types\Restrictions(array(Type::TYPED_OBJECT), array('Falcraft\\Data\\Types\\Set', 'Falcraft\\Data\\Types\\Range'), array('autoload' => false)); $allowedTypes = $testRestrictions->getAllowedTypes(); $allowedClasses = $testRestrictions->getAllowedClasses(); } catch (\Exception $e) { $success = false; } if ($success) { echo "Success!\n\n"; echo "Allowed Types -- \n\n"; var_dump($allowedTypes); echo "\nAllowed Classes -- \n\n"; var_dump($allowedClasses); echo "\n"; } else { echo "Failure...\n"; }
/** * OrderedNode Class Constructor * * It takes two RestrictedSets, whose restrictions have to match the * OrderedNode restrictions (VertexInterface). In this vertex model * (ordered node) incoming connections are parents, outgoing connections * are children, and mutual connections are siblings. * * Children are a special matter, they're made up a VertexList. * A VertexList is an ordered list of Vertices (held together * by a double linked list of edges) The vertexlist takes care of the * children's mutual connections (I know, bad coupling). To do * vertexlist operations use getVertexList() * * This initializes the restrictions member for the interface * VertexInterface (supported in Falcraft\Data\Types\Restrictions 1.3) * * @param Falcraft\Data\Types\RestrictedSet $parents * The initial parent vertices * @param array $children * The initial children vertices in reference * @param Falcraft\Data\Types\RestrictedSet $siblings * The initial sibling vertices * * @throws TypesException\InvalidArgumentException * If a given RestrictedSet has non-matching restrictions * */ public function __construct(RestrictedSet $parents = null, array $children = array(), RestrictedSet $siblings = null, array $options = array()) { parent::__construct(null, null, null, $options); // Initialize restrictions, anything that is an instanceof (implements) VertexInterface) $this->restrictions = new Restrictions(array(Type::TYPED_OBJECT), array('Falcraft\\Data\\Types\\Resource\\VertexInterface'), array('autoload' => true)); // Map the parameters to the AbstractVertex lingo $params = array('incoming' => 'parents', 'mutual' => 'siblings'); // Cycle through parameters, replacing 'incoming' with 'parents' etc. // This whole mixup is done so that people won't be confused about where // to put parents, children, and siblings. (incoming, outgoing, mutual) foreach ($params as $key => $param) { if (is_null(${$param})) { $this->{$param} = RestrictedSet::build(array(), $this->restrictions, array('strict' => true)); // Make sure the restrictions on the RestrictedSet match with our own restrictions } else { if (Restrictions::compare($this->restrictions, ${$param}->getRestrictions())) { $this->{$key} = ${$param}; } else { throw new TypesException\InvalidArgumentException('OrderedNode->__construct: Improper RestrictedSet At ' . 'Constructor: ' . $param); } } } // Children are a special matter in this class $this->outgoing = new VertexList($children); }