コード例 #1
0
ファイル: Property.php プロジェクト: rambo/jackalope
 /**
  * Create a property, either from server data or locally
  *
  * To indicate a property has newly been created locally, make sure to pass
  * true for the $new parameter.
  *
  * @param object $factory  an object factory implementing "get" as described in \jackalope\Factory
  * @param array $data array with fields
  *                    type (integer or string from PropertyType)
  *                    and value (data for creating value object - array for multivalue property)
  * @param string $path the absolute path of this item
  * @param Session the session instance
  * @param ObjectManager the objectmanager instance - the caller has to take care of registering this item with the object manager
  * @param boolean $new optional: set to true to make this property aware its not yet existing on the server. defaults to false
  */
 public function __construct($factory, array $data, $path, Session $session, ObjectManager $objectManager, $new = false)
 {
     parent::__construct($factory, $path, $session, $objectManager, $new);
     $type = $data['type'];
     if (is_string($type)) {
         $type = \PHPCR\PropertyType::valueFromName($type);
     } elseif (!is_numeric($type)) {
         throw new \PHPCR\RepositoryException("INTERNAL ERROR -- No valid type specified ({$type})");
     } else {
         //sanity check. this will throw InvalidArgumentException if $type is not a valid type
         \PHPCR\PropertyType::nameFromValue($type);
     }
     $this->type = $type;
     if (is_array($data['value'])) {
         $this->isMultiple = true;
         $this->value = array();
         foreach ($data['value'] as $value) {
             $this->value[] = Helper::convertType($value, $type);
         }
     } elseif (null !== $data['value']) {
         $this->value = Helper::convertType($data['value'], $type);
     } else {
         throw new \PHPCR\RepositoryException('INTERNAL ERROR -- data[value] may not be null');
     }
 }
コード例 #2
0
ファイル: Node.php プロジェクト: jackalope/jackalope-fs
 public function setProperty($name, $value = null, $type = 'String')
 {
     if (is_integer($type)) {
         $type = PropertyType::nameFromValue($type);
     }
     $this->properties[$name] = array('value' => $value, 'type' => $type);
 }
コード例 #3
0
 /**
  * Determine PropertyType from on variable type.
  *
  * This is most of the remainder of ValueFactory that is still needed.
  *
  * - if the given $value is a Node object, type will be REFERENCE, unless
  *    $weak is set to true which results in WEAKREFERENCE
  * - if the given $value is a DateTime object, the type will be DATE.
  * - if the $value is an empty array, the type is arbitrarily set to STRING
  * - if the $value is a non-empty array, the type of its first element is
  *   chosen.
  *
  * Note that string is converted to date exactly if it matches the jcr
  * formatting spec for dates (sYYYY-MM-DDThh:mm:ss.sssTZD) according to
  * http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.6.4.3%20From%20DATE%20To
  *
  * @param mixed   $value The variable we need to know the type of
  * @param boolean $weak  When a Node is given as $value this can be given
  *                       as true to create a WEAKREFERENCE.
  *
  * @return int One of the type constants
  *
  * @throws ValueFormatException if the type can not be determined
  */
 public function determineType($value, $weak = false)
 {
     if (is_array($value)) {
         if (0 === count($value)) {
             // there is no value to determine the type on. we arbitrarily
             // chose string, which is what jackrabbit does as well.
             return PropertyType::STRING;
         }
         $value = reset($value);
     }
     return PropertyType::determineType($value, $weak);
 }
コード例 #4
0
 /**
  * Convert a node type into YAML format
  *
  * @param NodeTypeInterface
  *
  * @return string
  */
 public function serialize(NodeTypeInterface $nt)
 {
     $out = array('name' => $nt->getName(), 'declared_supertypes' => $nt->getDeclaredSupertypeNames(), 'abstract' => (bool) $nt->isAbstract(), 'mixin' => (bool) $nt->isMixin(), 'orderable_child_nodes' => (bool) $nt->hasOrderableChildNodes(), 'queryable' => (bool) $nt->isQueryable(), 'primary_item' => $nt->getPrimaryItemName(), 'properties' => array(), 'children' => array());
     foreach ($nt->getDeclaredPropertyDefinitions() as $pd) {
         $property = $this->getItemDefinitionArray($pd);
         $property = array_merge($property, array('required_type' => PropertyType::nameFromValue($pd->getRequiredType()), 'value_constraints' => $pd->getValueConstraints(), 'default_values' => $pd->getDefaultValues(), 'multiple' => (bool) $pd->isMultiple(), 'available_query_operators' => $pd->getAvailableQueryOperators(), 'full_text_searchable' => (bool) $pd->isFullTextSearchable(), 'query_orderable' => (bool) $pd->isQueryOrderable()));
         $out['properties'][] = $property;
     }
     foreach ($nt->getDeclaredChildNodeDefinitions() as $cd) {
         $child = $this->getItemDefinitionArray($cd);
         $child = array_merge($child, array('required_primary_types' => $cd->getRequiredPrimaryTypeNames(), 'default_primary_type' => $cd->getDefaultPrimaryTypeName(), 'same_name_siblings' => (bool) $cd->allowsSameNameSiblings()));
         $out['children'][] = $child;
     }
     return Yaml::dump($out, 10);
 }
コード例 #5
0
 private function walkNode(NodeBuilder $builder, NodeInterface $parentNode)
 {
     for ($i = $builder->getRangeStart(); $i <= $builder->getRangeEnd(); $i++) {
         $name = str_replace(NodeBuilder::ITERATION_TOKEN, $i, $builder->getName());
         $this->count++;
         $node = $parentNode->addNode($name, $builder->getNodeTypeName());
         foreach ($builder->getProperties() as $property) {
             list($name, $value, $type) = $property;
             $node->setProperty($name, $value, PropertyType::valueFromName($type));
         }
         foreach ($builder->getNodes() as $childNodeBuilder) {
             $this->walkNode($childNodeBuilder, $node);
         }
     }
 }
コード例 #6
0
 private function configure()
 {
     $this->nodeTypeMap = array('name' => function ($t, $v) {
         $t->setName($v);
     }, 'auto_created' => function ($t, $v) {
         $t->setAutoCreated((bool) $v);
     }, 'declared_supertypes' => function ($t, $v) {
         $t->setDeclaredSuperTypeNames((array) $v);
     }, 'abstract' => function ($t, $v) {
         $t->setAbstract($v);
     }, 'mixin' => function ($t, $v) {
         $t->setMixin((bool) $v);
     }, 'orderable_child_nodes' => function ($t, $v) {
         $t->setOrderableChildNodes((bool) $v);
     }, 'primary_item' => function ($t, $v) {
         $t->setPrimaryItemName((string) $v);
     }, 'queryable' => function ($t, $v) {
         $t->setQueryable((bool) $v);
     });
     $this->childDefinitionMap = array_merge($this->getItemDefinitionMap(), array('default_primary_type' => function ($t, $v) {
         $t->setDefaultPrimaryTypeName($v);
     }, 'same_name_siblings' => function ($t, $v) {
         $t->setSameNameSiblings((bool) $v);
     }, 'required_primary_types' => function ($t, $v) {
         $t->setRequiredPrimaryTypeNames((array) $v);
     }));
     $this->propertyMap = array_merge($this->getItemDefinitionMap(), array('multiple' => function ($t, $v) {
         $t->setMultiple((bool) $v);
     }, 'default_values' => function ($t, $v) {
         $t->setDefaultValues((array) $v);
     }, 'full_text_searchable' => function ($t, $v) {
         $t->setFullTextSearchable((bool) $v);
     }, 'query_orderable' => function ($t, $v) {
         $t->setQueryOrderable((bool) $v);
     }, 'value_constraints' => function ($t, $v) {
         $t->setValueConstraints((array) $v);
     }, 'required_type' => function ($t, $v) {
         $t->setRequiredType(PropertyType::valueFromName($v));
     }, 'available_query_operators' => function ($t, $v) {
         $queryOperators = array();
         foreach ($v as $queryOperator) {
             $queryOperator = constant('PHPCR\\Query\\QOM\\QueryObjectModelConstantsInterface::' . strtoupper(str_replace('.', '_', $queryOperator)));
             $queryOperators[] = $queryOperator;
         }
         $t->setAvailableQueryOperators($queryOperators);
     }));
 }
コード例 #7
0
 protected function fromXML(DOMElement $node)
 {
     parent::fromXML($node);
     $this->requiredType = \PHPCR\PropertyType::valueFromName($node->getAttribute('requiredType'));
     $this->isMultiple = Helper::getBoolAttribute($node, 'multiple');
     $this->isFullTextSearchable = Helper::getBoolAttribute($node, 'fullTextSearchable');
     $this->isQueryOrderable = Helper::getBoolAttribute($node, 'queryOrderable');
     $xp = new DOMXPath($node->ownerDocument);
     $valueConstraints = $xp->query('valueConstraints/valueConstraint', $node);
     foreach ($valueConstraints as $valueConstraint) {
         $this->valueConstraints[] = $valueConstraint->nodeValue;
     }
     $availableQueryOperators = $xp->query('availableQueryOperators/availableQueryOperator', $node);
     foreach ($availableQueryOperators as $availableQueryOperator) {
         $this->availableQueryOperators[] = $availableQueryOperator->nodeValue;
     }
     $defaultValues = $xp->query('defaultValues/defaultValue', $node);
     foreach ($defaultValues as $defaultValue) {
         $this->defaultValues[] = $defaultValue->nodeValue;
     }
 }
コード例 #8
0
 public function execute(InputInterface $input, OutputInterface $output)
 {
     $session = $this->get('phpcr.session');
     $pathHelper = $this->get('helper.path');
     $path = $session->getAbsPath($input->getArgument('path'));
     $value = $input->getArgument('value');
     $type = $input->getOption('type');
     $nodePath = $pathHelper->getParentPath($path);
     $propName = $pathHelper->getNodeName($path);
     $nodes = $session->findNodes($nodePath);
     foreach ($nodes as $node) {
         $intType = null;
         if ($type) {
             $intType = PropertyType::valueFromName($type);
             if ($intType === PropertyType::REFERENCE || $intType === PropertyType::WEAKREFERENCE) {
                 // convert path to UUID
                 if (false === UUIDHelper::isUuid($value)) {
                     $path = $value;
                     try {
                         $targetNode = $session->getNode($path);
                         $value = $targetNode->getIdentifier();
                     } catch (PathNotFoundException $e) {
                     }
                     if (null === $value) {
                         throw new \InvalidArgumentException(sprintf('Node at path "%s" specified for reference is not referenceable', $path));
                     }
                 }
             }
         } else {
             try {
                 $property = $node->getProperty($propName);
                 $intType = $property->getType();
             } catch (PathNotFoundException $e) {
                 // property doesn't exist and no type specified, default to string
                 $intType = PropertyType::STRING;
             }
         }
         $node->setProperty($propName, $value, $intType);
     }
 }
コード例 #9
0
 /**
  * Convert property definition xml into array.
  *
  * @param  \DOMElement $node
  * @return array
  */
 public function getPropertyDefinitionFromXml(DOMElement $node)
 {
     $data = $this->getItemDefinitionFromXml($node);
     $data['requiredType'] = \PHPCR\PropertyType::valueFromName($node->getAttribute('requiredType'));
     $data['multiple'] = Helper::getBoolAttribute($node, 'multiple');
     $data['fullTextSearchable'] = Helper::getBoolAttribute($node, 'fullTextSearchable');
     $data['queryOrderable'] = Helper::getBoolAttribute($node, 'queryOrderable');
     $xp = new DOMXPath($node->ownerDocument);
     $valueConstraints = $xp->query('valueConstraints/valueConstraint', $node);
     foreach ($valueConstraints as $valueConstraint) {
         $data['valueConstraints'][] = $valueConstraint->nodeValue;
     }
     $availableQueryOperators = $xp->query('availableQueryOperators/availableQueryOperator', $node);
     foreach ($availableQueryOperators as $availableQueryOperator) {
         $data['availableQueryOperators'][] = $availableQueryOperator->nodeValue;
     }
     $defaultValues = $xp->query('defaultValues/defaultValue', $node);
     foreach ($defaultValues as $defaultValue) {
         $data['defaultValues'][] = $defaultValue->nodeValue;
     }
     return $data;
 }
コード例 #10
0
ファイル: Node.php プロジェクト: frogriotcom/jackalope
 /**
  * Initialize or update this object with raw data from backend.
  *
  * @param array   $rawData     in the format as returned from Jackalope\Transport\TransportInterface
  * @param boolean $update      whether to initialize this object or update
  * @param boolean $keepChanges only used if $update is true, same as $keepChanges in refresh()
  *
  * @see Node::__construct()
  * @see Node::refresh()
  */
 private function parseData($rawData, $update, $keepChanges = false)
 {
     //TODO: refactor to use hash array instead of stdClass struct
     if ($update) {
         // keep backup of old state so we can remove what needs to be removed
         $oldNodes = array_flip(array_values($this->nodes));
         $oldProperties = $this->properties;
     }
     /*
      * we collect all nodes coming from the backend. if we update with
      * $keepChanges, we use this to update the node list rather than losing
      * reorders
      *
      * properties are easy as they are not ordered.
      */
     $nodesInBackend = array();
     foreach ($rawData as $key => $value) {
         $node = false;
         // reset to avoid trouble
         if (is_object($value)) {
             // this is a node. add it if
             if (!$update || !$keepChanges || isset($oldNodes[$key]) || !($node = $this->objectManager->getCachedNode($this->path . '/' . $key))) {
                 // for all those cases, if the node was moved away or is deleted in current session, we do not add it
                 if (!$this->objectManager->isNodeMoved($this->path . '/' . $key) && !$this->objectManager->isNodeDeleted($this->path . '/' . $key)) {
                     // otherwise we (re)load a node from backend but a child has been moved away already
                     $nodesInBackend[] = $key;
                 }
             }
             if ($update) {
                 unset($oldNodes[$key]);
             }
         } else {
             //property or meta information
             /* Property type declarations start with :, the value then is
              * the type string from the NodeType constants. We skip that and
              * look at the type when we encounter the value of the property.
              *
              * If its a binary data, we only get the type declaration and
              * no data. Then the $value of the type declaration is not the
              * type string for binary, but the number of bytes of the
              * property - resp. array of number of bytes.
              *
              * The magic property ::NodeIteratorSize tells this node has no
              * children. Ignore that info for now. We might optimize with
              * this info once we do prefetch nodes.
              */
             if (0 === strpos($key, ':')) {
                 if ((is_int($value) || is_array($value)) && $key != '::NodeIteratorSize') {
                     // This is a binary property and we just got its length with no data
                     $key = substr($key, 1);
                     if (!isset($rawData->{$key})) {
                         $binaries[$key] = $value;
                         if ($update) {
                             unset($oldProperties[$key]);
                         }
                         if (isset($this->properties[$key])) {
                             // refresh existing binary, this will only happen in update
                             // only update length
                             if (!($keepChanges && $this->properties[$key]->isModified())) {
                                 $this->properties[$key]->_setLength($value);
                                 if ($this->properties[$key]->isDirty()) {
                                     $this->properties[$key]->setClean();
                                 }
                             }
                         } else {
                             // this will always fall into the creation mode
                             $this->_setProperty($key, $value, PropertyType::BINARY, true);
                         }
                     }
                 }
                 //else this is a type declaration
                 //skip this entry (if its binary, its already processed
                 continue;
             }
             if ($update && array_key_exists($key, $this->properties)) {
                 unset($oldProperties[$key]);
                 $prop = $this->properties[$key];
                 if ($keepChanges && $prop->isModified()) {
                     continue;
                 }
             } elseif ($update && array_key_exists($key, $this->deletedProperties)) {
                 if ($keepChanges) {
                     // keep the delete
                     continue;
                 } else {
                     // restore the property
                     $this->properties[$key] = $this->deletedProperties[$key];
                     $this->properties[$key]->setClean();
                     // now let the loop update the value. no need to talk to ObjectManager as it
                     // does not store property deletions
                 }
             }
             switch ($key) {
                 case 'jcr:index':
                     $this->index = $value;
                     break;
                 case 'jcr:primaryType':
                     $this->primaryType = $value;
                     // type information is exposed as property too,
                     // although there exist more specific methods
                     $this->_setProperty('jcr:primaryType', $value, PropertyType::NAME, true);
                     break;
                 case 'jcr:mixinTypes':
                     // type information is exposed as property too,
                     // although there exist more specific methods
                     $this->_setProperty($key, $value, PropertyType::NAME, true);
                     break;
                     // OPTIMIZE: do not instantiate properties until needed
                 // OPTIMIZE: do not instantiate properties until needed
                 default:
                     if (isset($rawData->{':' . $key})) {
                         /*
                          * this is an inconsistency between jackrabbit and
                          * dbal transport: jackrabbit has type name, dbal
                          * delivers numeric type.
                          * we should eventually fix the format returned by
                          * transport and either have jackrabbit transport
                          * do the conversion or let dbal store a string
                          * value instead of numerical.
                          */
                         $type = is_numeric($rawData->{':' . $key}) ? $rawData->{':' . $key} : PropertyType::valueFromName($rawData->{':' . $key});
                     } else {
                         $type = $this->valueConverter->determineType($value);
                     }
                     $this->_setProperty($key, $value, $type, true);
                     break;
             }
         }
     }
     if ($update) {
         if ($keepChanges) {
             // we keep changes. merge new nodes to the right place
             $previous = null;
             $newFromBackend = array_diff($nodesInBackend, array_intersect($this->nodes, $nodesInBackend));
             foreach ($newFromBackend as $name) {
                 $pos = array_search($name, $nodesInBackend);
                 if (is_array($this->originalNodesOrder)) {
                     // update original order to send the correct reorderings
                     array_splice($this->originalNodesOrder, $pos, 0, $name);
                 }
                 if ($pos === 0) {
                     array_unshift($this->nodes, $name);
                 } else {
                     // do we find the predecessor of the new node in the list?
                     $insert = array_search($nodesInBackend[$pos - 1], $this->nodes);
                     if (false !== $insert) {
                         array_splice($this->nodes, $insert + 1, 0, $name);
                     } else {
                         // failed to find predecessor, add to the end
                         $this->nodes[] = $name;
                     }
                 }
             }
         } else {
             // discard changes, just overwrite node list
             $this->nodes = $nodesInBackend;
             $this->originalNodesOrder = null;
         }
         foreach ($oldProperties as $name => $property) {
             if (!($keepChanges && $property->isNew())) {
                 // may not call remove(), we don't want another delete with
                 // the backend to be attempted
                 $this->properties[$name]->setDeleted();
                 unset($this->properties[$name]);
             }
         }
         // notify nodes that where not received again that they disappeared
         foreach ($oldNodes as $name => $index) {
             if ($this->objectManager->purgeDisappearedNode($this->path . '/' . $name, $keepChanges)) {
                 // drop, it was not a new child
                 if ($keepChanges) {
                     // otherwise we overwrote $this->nodes with the backend
                     $id = array_search($name, $this->nodes);
                     if (false !== $id) {
                         unset($this->nodes[$id]);
                     }
                 }
             }
         }
     } else {
         // new node loaded from backend
         $this->nodes = $nodesInBackend;
     }
 }
コード例 #11
0
ファイル: NodeNormalizer.php プロジェクト: hason/phpcr-shell
 /**
  * {@inheritDoc}
  */
 public function denormalize($data, $class, $format = null, array $context = array())
 {
     if (!$data) {
         throw new \InvalidArgumentException('Editor returned nothing .. nodes must have at least one property (i.e. the jcr:primaryType property)');
     }
     if (!isset($context['node'])) {
         throw new \InvalidArgumentException(sprintf('You must provide the PHPCR node instance to update in the context using the "node" key.'));
     }
     $node = $context['node'];
     $errors = array();
     // Update / remove existing properties
     foreach ($node->getProperties() as $property) {
         if (false === $this->isPropertyEditable($property)) {
             continue;
         }
         try {
             if (!isset($data[$property->getName()])) {
                 $property->remove();
                 continue;
             }
             $datum = $this->normalizeDatum($data[$property->getName()]);
             $typeValue = isset($datum['type']) ? PropertyType::valueFromName($datum['type']) : null;
             if (isset($datum['value'])) {
                 // if the type or the value is differnet, update the property
                 if ($datum['value'] != $property->getValue() || $typeValue != $property->getType()) {
                     // setValue doesn't like being passed a null value as a type ...
                     if ($typeValue !== null) {
                         $property->setValue($datum['value'], $typeValue);
                     } else {
                         $property->setValue($datum['value']);
                     }
                 }
             }
         } catch (\Exception $e) {
             $errors[] = $e->getMessage();
         }
         unset($data[$property->getName()]);
     }
     // Add new properties
     foreach ($data as $pName => $datum) {
         $datum = $this->normalizeDatum($datum);
         $pValue = isset($datum['value']) ? $datum['value'] : null;
         $pType = isset($datum['type']) ? PropertyType::valueFromName($datum['type']) : null;
         if ($pValue !== null) {
             $node->setProperty($pName, $pValue, $pType);
         }
     }
     if (count($errors) > 0) {
         throw new InvalidArgumentException(sprintf('Errors encountered during denormalization: %s', implode($errors, "\n")));
     }
 }
コード例 #12
0
 protected function parseCastLiteral($token)
 {
     if (!$this->scanner->tokenIs($token, 'CAST')) {
         throw new \LogicException('parseCastLiteral when not a CAST');
     }
     $this->scanner->expectToken('(');
     $token = $this->scanner->fetchNextToken();
     $quoteString = false;
     if (substr($token, 0, 1) === '\'') {
         $quoteString = "'";
     } elseif (substr($token, 0, 1) === '"') {
         $quoteString = '"';
     }
     if ($quoteString) {
         while (substr($token, -1) !== $quoteString) {
             $nextToken = $this->scanner->fetchNextToken();
             if ('' === $nextToken) {
                 break;
             }
             $token .= $nextToken;
         }
         if (substr($token, -1) !== $quoteString) {
             throw new InvalidQueryException("Syntax error: unterminated quoted string '{$token}' in '{$this->sql2}'");
         }
         $token = substr($token, 1, -1);
         $token = str_replace('\\' . $quoteString, $quoteString, $token);
     }
     $this->scanner->expectToken('AS');
     $type = $this->scanner->fetchNextToken();
     try {
         $typeValue = PropertyType::valueFromName($type);
     } catch (\InvalidArgumentException $e) {
         throw new InvalidQueryException("Syntax error: attempting to cast to an invalid type '{$type}'");
     }
     $this->scanner->expectToken(')');
     try {
         $token = $this->valueConverter->convertType($token, $typeValue, PropertyType::STRING);
     } catch (\Exception $e) {
         throw new InvalidQueryException("Syntax error: attempting to cast string '{$token}' to type '{$type}'");
     }
     return $token;
 }
コード例 #13
0
 /**
  * "Decode" PHPCR property to MongoDB property
  *
  * @param $property
  * @return array|null
  *
  * @throws \Exception
  */
 private function decodeProperty(PropertyInterface $property)
 {
     $path = $property->getPath();
     $path = $this->validatePath($path);
     $name = explode('/', $path);
     $name = end($name);
     if ($name == 'jcr:uuid' || $name == 'jcr:primaryType') {
         return null;
     }
     if (!$property->isModified() && !$property->isNew()) {
         return null;
     }
     $propType = $property->getType();
     $propNode = $property->getNode();
     if (($propType == PropertyType::REFERENCE || $propType == PropertyType::WEAKREFERENCE) && ($propNode instanceof NodeInterface && !$propNode->isNodeType('mix:referenceable'))) {
         throw new ValueFormatException('Node ' . $property->getNode()->getPath() . ' is not referenceable.');
     }
     $isMultiple = $property->isMultiple();
     $typeId = $property->getType();
     $type = PropertyType::nameFromValue($typeId);
     $data = array('multi' => $isMultiple, 'name' => $property->getName(), 'type' => $type);
     $binaryData = null;
     switch ($typeId) {
         case PropertyType::NAME:
         case PropertyType::URI:
         case PropertyType::WEAKREFERENCE:
         case PropertyType::REFERENCE:
         case PropertyType::PATH:
             $values = $property->getString();
             break;
         case PropertyType::DECIMAL:
             $values = $property->getDecimal();
             break;
         case PropertyType::STRING:
             $values = $property->getString();
             break;
         case PropertyType::BOOLEAN:
             $values = $property->getBoolean();
             break;
         case PropertyType::LONG:
             $values = $property->getLong();
             break;
         case PropertyType::BINARY:
             if ($property->isMultiple()) {
                 foreach ((array) $property->getBinary() as $binary) {
                     $binary = stream_get_contents($binary);
                     $binaryData[] = $binary;
                     $values[] = strlen($binary);
                 }
             } else {
                 $binary = stream_get_contents($property->getBinary());
                 $binaryData[] = $binary;
                 $values = strlen($binary);
             }
             break;
         case PropertyType::DATE:
             if ($property->isMultiple()) {
                 $dates = $property->getDate() ?: new \DateTime('now');
                 foreach ((array) $dates as $date) {
                     $value = array('date' => new \MongoDate($date->getTimestamp()), 'timezone' => $date->getTimezone()->getName());
                     $values[] = $value;
                 }
             } else {
                 $date = $property->getDate() ?: new \DateTime('now');
                 $values = array('date' => new \MongoDate($date->getTimestamp()), 'timezone' => $date->getTimezone()->getName());
             }
             break;
         case PropertyType::DOUBLE:
             $values = $property->getDouble();
             break;
     }
     if ($isMultiple) {
         $data['value'] = array();
         foreach ((array) $values as $value) {
             $this->assertValidPropertyValue($data['type'], $value, $path);
             $data['value'][] = $value;
         }
     } else {
         $this->assertValidPropertyValue($data['type'], $values, $path);
         $data['value'] = $values;
     }
     if ($binaryData) {
         try {
             foreach ($binaryData as $idx => $binary) {
                 $grid = $this->db->getGridFS();
                 $grid->getMongoCollection()->storeBytes($binary, array('path' => $path, 'w_id' => $this->workspaceId, 'idx' => $idx));
             }
         } catch (\Exception $e) {
             throw $e;
         }
     }
     return $data;
 }
コード例 #14
0
ファイル: Client.php プロジェクト: rambo/jackalope
 /**
  * Stores a property to the given absolute path
  *
  * @param string $path Absolute path to identify a specific property.
  * @param \PHPCR\PropertyInterface
  * @return bool true on success
  *
  * @throws \PHPCR\RepositoryException if not logged in
  */
 public function storeProperty($path, \PHPCR\PropertyInterface $property)
 {
     $this->ensureAbsolutePath($path);
     $type = \PHPCR\PropertyType::nameFromValue($property->getType());
     $request = $this->getRequest(Request::PUT, $path);
     $nativeValue = $property->getNativeValue();
     if ($property->getName() === 'jcr:mixinTypes') {
         $uri = $this->normalizeUri(dirname($path) === '\\' ? '/' : dirname($path));
         $request->setUri($uri);
         $request->setMethod(Request::PROPPATCH);
         $body = '<?xml version="1.0" encoding="UTF-8"?>' . '<D:propertyupdate xmlns:D="DAV:">' . '<D:set>' . '<D:prop>' . '<dcr:mixinnodetypes xmlns:dcr="http://www.day.com/jcr/webdav/1.0">';
         foreach ($nativeValue as $value) {
             $body .= '<dcr:nodetype><dcr:nodetypename>' . $value . '</dcr:nodetypename></dcr:nodetype>';
         }
         $body .= '</dcr:mixinnodetypes>' . '</D:prop>' . '</D:set>' . '</D:propertyupdate>';
     } elseif (is_array($nativeValue)) {
         $body = '<?xml version="1.0" encoding="UTF-8"?>' . '<jcr:values xmlns:jcr="http://www.day.com/jcr/webdav/1.0">';
         foreach ($nativeValue as $value) {
             $body .= '<jcr:value jcr:type="' . $type . '">' . $this->propertyToXmlString($value, $type) . '</jcr:value>';
         }
         $body .= '</jcr:values>';
     } else {
         $body = $this->propertyToRawString($nativeValue, $type);
         $request->setContentType('jcr-value/' . strtolower($type));
     }
     $request->setBody($body);
     $request->execute();
     return true;
 }
コード例 #15
0
ファイル: UnitOfWork.php プロジェクト: nikophil/cmf-tests
 /**
  * Executes all document updates
  *
  * @param array   $documents      array of all to be updated documents
  * @param boolean $dispatchEvents if to dispatch events
  */
 private function executeUpdates($documents, $dispatchEvents = true)
 {
     foreach ($documents as $oid => $document) {
         if (!$this->contains($oid)) {
             continue;
         }
         $class = $this->dm->getClassMetadata(get_class($document));
         $node = $this->session->getNode($this->getDocumentId($document));
         if ($this->writeMetadata) {
             $this->documentClassMapper->writeMetadata($this->dm, $node, $class->name);
         }
         if ($dispatchEvents) {
             if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::preUpdate)) {
                 $this->eventListenersInvoker->invoke($class, Event::preUpdate, $document, new PreUpdateEventArgs($document, $this->dm, $this->documentChangesets[$oid]), $invoke);
                 $this->changesetComputed = array_diff($this->changesetComputed, array($oid));
                 $this->computeChangeSet($class, $document);
             }
         }
         $fields = isset($this->documentChangesets[$oid]['fields']) ? $this->documentChangesets[$oid]['fields'] : array();
         foreach ($fields as $fieldName => $data) {
             $fieldValue = $data[1];
             // PHPCR does not validate nullable unless we would start to
             // generate custom node types, which we at the moment don't.
             // the ORM can delegate this validation to the relational database
             // that is using a strict schema.
             // do this after the preUpdate events to give listener a last
             // chance to provide values
             if (null === $fieldValue && in_array($fieldName, $class->fieldMappings) && !$class->isNullable($fieldName) && !$this->isAutocreatedProperty($class, $fieldName)) {
                 throw new PHPCRException(sprintf('Field "%s" of class "%s" is not nullable', $fieldName, $class->name));
             }
             // Ignore translatable fields (they will be persisted by the translation strategy)
             if (in_array($fieldName, $class->translatableFields)) {
                 continue;
             }
             $mapping = $class->mappings[$fieldName];
             if (in_array($fieldName, $class->fieldMappings)) {
                 $type = PropertyType::valueFromName($mapping['type']);
                 if ($mapping['multivalue']) {
                     $value = empty($fieldValue) ? null : ($fieldValue instanceof Collection ? $fieldValue->toArray() : $fieldValue);
                     if ($value && isset($mapping['assoc'])) {
                         $value = $this->processAssoc($node, $mapping, $value);
                     }
                 } else {
                     $value = $fieldValue;
                 }
                 $node->setProperty($mapping['property'], $value, $type);
             } elseif ($mapping['type'] === $class::MANY_TO_ONE || $mapping['type'] === $class::MANY_TO_MANY) {
                 if (!$this->writeMetadata) {
                     continue;
                 }
                 if ($node->hasProperty($mapping['property']) && is_null($fieldValue)) {
                     $node->getProperty($mapping['property'])->remove();
                     if (isset($mapping['assoc'])) {
                         $this->removeAssoc($node, $mapping);
                     }
                     continue;
                 }
                 switch ($mapping['strategy']) {
                     case 'hard':
                         $strategy = PropertyType::REFERENCE;
                         break;
                     case 'path':
                         $strategy = PropertyType::PATH;
                         break;
                     default:
                         $strategy = PropertyType::WEAKREFERENCE;
                         break;
                 }
                 if ($mapping['type'] === $class::MANY_TO_MANY) {
                     if (isset($fieldValue)) {
                         $refNodesIds = array();
                         foreach ($fieldValue as $fv) {
                             if ($fv === null) {
                                 continue;
                             }
                             $associatedNode = $this->session->getNode($this->getDocumentId($fv));
                             if ($strategy === PropertyType::PATH) {
                                 $refNodesIds[] = $associatedNode->getPath();
                             } else {
                                 $refClass = $this->dm->getClassMetadata(get_class($fv));
                                 $this->setMixins($refClass, $associatedNode, $fv);
                                 if (!$associatedNode->isNodeType('mix:referenceable')) {
                                     throw new PHPCRException(sprintf('Referenced document %s is not referenceable. Use referenceable=true in Document annotation: ' . self::objToStr($document, $this->dm), ClassUtils::getClass($fv)));
                                 }
                                 $refNodesIds[] = $associatedNode->getIdentifier();
                             }
                         }
                         $refNodesIds = empty($refNodesIds) ? null : $refNodesIds;
                         $node->setProperty($mapping['property'], $refNodesIds, $strategy);
                     }
                 } elseif ($mapping['type'] === $class::MANY_TO_ONE) {
                     if (isset($fieldValue)) {
                         $associatedNode = $this->session->getNode($this->getDocumentId($fieldValue));
                         if ($strategy === PropertyType::PATH) {
                             $node->setProperty($fieldName, $associatedNode->getPath(), $strategy);
                         } else {
                             $refClass = $this->dm->getClassMetadata(get_class($fieldValue));
                             $this->setMixins($refClass, $associatedNode, $document);
                             if (!$associatedNode->isNodeType('mix:referenceable')) {
                                 throw new PHPCRException(sprintf('Referenced document %s is not referenceable. Use referenceable=true in Document annotation: ' . self::objToStr($document, $this->dm), ClassUtils::getClass($fieldValue)));
                             }
                             $node->setProperty($mapping['property'], $associatedNode->getIdentifier(), $strategy);
                         }
                     }
                 }
             } elseif ('referrers' === $mapping['type']) {
                 if (isset($fieldValue)) {
                     /*
                      * each document in referrers field is supposed to
                      * reference this document, so we have to update its
                      * referencing property to contain the uuid of this
                      * document
                      */
                     foreach ($fieldValue as $fv) {
                         if ($fv === null) {
                             continue;
                         }
                         if (!$fv instanceof $mapping['referringDocument']) {
                             throw new PHPCRException(sprintf("%s is not an instance of %s for document %s field %s", self::objToStr($fv, $this->dm), $mapping['referencedBy'], self::objToStr($document, $this->dm), $mapping['fieldName']));
                         }
                         $referencingNode = $this->session->getNode($this->getDocumentId($fv));
                         $referencingMeta = $this->dm->getClassMetadata($mapping['referringDocument']);
                         $referencingField = $referencingMeta->getAssociation($mapping['referencedBy']);
                         $uuid = $node->getIdentifier();
                         $strategy = $referencingField['strategy'] == 'weak' ? PropertyType::WEAKREFERENCE : PropertyType::REFERENCE;
                         switch ($referencingField['type']) {
                             case ClassMetadata::MANY_TO_ONE:
                                 $ref = $referencingMeta->getFieldValue($fv, $referencingField['fieldName']);
                                 if ($ref !== null && $ref !== $document) {
                                     throw new PHPCRException(sprintf('Conflicting settings for referrer and reference: Document %s field %s points to %s but document %s has set first document as referrer on field %s', self::objToStr($fv, $this->dm), $referencingField['fieldName'], self::objToStr($ref, $this->dm), self::objToStr($document, $this->dm), $mapping['fieldName']));
                                 }
                                 // update the referencing document field to point to this document
                                 $referencingMeta->setFieldValue($fv, $referencingField['fieldName'], $document);
                                 // and make sure the reference is not deleted in this change because the field could be null
                                 unset($this->documentChangesets[spl_object_hash($fv)]['fields'][$referencingField['fieldName']]);
                                 // store the change in PHPCR
                                 $referencingNode->setProperty($referencingField['property'], $uuid, $strategy);
                                 break;
                             case ClassMetadata::MANY_TO_MANY:
                                 /** @var $collection ReferenceManyCollection */
                                 $collection = $referencingMeta->getFieldValue($fv, $referencingField['fieldName']);
                                 if ($collection instanceof PersistentCollection && $collection->isDirty()) {
                                     throw new PHPCRException(sprintf('You may not modify the reference and referrer collections of interlinked documents as this is ambiguous. Reference %s on document %s and referrers %s on document %s are both modified', self::objToStr($fv, $this->dm), $referencingField['fieldName'], self::objToStr($document, $this->dm), $mapping['fieldName']));
                                 }
                                 if ($collection) {
                                     // make sure the reference is not deleted in this change because the field could be null
                                     unset($this->documentChangesets[spl_object_hash($fv)]['fields'][$referencingField['fieldName']]);
                                 } else {
                                     $collection = new ReferenceManyCollection($this->dm, $fv, $referencingField['property'], array($node), $class->name);
                                     $referencingMeta->setFieldValue($fv, $referencingField['fieldName'], $collection);
                                 }
                                 if ($referencingNode->hasProperty($referencingField['property'])) {
                                     if (!in_array($uuid, $referencingNode->getProperty($referencingField['property'])->getString())) {
                                         if (!$collection instanceof PersistentCollection || !$collection->isDirty()) {
                                             // update the reference collection: add us to it
                                             $collection->add($document);
                                         }
                                         // store the change in PHPCR
                                         $referencingNode->getProperty($referencingField['property'])->addValue($uuid);
                                         // property should be correct type already
                                     }
                                 } else {
                                     // store the change in PHPCR
                                     $referencingNode->setProperty($referencingField['property'], array($uuid), $strategy);
                                 }
                                 // avoid confusion later, this change to the reference collection is already saved
                                 $collection->setDirty(false);
                                 break;
                             default:
                                 // in class metadata we only did a santiy check but not look at the actual mapping
                                 throw new MappingException(sprintf('Field "%s" of document "%s" is not a reference field. Error in referrer annotation: ' . self::objToStr($document, $this->dm), $mapping['referencedBy'], ClassUtils::getClass($fv)));
                         }
                     }
                 }
             } elseif ('child' === $mapping['type']) {
                 if ($fieldValue === null && $node->hasNode($mapping['nodeName'])) {
                     $child = $node->getNode($mapping['nodeName']);
                     $childDocument = $this->getOrCreateDocument(null, $child);
                     $this->purgeChildren($childDocument);
                     $child->remove();
                 }
             }
         }
         if (!empty($this->documentChangesets[$oid]['reorderings'])) {
             foreach ($this->documentChangesets[$oid]['reorderings'] as $reorderings) {
                 foreach ($reorderings as $srcChildRelPath => $destChildRelPath) {
                     $node->orderBefore($srcChildRelPath, $destChildRelPath);
                 }
             }
         }
         $this->doSaveTranslation($document, $node, $class);
         if ($dispatchEvents) {
             if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::postUpdate)) {
                 $this->eventListenersInvoker->invoke($class, Event::postUpdate, $document, new LifecycleEventArgs($document, $this->dm), $invoke);
             }
         }
     }
 }
コード例 #16
0
 /**
  * Quote a string for inclusion in an SQL2 query
  *
  * @see \PHPCR\PropertyType
  * @param  string $val
  * @param  int $type
  * @return string
  */
 public function quote($val, $type = PropertyType::STRING)
 {
     if (null !== $type) {
         $val = PropertyType::convertType($val, $type);
     }
     return "'" . str_replace("'", "''", $val) . "'";
 }
コード例 #17
0
ファイル: ContextBase.php プロジェクト: hason/phpcr-shell
 /**
  * @Given /^the property "([^"]*)" should have type "([^"]*)" and value "([^"]*)"$/
  */
 public function thePropertyShouldHaveTypeAndValue($arg1, $arg2, $arg3)
 {
     $session = $this->getSession();
     $property = $session->getItem($arg1);
     if (!$property instanceof PropertyInterface) {
         throw new \InvalidArgumentException(sprintf('Item at "%s" is not a property', $arg1));
     }
     \PHPUnit_Framework_Assert::assertEquals($arg2, PropertyType::nameFromValue($property->getType()));
     \PHPUnit_Framework_Assert::assertEquals($arg3, $property->getValue());
 }
コード例 #18
0
ファイル: Node.php プロジェクト: ruflin/jackalope
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function getPropertyValue($name, $type = null)
 {
     $this->checkState();
     $val = $this->getProperty($name)->getValue();
     if (!is_null($type)) {
         $val = PropertyType::convertType($val, $type);
     }
     return $val;
 }
コード例 #19
0
 /**
  * @expectedException \PHPCR\ValueFormatException
  */
 public function testDetermineTypeNull()
 {
     PropertyType::determineType(null);
 }
コード例 #20
0
ファイル: CndParser.php プロジェクト: frogriotcom/phpcr-utils
 /**
  * The property type is delimited by parentheses ('*' is a synonym for UNDEFINED).
  * If this element is absent, STRING is assumed. A '?' indicates that this
  * attribute is a variant.
  *
  *      PropertyType ::= '(' ('STRING' | 'BINARY' | 'LONG' | 'DOUBLE' |
  *          'BOOLEAN' | 'DATE' | 'NAME' | 'PATH' |
  *          'REFERENCE' | 'WEAKREFERENCE' |
  *          'DECIMAL' | 'URI' | 'UNDEFINED' | '*' |
  *          '?') ')'
  */
 protected function parsePropertyType(PropertyDefinitionTemplateInterface $property)
 {
     $types = array("STRING", "BINARY", "LONG", "DOUBLE", "BOOLEAN", "DATE", "NAME", "PATH", "REFERENCE", "WEAKREFERENCE", "DECIMAL", "URI", "UNDEFINED", "*", "?");
     if (!$this->checkTokenIn(Token::TK_IDENTIFIER, $types, true)) {
         throw new ParserException($this->tokenQueue, sprintf("Invalid property type: %s", $this->tokenQueue->get()->getData()));
     }
     $data = $this->tokenQueue->get()->getData();
     $this->expectToken(Token::TK_SYMBOL, ')');
     $property->setRequiredType(PropertyType::valueFromName($data));
 }
コード例 #21
0
 protected function getMimePart($name, $value, $mime_boundary)
 {
     $data = '';
     $eol = "\r\n";
     if (is_array($value)) {
         if (is_array($value[0])) {
             foreach ($value[0] as $v) {
                 $data .= $this->getMimePart($name, array($v, $value[1]), $mime_boundary);
             }
             return $data;
         }
         $data .= '--' . $mime_boundary . $eol;
         if (is_resource($value[0])) {
             $data .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '"' . $eol;
             $data .= 'Content-Type: jcr-value/' . strtolower(PropertyType::nameFromValue($value[1])) . '; charset=UTF-8' . $eol;
             $data .= 'Content-Transfer-Encoding: binary' . $eol . $eol;
             $data .= stream_get_contents($value[0]) . $eol;
             fclose($value[0]);
         } else {
             $data .= 'Content-Disposition: form-data; name="' . $name . '"' . $eol;
             $data .= 'Content-Type: jcr-value/' . strtolower(PropertyType::nameFromValue($value[1])) . '; charset=UTF-8' . $eol;
             $data .= 'Content-Transfer-Encoding: 8bit' . $eol . $eol;
             switch ($value[1]) {
                 case PropertyType::DATE:
                     $data .= $this->valueConverter->convertType($value[0], PropertyType::STRING);
                     break;
                 default:
                     $data .= $value[0];
             }
             $data .= $eol;
         }
     } else {
         if (is_array($value)) {
             foreach ($value as $v) {
                 $data .= $this->getMimePart($name, $v, $mime_boundary);
             }
             return $data;
         }
         $data .= '--' . $mime_boundary . $eol;
         $data .= 'Content-Disposition: form-data; name="' . $name . '"' . $eol;
         $data .= 'Content-Type: text/plain; charset=UTF-8' . $eol;
         $data .= 'Content-Transfer-Encoding: 8bit' . $eol . $eol;
         //$data .= '--' . $mime_boundary . $eol;
         $data .= $value . $eol;
     }
     return $data;
 }
コード例 #22
0
ファイル: CndWriter.php プロジェクト: frogriotcom/phpcr-utils
 private function writeProperties($properties)
 {
     if (null === $properties) {
         // getDeclaredPropertyDefinitions is allowed to return null on
         // newly created node type definitions
         return '';
     }
     $s = '';
     /** @var $property PropertyDefinitionInterface */
     foreach ($properties as $property) {
         $this->checkNamespace($property->getName());
         $s .= '- ' . $property->getName();
         if ($property->getRequiredType()) {
             $s .= ' (' . PropertyType::nameFromValue($property->getRequiredType()) . ')';
         }
         $s .= "\n";
         if ($property->getDefaultValues()) {
             $s .= "= '" . implode("', '", $property->getDefaultValues()) . "'\n";
         }
         $attributes = '';
         if ($property->isMandatory()) {
             $attributes .= 'mandatory ';
         }
         if ($property->isAutoCreated()) {
             $attributes .= 'autocreated ';
         }
         if ($property->isProtected()) {
             $attributes .= 'protected ';
         }
         if ($property->isMultiple()) {
             $attributes .= 'multiple ';
         }
         if ($property->getAvailableQueryOperators()) {
             $attributes .= implode("', '", $property->getAvailableQueryOperators());
         }
         if (!$property->isFullTextSearchable()) {
             $attributes .= 'nofulltext ';
         }
         if (!$property->isQueryOrderable()) {
             $attributes .= 'noqueryorder ';
         }
         if (OnParentVersionAction::COPY !== $property->getOnParentVersion()) {
             $attributes .= OnParentVersionAction::nameFromValue($property->getOnParentVersion()) . ' ';
         }
         if ($attributes) {
             $s .= trim($attributes) . "\n";
         }
         if ($property->getValueConstraints()) {
             $s .= "< '" . implode("', '", $property->getValueConstraints()) . "'\n";
         }
     }
     return $s;
 }
コード例 #23
0
ファイル: UnitOfWork.php プロジェクト: nicam/phpcr-odm
 /**
  * Executes all document updates
  *
  * @param array $documents array of all to be updated documents
  * @param boolean $dispatchEvents if to dispatch events
  */
 private function executeUpdates($documents, $dispatchEvents = true)
 {
     foreach ($documents as $oid => $document) {
         if (!$this->contains($oid)) {
             continue;
         }
         $class = $this->dm->getClassMetadata(get_class($document));
         $node = $this->session->getNode($this->getDocumentId($document));
         if ($this->writeMetadata) {
             $this->documentClassMapper->writeMetadata($this->dm, $node, $class->name);
         }
         if ($dispatchEvents) {
             if (isset($class->lifecycleCallbacks[Event::preUpdate])) {
                 $class->invokeLifecycleCallbacks(Event::preUpdate, $document);
                 $this->computeChangeSet($class, $document);
             }
             if ($this->evm->hasListeners(Event::preUpdate)) {
                 $this->evm->dispatchEvent(Event::preUpdate, new LifecycleEventArgs($document, $this->dm));
                 $this->computeChangeSet($class, $document);
             }
         }
         foreach ($this->documentChangesets[$oid] as $fieldName => $fieldValue) {
             // Ignore translatable fields (they will be persisted by the translation strategy)
             if (in_array($fieldName, $class->translatableFields)) {
                 continue;
             }
             if (isset($class->fieldMappings[$fieldName])) {
                 $type = PropertyType::valueFromName($class->fieldMappings[$fieldName]['type']);
                 if ($class->fieldMappings[$fieldName]['multivalue']) {
                     $value = $fieldValue === null ? null : $fieldValue->toArray();
                     $node->setProperty($class->fieldMappings[$fieldName]['name'], $value, $type);
                 } else {
                     $node->setProperty($class->fieldMappings[$fieldName]['name'], $fieldValue, $type);
                 }
             } elseif (isset($class->associationsMappings[$fieldName]) && $this->writeMetadata) {
                 if ($node->hasProperty($class->associationsMappings[$fieldName]['fieldName']) && is_null($fieldValue)) {
                     $node->getProperty($class->associationsMappings[$fieldName]['fieldName'])->remove();
                     continue;
                 }
                 $type = $class->associationsMappings[$fieldName]['weak'] ? PropertyType::WEAKREFERENCE : PropertyType::REFERENCE;
                 if ($class->associationsMappings[$fieldName]['type'] === $class::MANY_TO_MANY) {
                     if (isset($fieldValue)) {
                         $refNodesIds = array();
                         foreach ($fieldValue as $fv) {
                             if ($fv === null) {
                                 continue;
                             }
                             $associatedNode = $this->session->getNode($this->getDocumentId($fv));
                             $refClass = $this->dm->getClassMetadata(get_class($fv));
                             $this->setMixins($refClass, $associatedNode);
                             if (!$associatedNode->isNodeType('mix:referenceable')) {
                                 throw new PHPCRException(sprintf('Referenced document %s is not referenceable. Use referenceable=true in Document annotation: ' . self::objToStr($document, $this->dm), get_class($fv)));
                             }
                             $refNodesIds[] = $associatedNode->getIdentifier();
                         }
                         if (!empty($refNodesIds)) {
                             $node->setProperty($class->associationsMappings[$fieldName]['fieldName'], $refNodesIds, $type);
                         }
                     }
                 } elseif ($class->associationsMappings[$fieldName]['type'] === $class::MANY_TO_ONE) {
                     if (isset($fieldValue)) {
                         $associatedNode = $this->session->getNode($this->getDocumentId($fieldValue));
                         $refClass = $this->dm->getClassMetadata(get_class($fieldValue));
                         $this->setMixins($refClass, $associatedNode);
                         if (!$associatedNode->isNodeType('mix:referenceable')) {
                             throw new PHPCRException(sprintf('Referenced document %s is not referenceable. Use referenceable=true in Document annotation: ' . self::objToStr($document, $this->dm), get_class($fieldValue)));
                         }
                         $node->setProperty($class->associationsMappings[$fieldName]['fieldName'], $associatedNode->getIdentifier(), $type);
                     }
                 }
             } elseif (isset($class->childMappings[$fieldName])) {
                 if ($fieldValue === null) {
                     if ($node->hasNode($class->childMappings[$fieldName]['name'])) {
                         $child = $node->getNode($class->childMappings[$fieldName]['name']);
                         $childDocument = $this->createDocument(null, $child);
                         $this->purgeChildren($childDocument);
                         $child->remove();
                     }
                 } elseif ($this->originalData[$oid][$fieldName] && $this->originalData[$oid][$fieldName] !== $fieldValue) {
                     throw new PHPCRException('Cannot move/copy children by assignment as it would be ambiguous. Please use the DocumentManager::move() or PHPCR\\Session::copy() operations for this.');
                 }
             }
         }
         $this->doSaveTranslation($document, $node, $class);
         if ($dispatchEvents) {
             if (isset($class->lifecycleCallbacks[Event::postUpdate])) {
                 $class->invokeLifecycleCallbacks(Event::postUpdate, $document);
             }
             if ($this->evm->hasListeners(Event::postUpdate)) {
                 $this->evm->dispatchEvent(Event::postUpdate, new LifecycleEventArgs($document, $this->dm));
             }
         }
     }
 }
コード例 #24
0
ファイル: DocumentManager.php プロジェクト: nicam/phpcr-odm
 /**
  * Quote a string for inclusion in an SQL2 query
  *
  * @see \PHPCR\PropertyType
  * @param  string $val
  * @param  int $type
  * @return string
  */
 public function quote($val, $type = null)
 {
     if (null !== $type) {
         $val = PropertyType::convertType($val, $type);
     }
     return "'" . str_replace("'", "''", $this->escapeIllegalCharacters($val)) . "'";
 }
コード例 #25
0
ファイル: Property.php プロジェクト: ruflin/jackalope
 /**
  * Internally used to set the value of the property without any notification
  * of changes nor state change.
  *
  * @param mixed $value
  * @param string $type
  *
  * @return void
  *
  * @see Property::setValue()
  *
  * @private
  */
 public function _setValue($value, $type = PropertyType::UNDEFINED)
 {
     if (is_null($value)) {
         $this->remove();
         return;
     }
     if (!is_integer($type)) {
         // @codeCoverageIgnoreStart
         throw new InvalidArgumentException("The type has to be one of the numeric constants defined in PHPCR\\PropertyType. {$type}");
         // @codeCoverageIgnoreEnd
     }
     if ($this->isNew()) {
         $this->isMultiple = is_array($value);
     }
     if (is_array($value) && !$this->isMultiple) {
         throw new ValueFormatException('Can not set a single value property (' . $this->name . ') with an array of values');
     }
     //TODO: check if changing type allowed.
     /*
      * if ($type !== null && ! canHaveType($type)) {
      *   throw new ConstraintViolationException("Can not set this property to type ".PropertyType::nameFromValue($type));
      * }
      */
     if (PropertyType::UNDEFINED === $type) {
         $type = PropertyType::determineType(is_array($value) ? reset($value) : $value);
     }
     $targettype = $this->type;
     if ($this->type !== $type) {
         /* TODO: find out with node type definition if the new type is allowed
              if (canHaveType($type)) {
            */
         $targettype = $type;
         /*
           } else {
               //convert to an allowed type. if the current type is defined $targettype = $this->type;
           }
         */
     }
     $value = PropertyType::convertType($value, $targettype, $type);
     if (PropertyType::BINARY === $targettype) {
         $stat = fstat($value);
         //TODO: read file into local context? fstat not available on all streams
         $this->length = $stat['size'];
     }
     $this->type = $targettype;
     $this->value = $value;
 }
コード例 #26
0
ファイル: ImportExport.php プロジェクト: viral810/ngSimpleCMS
 /**
  * Import document in system view
  *
  * @param NodeInterface              $parentNode
  * @param NamespaceRegistryInterface $ns
  * @param FilteredXMLReader          $xml
  * @param int                        $uuidBehavior
  * @param array                      $namespaceMap hashmap of prefix => uri for namespaces in the document
  */
 private static function importSystemView(NodeInterface $parentNode, NamespaceRegistryInterface $ns, FilteredXMLReader $xml, $uuidBehavior, $namespaceMap = array())
 {
     while ($xml->moveToNextAttribute()) {
         if ('xmlns' == $xml->prefix) {
             try {
                 $prefix = $ns->getPrefix($xml->value);
             } catch (NamespaceException $e) {
                 $prefix = $xml->localName;
                 $ns->registerNamespace($prefix, $xml->value);
             }
             // @codeCoverageIgnoreStart
             if ('jcr' == $prefix && 'jcr' != $xml->localName) {
                 throw new RepositoryException('Can not handle a document where the {http://www.jcp.org/jcr/1.0} namespace is not mapped to jcr');
             }
             if ('nt' == $prefix && 'nt' != $xml->localName) {
                 throw new RepositoryException('Can not handle a document where the {http://www.jcp.org/jcr/nt/1.0} namespace is not mapped to nt');
             }
             // @codeCoverageIgnoreEnd
             $namespaceMap[$xml->localName] = $prefix;
         } elseif (NamespaceRegistryInterface::NAMESPACE_SV == $xml->namespaceURI && 'name' == $xml->localName) {
             $nodename = $xml->value;
         }
     }
     if (!isset($nodename)) {
         throw new InvalidSerializedDataException('there was no sv:name attribute in an element');
     }
     // now get jcr:primaryType
     if (!$xml->read()) {
         throw new InvalidSerializedDataException('missing information to create node');
     }
     if ('property' != $xml->localName || NamespaceRegistryInterface::NAMESPACE_SV != $xml->namespaceURI) {
         throw new InvalidSerializedDataException('first child of node must be sv:property for jcr:primaryType. Found {' . $xml->namespaceURI . '}' . $xml->localName . '="' . $xml->value . '"' . $xml->nodeType);
     }
     if (!$xml->moveToAttributeNs('name', NamespaceRegistryInterface::NAMESPACE_SV) || 'jcr:primaryType' != $xml->value) {
         throw new InvalidSerializedDataException('first child of node must be sv:property for jcr:primaryType. Found {' . $xml->namespaceURI . '}' . $xml->localName . '="' . $xml->value . '"');
     }
     $xml->read();
     // value child of property jcr:primaryType
     $xml->read();
     // text content
     $nodetype = $xml->value;
     $nodename = self::cleanNamespace($nodename, $namespaceMap);
     $properties = array();
     $xml->read();
     // </value>
     $xml->read();
     // </property>
     $xml->read();
     // next thing
     // read the properties of the node. they must come first.
     while (XMLReader::END_ELEMENT != $xml->nodeType && 'property' == $xml->localName) {
         $xml->moveToAttributeNs('name', NamespaceRegistryInterface::NAMESPACE_SV);
         $name = $xml->value;
         $xml->moveToAttributeNs('type', NamespaceRegistryInterface::NAMESPACE_SV);
         $type = PropertyType::valueFromName($xml->value);
         if ($xml->moveToAttributeNs('multiple', NamespaceRegistryInterface::NAMESPACE_SV)) {
             $multiple = strcasecmp($xml->value, 'true') === 0;
         } else {
             $multiple = false;
         }
         $values = array();
         // go to the value child. if empty property, brings us to closing
         // property tag. if self-closing, brings us to the next property or
         // node closing tag
         $xml->read();
         while ('value' == $xml->localName) {
             if ($xml->isEmptyElement) {
                 $values[] = '';
             } else {
                 $xml->read();
                 if (XMLReader::END_ELEMENT == $xml->nodeType) {
                     // this is an empty tag
                     $values[] = '';
                 } else {
                     $values[] = PropertyType::BINARY == $type ? base64_decode($xml->value) : $xml->value;
                     $xml->read();
                     // consume the content
                 }
             }
             $xml->read();
             // consume closing tag
         }
         if (!$multiple && count($values) == 1) {
             $values = reset($values);
             // unbox if it does not need to be multivalue
         }
         $name = self::cleanNamespace($name, $namespaceMap);
         $properties[$name] = array('values' => $values, 'type' => $type);
         /* only consume closing property, but not the next element if we
          * had an empty multiple property with no value children at all
          * and don't consume the closing node tag after a self-closing
          * empty property
          */
         if (XMLReader::END_ELEMENT == $xml->nodeType && 'property' == $xml->localName) {
             $xml->read();
         }
     }
     $node = self::addNode($parentNode, $nodename, $nodetype, $properties, $uuidBehavior);
     // if there are child nodes, they all come after the properties
     while (XMLReader::END_ELEMENT != $xml->nodeType && 'node' == $xml->localName) {
         self::importSystemView($node, $ns, $xml, $uuidBehavior, $namespaceMap);
     }
     if (XMLReader::END_ELEMENT != $xml->nodeType) {
         throw new InvalidSerializedDataException('Unexpected element "' . $xml->localName . '" type "' . $xml->nodeType . '" with content "' . $xml->value . '" after ' . $node->getPath());
     }
     $xml->read();
     // </node>
 }
コード例 #27
0
 /**
  * Seperate properties array into an xml and binary data.
  *
  * @param array   $properties
  *
  * @return array (
  *     'stringDom' => $stringDom,
  *     'numericalDom' => $numericalDom',
  *     'binaryData' => streams,
  *     'references' => array('type' => INT, 'values' => array(UUIDs)))
  */
 private function propsToXML($properties)
 {
     $namespaces = array('mix' => "http://www.jcp.org/jcr/mix/1.0", 'nt' => "http://www.jcp.org/jcr/nt/1.0", 'xs' => "http://www.w3.org/2001/XMLSchema", 'jcr' => "http://www.jcp.org/jcr/1.0", 'sv' => "http://www.jcp.org/jcr/sv/1.0", 'rep' => "internal");
     $doms = array('stringDom' => array(), 'numericalDom' => array());
     $binaryData = $references = array();
     foreach ($properties as $property) {
         $targetDoms = array('stringDom');
         switch ($property->getType()) {
             case PropertyType::WEAKREFERENCE:
             case PropertyType::REFERENCE:
                 $references[$property->getName()] = array('type' => $property->getType(), 'values' => $property->isMultiple() ? $property->getString() : array($property->getString()));
             case PropertyType::NAME:
             case PropertyType::URI:
             case PropertyType::PATH:
             case PropertyType::STRING:
                 $values = $property->getString();
                 break;
             case PropertyType::DECIMAL:
                 $values = $property->getDecimal();
                 $targetDoms[] = 'numericalDom';
                 break;
             case PropertyType::BOOLEAN:
                 $values = array_map('intval', (array) $property->getBoolean());
                 break;
             case PropertyType::LONG:
                 $values = $property->getLong();
                 $targetDoms[] = 'numericalDom';
                 break;
             case PropertyType::BINARY:
                 if ($property->isNew() || $property->isModified()) {
                     $values = array();
                     foreach ((array) $property->getValueForStorage() as $stream) {
                         if (null === $stream) {
                             $binary = '';
                         } else {
                             $binary = stream_get_contents($stream);
                             fclose($stream);
                         }
                         $binaryData[$property->getName()][] = $binary;
                         $length = strlen($binary);
                         $values[] = $length;
                     }
                 } else {
                     $values = $property->getLength();
                     if (!$property->isMultiple() && empty($values)) {
                         $values = array(0);
                     }
                 }
                 break;
             case PropertyType::DATE:
                 $values = $property->getDate();
                 if ($values instanceof \DateTime) {
                     $values = array($values);
                 }
                 foreach ((array) $values as $key => $date) {
                     if ($date instanceof \DateTime) {
                         // do not modify the instance which is associated with the node.
                         $date = clone $date;
                         // normalize to UTC for storage.
                         $date->setTimezone(new \DateTimeZone('UTC'));
                     }
                     $values[$key] = $date;
                 }
                 $values = $this->valueConverter->convertType($values, PropertyType::STRING);
                 break;
             case PropertyType::DOUBLE:
                 $values = $property->getDouble();
                 $targetDoms[] = 'numericalDom';
                 break;
             default:
                 throw new RepositoryException('unknown type ' . $property->getType());
         }
         foreach ($targetDoms as $targetDom) {
             $doms[$targetDom][] = array('name' => $property->getName(), 'type' => PropertyType::nameFromValue($property->getType()), 'multiple' => $property->isMultiple(), 'lengths' => (array) $property->getLength(), 'values' => $values);
         }
     }
     $ret = array('stringDom' => null, 'numericalDom' => null, 'binaryData' => $binaryData, 'references' => $references);
     foreach ($doms as $targetDom => $properties) {
         $dom = new \DOMDocument('1.0', 'UTF-8');
         $rootNode = $dom->createElement('sv:node');
         foreach ($namespaces as $namespace => $uri) {
             $rootNode->setAttribute('xmlns:' . $namespace, $uri);
         }
         $dom->appendChild($rootNode);
         foreach ($properties as $property) {
             /* @var $property Property */
             $propertyNode = $dom->createElement('sv:property');
             $propertyNode->setAttribute('sv:name', $property['name']);
             $propertyNode->setAttribute('sv:type', $property['type']);
             $propertyNode->setAttribute('sv:multi-valued', $property['multiple'] ? '1' : '0');
             $lengths = (array) $property['lengths'];
             foreach ((array) $property['values'] as $key => $value) {
                 $element = $propertyNode->appendChild($dom->createElement('sv:value'));
                 $element->appendChild($dom->createTextNode($value));
                 if (isset($lengths[$key])) {
                     $lengthAttribute = $dom->createAttribute('length');
                     $lengthAttribute->value = $lengths[$key];
                     $element->appendChild($lengthAttribute);
                 }
             }
             $rootNode->appendChild($propertyNode);
         }
         if (count($properties)) {
             $ret[$targetDom] = $dom;
         }
     }
     return $ret;
 }
コード例 #28
0
ファイル: Property.php プロジェクト: jackalope/jackalope
 /**
  * Internally used to set the value of the property without any notification
  * of changes nor state change.
  *
  * @param mixed      $value       The value to set.
  * @param int|string $type        PropertyType constant
  * @param boolean    $constructor Whether this is called from the constructor.
  *
  * @see Property::setValue()
  *
  * @throws AccessDeniedException
  * @throws ItemNotFoundException
  * @throws LockException
  * @throws ConstraintViolationException
  * @throws RepositoryException
  * @throws VersionException
  * @throws InvalidArgumentException
  * @throws ValueFormatException
  *
  * @private
  */
 public function _setValue($value, $type = PropertyType::UNDEFINED, $constructor = false)
 {
     if (null === $value) {
         $this->remove();
         return;
     }
     if (is_string($type)) {
         $type = PropertyType::valueFromName($type);
     } elseif (!is_numeric($type)) {
         // @codeCoverageIgnoreStart
         throw new RepositoryException("INTERNAL ERROR -- No valid type specified ({$type})");
         // @codeCoverageIgnoreEnd
     } else {
         //sanity check. this will throw InvalidArgumentException if $type is not a valid type
         PropertyType::nameFromValue($type);
     }
     if ($constructor || $this->isNew()) {
         $this->isMultiple = is_array($value);
     }
     if (is_array($value) && !$this->isMultiple) {
         throw new ValueFormatException('Can not set a single value property (' . $this->name . ') with an array of values');
     }
     if ($this->isMultiple && is_scalar($value)) {
         throw new ValueFormatException('Can not set a multivalue property (' . $this->name . ') with a scalar value');
     }
     if ($this->isMultiple) {
         foreach ($value as $key => $v) {
             if (null === $v) {
                 unset($value[$key]);
             }
         }
     }
     //TODO: check if changing type allowed.
     /*
      * if ($type !== null && ! canHaveType($type)) {
      *   throw new ConstraintViolationException("Can not set this property to type ".PropertyType::nameFromValue($type));
      * }
      */
     if (PropertyType::UNDEFINED === $type) {
         // avoid changing type of multivalue property with empty array
         if (!$this->isMultiple() || count($value) || PropertyType::UNDEFINED === $this->type) {
             $type = $this->valueConverter->determineType($value);
         } else {
             $type = $this->type;
         }
     }
     $targetType = $type;
     /*
      * TODO: find out with node type definition if the new type is allowed
     if ($this->type !== $type) {
         if (!canHaveType($type)) {
              //convert to an allowed type
         }
     }
     */
     if (PropertyType::BINARY !== $targetType || $constructor && $this->isNew() || !$this->isNew() && PropertyType::UNDEFINED !== $this->type && $this->type !== $targetType) {
         $value = $this->valueConverter->convertType($value, $targetType, $constructor ? PropertyType::UNDEFINED : $type);
     }
     if (PropertyType::BINARY === $targetType) {
         if ($constructor && !$this->isNew()) {
             // reading a binary property from backend, we do not get the stream immediately but just the size
             if (is_array($value)) {
                 $this->isMultiple = true;
             }
             $this->type = PropertyType::BINARY;
             $this->length = $value;
             $this->value = null;
             return;
         }
         if (is_array($value)) {
             $this->length = array();
             foreach ($value as $v) {
                 $stat = is_resource($v) ? fstat($v) : array('size' => -1);
                 $this->length[] = $stat['size'];
             }
         } elseif (is_resource($value)) {
             $stat = fstat($value);
             $this->length = $stat['size'];
         } else {
             $this->length = -1;
         }
     }
     $this->type = $targetType;
     $this->value = $value;
 }
コード例 #29
0
ファイル: NodeListCommand.php プロジェクト: hason/phpcr-shell
 private function renderProperties($currentNode, $table, $spacers, $filter = null)
 {
     $properties = (array) $currentNode->getProperties($filter ?: null);
     $properties = $this->sort($properties);
     try {
         $primaryItem = $currentNode->getPrimaryItem();
     } catch (ItemNotFoundException $e) {
         $primaryItem = null;
     }
     $nodeType = $currentNode->getPrimaryNodeType();
     $propertyDefinitions = $nodeType->getDeclaredPropertyDefinitions();
     $propertyNames = array();
     foreach ($propertyDefinitions as $name => $propertyDefinition) {
         $propertyNames[$propertyDefinition->getName()] = $propertyDefinition;
     }
     $i = 0;
     foreach ($properties as $name => $property) {
         try {
             $i++;
             if (isset($propertyNames[$name])) {
                 unset($propertyNames[$name]);
             }
             $valueCell = $this->formatter->formatValue($property);
         } catch (\Exception $e) {
             $valueCell = '<error>' . $e->getMessage() . '</error>';
         }
         $table->addRow(array('<property>' . implode('', $spacers) . $name . '</property>', sprintf('<property-type>%s (%s)</property-type>', $this->formatter->getPropertyTypeName($property->getType()), implode(',', (array) $property->getLength()) ?: '0'), $valueCell));
     }
     if ($this->showTemplate) {
         foreach ($propertyNames as $propertyName => $property) {
             $table->addRow(array('<templateproperty>' . implode('', $spacers) . '@' . $propertyName . '</templateproperty>', '<property-type>' . strtoupper(PropertyType::nameFromValue($property->getRequiredType())) . '</property-type>', ''));
         }
     }
 }
コード例 #30
0
 /**
  * Determine PropertyType from on variable type.
  *
  * This is most of the remainder of ValueFactory that is still needed.
  *
  * - if the given $value is a Node object, type will be REFERENCE, unless
  *    $weak is set to true which results in WEAKREFERENCE
  * - if the given $value is a DateTime object, the type will be DATE.
  *
  * Note that string is converted to date exactly if it matches the jcr
  * formatting spec for dates (sYYYY-MM-DDThh:mm:ss.sssTZD) according to
  * http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.6.4.3%20From%20DATE%20To
  *
  * @param mixed   $value The variable we need to know the type of
  * @param boolean $weak  When a Node is given as $value this can be given
  *                       as true to create a WEAKREFERENCE.
  *
  * @return int One of the type constants
  *
  * @throws ValueFormatException if the type can not be determined
  */
 public function determineType($value, $weak = false)
 {
     return PropertyType::determineType($value, $weak);
 }