/** * \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); }
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']]); }
/** * 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; } }
/** * 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); } }
/** * 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; }
/** * "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); }
/** * 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; }
/** * 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; } }