/**
  * \PHPCR\PropertyInterface::setValue.
  */
 public function testSetValue()
 {
     $this->property->setValue(1024);
     $this->assertEquals(1024, $this->property->getLong());
     $this->saveAndRenewSession();
     $prop = $this->session->getProperty($this->propPath);
     $this->assertEquals(1024, $prop->getLong());
 }
 public function formatValue(PropertyInterface $property, $showBinary = false, $truncate = true)
 {
     $values = $property->getValue();
     if (false === $property->isMultiple()) {
         $values = array($values);
     }
     $return = array();
     foreach ($values as $value) {
         switch (intval($property->getType())) {
             case PropertyType::UNDEFINED:
                 $return[] = '#UNDEFINED#';
             case PropertyType::BINARY:
                 if ($showBinary) {
                     $lines = array();
                     $pointer = $value;
                     while (($line = fgets($pointer)) !== false) {
                         $lines[] = $line;
                     }
                     $return[] = implode('', $lines);
                     break;
                 }
                 return '(binary data)';
             case PropertyType::BOOLEAN:
                 $return[] = $value ? 'true' : 'false';
                 break;
             case PropertyType::DATE:
                 $return[] = $value->format('c');
                 break;
             case PropertyType::REFERENCE:
             case PropertyType::WEAKREFERENCE:
                 $return[] = sprintf('%s (%s)', $this->textHelper->truncate($value->getPath(), 255), $value->getIdentifier());
                 break;
             case PropertyType::URI:
             case PropertyType::STRING:
                 $return[] = $truncate ? $this->textHelper->truncate($value) : $value;
                 break;
             case PropertyType::NAME:
             case PropertyType::LONG:
             case PropertyType::DOUBLE:
             case PropertyType::DECIMAL:
             case PropertyType::PATH:
                 $return[] = $value;
                 break;
             default:
                 throw new \RuntimeException('Unknown type ' . $property->getType());
         }
     }
     if ($property->isMultiple()) {
         return implode("\n", array_map(function ($value) {
             static $index = 0;
             return sprintf('<comment>[%d]</comment> %s', $index++, $value);
         }, $return));
     }
     return implode("\n", $return);
 }
Example #3
0
 public function it_can_normalize_a_node_to_an_array(NodeInterface $node, PropertyInterface $p1, PropertyInterface $p2, PropertyInterface $p3)
 {
     $node->getProperties()->willReturn([$p1, $p2, $p3]);
     $p1->getName()->willReturn('my:property.1');
     $p1->getType()->willReturn(PropertyType::STRING);
     $p1->getValue()->willReturn('P1 Val');
     $p2->getName()->willReturn('my:property.2');
     $p2->getType()->willReturn(PropertyType::DOUBLE);
     $p2->getValue()->willReturn('P2 Val');
     $p3->getName()->willReturn('my:property.3');
     $p3->getType()->willReturn(PropertyType::STRING);
     $p3->getValue()->willReturn('P3 Val');
     $this->normalize($node)->shouldReturn(['my:property.1' => ['type' => 'String', 'value' => 'P1 Val'], 'my:property.2' => ['type' => 'Double', 'value' => 'P2 Val'], 'my:property.3' => ['type' => 'String', 'value' => 'P3 Val']]);
 }
Example #4
0
    /**
     * Validation if all the data is correct before writing it into the database.
     *
     * @param PropertyInterface $property
     *
     * @throws ValueFormatException
     */
    private function assertValidProperty($property)
    {
        $type = $property->getType();
        switch ($type) {
            case PropertyType::NAME:
                $values = $property->getValue();
                if (!$property->isMultiple()) {
                    $values = array($values);
                }
                foreach ($values as $value) {
                    $pos = strpos($value, ':');
                    if (false !== $pos) {
                        $prefix = substr($value, 0, $pos);

                        $this->getNamespaces();
                        if (!isset($this->namespaces[$prefix])) {
                            throw new ValueFormatException("Invalid PHPCR NAME at '" . $property->getPath() . "': The namespace prefix " . $prefix . " does not exist.");
                        }
                    }
                }
                break;
            case PropertyType::PATH:
                $values = $property->getValue();
                if (!$property->isMultiple()) {
                    $values = array($values);
                }
                foreach ($values as $value) {
                    if (!preg_match('(((/|..)?[-a-zA-Z0-9:_]+)+)', $value)) {
                        throw new ValueFormatException("Invalid PATH '$value' at '" . $property->getPath() ."': Segments are separated by / and allowed chars are -a-zA-Z0-9:_");
                    }
                }
                break;
            case PropertyType::URI:
                $values = $property->getValue();
                if (!$property->isMultiple()) {
                    $values = array($values);
                }
                foreach ($values as $value) {
                    if (!preg_match(self::VALIDATE_URI_RFC3986, $value)) {
                        throw new ValueFormatException("Invalid URI '$value' at '" . $property->getPath() ."': Has to follow RFC 3986.");
                    }
                }
                break;
            case PropertyType::DECIMAL:
            case PropertyType::STRING:
                $values = (array) $property->getValue();
                foreach ($values as $value) {
                    if (!$this->isStringValid($value)) {
                        throw new ValueFormatException('Invalid character found in property "'.$property->getName().'". Are you passing a valid string?');
                    }
                }
                break;
        }
    }
Example #5
0
 /**
  * Remove a node or a property.
  *
  * If this is a node, sets all cached items below this node to deleted as
  * well.
  *
  * If property is set, the path denotes the node containing the property,
  * otherwise the node at path is removed.
  *
  * @param string $absPath The absolute path to the node to be removed,
  *      including the node name.
  * @param PropertyInterface $property optional, property instance to delete from the
  *      given node path. If set, absPath is the path to the node containing
  *      this property.
  *
  * @throws RepositoryException If node cannot be found at given path
  *
  * @see Item::remove()
  */
 public function removeItem($absPath, PropertyInterface $property = null)
 {
     if (!$this->transport instanceof WritingInterface) {
         throw new UnsupportedRepositoryOperationException('Transport does not support writing');
     }
     // the object is always cached as invocation flow goes through Item::remove() without exception
     if (!isset($this->objectsByPath['Node'][$absPath])) {
         throw new RepositoryException("Internal error: Item not found in local cache at {$absPath}");
     }
     if ($property) {
         $absPath = PathHelper::absolutizePath($property->getName(), $absPath);
         $this->performPropertyRemove($absPath, $property);
     } else {
         $node = $this->objectsByPath['Node'][$absPath];
         $this->performNodeRemove($absPath, $node);
         $this->cascadeDelete($absPath);
     }
 }
Example #6
0
 /**
  * Return false if property type is not editable
  *
  * (e.g. property type is binary)
  *
  * @return boolean
  */
 private function isPropertyEditable(PropertyInterface $property)
 {
     // do not serialize binary objects
     if (false === $this->allowBinary && PropertyType::BINARY == $property->getType()) {
         $this->notes[] = sprintf('Binary property "%s" has been omitted', $property->getName());
         return false;
     }
     return true;
 }
Example #7
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;
 }
 public function testGetTypeWeakReference()
 {
     $node = $this->node->getNode('index.txt/jcr:content');
     $node->setProperty('newWeakRef', '842e61c0-09ab-42a9-87c0-308ccc90e6f4', \PHPCR\PropertyType::WEAKREFERENCE);
     $this->assertEquals(\PHPCR\PropertyType::WEAKREFERENCE, $node->getProperty('newWeakRef')->getType(), 'Expecting WEAKREFERENCE type');
 }
 public function testGetLength()
 {
     $size = $this->binaryProperty->getLength();
     $this->assertInternalType('integer', $size);
     $this->assertEquals(strlen($this->decodedstring), $size);
 }
 /**
  * Remove the given property, or the value which references the node (when
  * multi-valued).
  *
  * @param NodeInterface     $node
  * @param PropertyInterface $property
  */
 private function dereferenceProperty(NodeInterface $node, PropertyInterface $property)
 {
     if (false === $property->isMultiple()) {
         $property->remove();
         return;
     }
     // dereference from multi-valued referring properties
     $values = $property->getValue();
     foreach ($values as $i => $referencedNode) {
         if ($referencedNode->getIdentifier() === $node->getIdentifier()) {
             unset($values[$i]);
         }
     }
     $property->getParent()->setProperty($property->getName(), $values);
 }
Example #11
0
 /**
  * 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;
 }
Example #12
0
 /**
  * Validation if all the data is correct before writing it into the database.
  *
  * @param PropertyInterface $property
  *
  * @throws RepositoryException
  * @throws ValueFormatException
  */
 private function assertValidProperty(PropertyInterface $property)
 {
     $type = $property->getType();
     switch ($type) {
         case PropertyType::NAME:
             $values = $property->getValue();
             if (!$property->isMultiple()) {
                 $values = array($values);
             }
             foreach ($values as $value) {
                 $pos = strpos($value, ':');
                 if (false !== $pos) {
                     $prefix = substr($value, 0, $pos);
                     if (!isset($this->namespaces[$prefix])) {
                         throw new ValueFormatException(sprintf('Invalid value for NAME property type at "%s", the namespace prefix "%s" does not exist.");', $property->getPath(), $prefix));
                     }
                 }
             }
             break;
         case PropertyType::PATH:
             $values = $property->getValue();
             if (!$property->isMultiple()) {
                 $values = array($values);
             }
             foreach ($values as $value) {
                 try {
                     // making the path absolute also validates the result to be a valid path
                     PathHelper::absolutizePath($value, $property->getPath());
                 } catch (RepositoryException $e) {
                     throw new ValueFormatException(sprintf('Value "%s" for PATH property at "%s" is invalid', $value, $property->getPath()), 0, $e);
                 }
             }
             break;
         case PropertyType::URI:
             $values = $property->getValue();
             if (!$property->isMultiple()) {
                 $values = array($values);
             }
             foreach ($values as $value) {
                 if (!preg_match(self::VALIDATE_URI_RFC3986, $value)) {
                     throw new ValueFormatException(sprintf('Invalid value "%s" for URI property at "%s". Value has to comply with RFC 3986.', $value, $property->getPath()));
                 }
             }
             break;
         case PropertyType::DECIMAL:
         case PropertyType::STRING:
             $values = (array) $property->getValue();
             foreach ($values as $value) {
                 if (0 !== preg_match(self::VALIDATE_STRING, $value)) {
                     throw new ValueFormatException(sprintf('Invalid character detected in value %s for STRING property at "%s".', json_encode($value), $property->getPath()));
                 }
             }
             break;
     }
 }