예제 #1
0
 public function current()
 {
     if (!$this->valid()) {
         return null;
     }
     return $this->factory->get('Query\\Row', array($this->objectManager, $this->rows[$this->position]));
 }
예제 #2
0
 /**
  * Internally create a node type object
  *
  * @param NodeTypeDefinitionInterface $ntd
  * @param bool                        $allowUpdate whether updating the definition is to be allowed or not
  *
  * @return NodeType the new node type
  *
  * @throws \PHPCR\NodeType\NodeTypeExistsException
  */
 protected function createNodeType(NodeTypeDefinitionInterface $ntd, $allowUpdate)
 {
     if ($this->hasNodeType($ntd->getName()) && !$allowUpdate) {
         throw new NodeTypeExistsException('NodeType already existing: ' . $ntd->getName());
     }
     return $this->factory->get('NodeType\\NodeType', array($this, $ntd));
 }
예제 #3
0
 /**
  * Reads the node type definition from an xml element
  *
  * @param DOMElement $node The dom element to read information from
  */
 protected function fromXml(DOMElement $node)
 {
     $this->name = $node->getAttribute('name');
     $this->isAbstract = Helper::getBoolAttribute($node, 'isAbstract');
     $this->isMixin = Helper::getBoolAttribute($node, 'isMixin');
     $this->isQueryable = Helper::getBoolAttribute($node, 'isQueryable');
     $this->hasOrderableChildNodes = Helper::getBoolAttribute($node, 'hasOrderableChildNodes');
     $this->primaryItemName = $node->getAttribute('primaryItemName');
     if (empty($this->primaryItemName)) {
         $this->primaryItemName = null;
     }
     $this->declaredSuperTypeNames = array();
     $xp = new DOMXPath($node->ownerDocument);
     $supertypes = $xp->query('supertypes/supertype', $node);
     foreach ($supertypes as $supertype) {
         $this->declaredSuperTypeNames[] = $supertype->nodeValue;
     }
     $this->declaredPropertyDefinitions = new ArrayObject();
     $properties = $xp->query('propertyDefinition', $node);
     foreach ($properties as $property) {
         $this->declaredPropertyDefinitions[] = $this->factory->get('NodeType\\PropertyDefinition', array($property, $this->nodeTypeManager));
     }
     $this->declaredNodeDefinitions = new ArrayObject();
     $declaredNodeDefinitions = $xp->query('childNodeDefinition', $node);
     foreach ($declaredNodeDefinitions as $nodeDefinition) {
         $this->declaredNodeDefinitions[] = $this->factory->get('NodeType\\NodeDefinition', array($nodeDefinition, $this->nodeTypeManager));
     }
 }
예제 #4
0
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function getVersionManager()
 {
     if (!$this->session->getTransport() instanceof VersioningInterface) {
         throw new UnsupportedRepositoryOperationException('Transport does not support versioning');
     }
     return $this->factory->get('Version\\VersionManager', array($this->session->getObjectManager()));
 }
예제 #5
0
 /**
  * Parse the events in an <entry> section
  *
  * @param DOMElement $entry
  * @param string     $currentUserId The current user ID as extracted from
  *      the <entry> part
  *
  * @return Event[]
  */
 protected function extractEvents(DOMElement $entry, $currentUserId)
 {
     $events = array();
     $domEvents = $entry->getElementsByTagName('event');
     foreach ($domEvents as $domEvent) {
         $event = $this->factory->get('Jackalope\\Observation\\Event', array($this->nodeTypeManager));
         $event->setType($this->extractEventType($domEvent));
         $date = $this->getDomElement($domEvent, 'eventdate', 'The event date was not found while building the event journal:\\n' . $this->getEventDom($domEvent));
         $event->setUserId($currentUserId);
         // The timestamps in Java contain milliseconds, it's not the case in PHP
         // so we strip millis from the response
         $event->setDate(substr($date->nodeValue, 0, -3));
         $id = $this->getDomElement($domEvent, 'eventidentifier');
         if ($id) {
             $event->setIdentifier($id->nodeValue);
         }
         $href = $this->getDomElement($domEvent, 'href');
         if ($href) {
             $path = str_replace($this->workspaceRootUri, '', $href->nodeValue);
             if (substr($path, -1) === '/') {
                 // Jackrabbit might return paths with trailing slashes. Eliminate them if present.
                 $path = substr($path, 0, -1);
             }
             $event->setPath($path);
         }
         $primaryNodeType = $this->getDomElement($domEvent, 'eventprimarynodetype');
         if ($primaryNodeType) {
             $event->setPrimaryNodeTypeName($primaryNodeType->nodeValue);
         }
         $mixinNodeTypes = $domEvent->getElementsByTagName('eventmixinnodetype');
         foreach ($mixinNodeTypes as $mixinNodeType) {
             $event->addMixinNodeTypeName($mixinNodeType->nodeValue);
         }
         $userData = $this->getDomElement($domEvent, 'eventuserdata');
         if ($userData) {
             $event->setUserData($userData->nodeValue);
         }
         $eventInfos = $this->getDomElement($domEvent, 'eventinfo');
         if ($eventInfos) {
             foreach ($eventInfos->childNodes as $info) {
                 if ($info->nodeType == XML_ELEMENT_NODE) {
                     $event->addInfo($info->tagName, $info->nodeValue);
                 }
             }
         }
         // abort if we got more events than expected (usually on paging)
         if ($event->getDate() > $this->creationMillis) {
             $this->nextMillis = false;
             return $events;
         }
         if ($this->filter->match($event)) {
             $events[] = $event;
         }
     }
     return $events;
 }
예제 #6
0
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function execute()
 {
     if (is_null($this->objectManager)) {
         // if the ObjectManager was not injected in the header. this is only supposed to happen in the DBAL client.
         throw new RepositoryException('Jackalope implementation error: This query was built for parsing only. (There is no ObjectManager to run the query against.)');
     }
     $transport = $this->objectManager->getTransport();
     $rawData = $transport->query($this);
     $queryResult = $this->factory->get('Query\\QueryResult', array($rawData, $this->objectManager));
     return $queryResult;
 }
예제 #7
0
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function getNodes($prefetch = false)
 {
     if ($prefetch !== true) {
         return $this->factory->get('Query\\NodeIterator', array($this->objectmanager, $this->rows));
     }
     $paths = array();
     foreach ($this->getRows() as $row) {
         $paths[] = $row->getPath();
     }
     return $this->objectmanager->getNodesByPath($paths);
 }
예제 #8
0
 /** Creates a session
  *
  * Builds the corresponding workspace instance
  *
  * @param FactoryInterface  $factory       the object factory
  * @param Repository        $repository
  * @param string            $workspaceName the workspace name that is used
  * @param SimpleCredentials $credentials   the credentials that where
  *      used to log in, in order to implement Session::getUserID()
  *      if they are null, getUserID returns null
  * @param TransportInterface $transport the transport implementation
  */
 public function __construct(FactoryInterface $factory, Repository $repository, $workspaceName, SimpleCredentials $credentials = null, TransportInterface $transport)
 {
     $this->factory = $factory;
     $this->repository = $repository;
     $this->objectManager = $this->factory->get('ObjectManager', array($transport, $this));
     $this->workspace = $this->factory->get('Workspace', array($this, $this->objectManager, $workspaceName));
     $this->credentials = $credentials;
     $this->namespaceRegistry = $this->workspace->getNamespaceRegistry();
     self::registerSession($this);
     $transport->setNodeTypeManager($this->workspace->getNodeTypeManager());
 }
예제 #9
0
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function login(CredentialsInterface $credentials = null, $workspaceName = null)
 {
     if (!($workspaceName = $this->transport->login($credentials, $workspaceName))) {
         throw new RepositoryException('transport failed to login without telling why');
     }
     /** @var $session Session */
     $session = $this->factory->get('Session', array($this, $workspaceName, $credentials, $this->transport));
     $session->setSessionOption(Session::OPTION_AUTO_LASTMODIFIED, $this->options[Session::OPTION_AUTO_LASTMODIFIED]);
     if ($this->options['transactions']) {
         $utx = $this->factory->get('Transaction\\UserTransaction', array($this->transport, $session, $session->getObjectManager()));
         $session->getWorkspace()->setTransactionManager($utx);
     }
     return $session;
 }
예제 #10
0
 /**
  * Reads the node type definition from an array
  *
  * @param array $data an array with key-value information
  */
 protected function fromArray(array $data)
 {
     $this->name = $data['name'];
     $this->isAbstract = $data['isAbstract'];
     $this->isMixin = $data['isMixin'];
     $this->isQueryable = $data['isQueryable'];
     $this->hasOrderableChildNodes = $data['hasOrderableChildNodes'];
     $this->primaryItemName = $data['primaryItemName'] ?: null;
     $this->declaredSuperTypeNames = isset($data['declaredSuperTypeNames']) && count($data['declaredSuperTypeNames']) ? $data['declaredSuperTypeNames'] : array();
     $this->declaredPropertyDefinitions = new ArrayObject();
     foreach ($data['declaredPropertyDefinitions'] as $propertyDef) {
         $this->declaredPropertyDefinitions[] = $this->factory->get('NodeType\\PropertyDefinition', array($propertyDef, $this->nodeTypeManager));
     }
     $this->declaredNodeDefinitions = new ArrayObject();
     foreach ($data['declaredNodeDefinitions'] as $nodeDef) {
         $this->declaredNodeDefinitions[] = $this->factory->get('NodeType\\NodeDefinition', array($nodeDef, $this->nodeTypeManager));
     }
 }
예제 #11
0
 /**
  * Get the node identified by an absolute path.
  *
  * To prevent unnecessary work to be done a cache is filled to only fetch
  * nodes once. To reset a node with the data from the backend, use
  * Node::refresh()
  *
  * Uses the factory to create a Node object.
  *
  * @param string $absPath The absolute path of the node to fetch.
  * @param string $class   The class of node to get. TODO: Is it sane to fetch
  *      data separately for Version and normal Node?
  * @param object $object A (prefetched) object (de-serialized json) from the backend
  *      only to be used if we get child nodes in one backend call
  *
  * @return NodeInterface
  *
  * @throws ItemNotFoundException If nothing is found at that
  *      absolute path
  * @throws RepositoryException If the path is not absolute or not
  *      well-formed
  *
  * @see Session::getNode()
  */
 public function getNodeByPath($absPath, $class = 'Node', $object = null)
 {
     $absPath = PathHelper::normalizePath($absPath);
     if (!empty($this->objectsByPath[$class][$absPath])) {
         // Return it from memory if we already have it
         return $this->objectsByPath[$class][$absPath];
     }
     // do this even if we have item in cache, will throw error if path is deleted - sanity check
     $fetchPath = $this->getFetchPath($absPath, $class);
     if (!$object) {
         // this is the first request, get data from transport
         $object = $this->transport->getNode($fetchPath);
     }
     // recursively create nodes for pre-fetched children if fetchDepth was > 1
     foreach ($object as $name => $properties) {
         if (is_object($properties)) {
             $objVars = get_object_vars($properties);
             $countObjVars = count($objVars);
             // if there's more than one objectvar or just one and this isn't jcr:uuid,
             // then we assume this child was pre-fetched from the backend completely
             if ($countObjVars > 1 || $countObjVars == 1 && !isset($objVars['jcr:uuid'])) {
                 try {
                     $parentPath = '/' === $absPath ? '/' : $absPath . '/';
                     $this->getNodeByPath($parentPath . $name, $class, $properties);
                 } catch (ItemNotFoundException $ignore) {
                     // we get here if the item was deleted or moved locally. just ignore
                 }
             }
         }
     }
     /** @var $node NodeInterface */
     $node = $this->factory->get($class, array($object, $absPath, $this->session, $this));
     if ($uuid = $node->getIdentifier()) {
         // map even nodes that are not mix:referenceable, as long as they have a uuid
         $this->objectsByUuid[$uuid] = $absPath;
     }
     $this->objectsByPath[$class][$absPath] = $node;
     return $this->objectsByPath[$class][$absPath];
 }
예제 #12
0
 /**
  * {@inheritDoc}
  */
 public function query(Query $query)
 {
     $this->assertLoggedIn();
     if (!$query instanceof QueryObjectModelInterface) {
         $parser = new Sql2ToQomQueryConverter($this->factory->get('Query\\QOM\\QueryObjectModelFactory'));
         try {
             $qom = $parser->parse($query->getStatement());
             $qom->setLimit($query->getLimit());
             $qom->setOffset($query->getOffset());
         } catch (\Exception $e) {
             throw new InvalidQueryException('Invalid query: ' . $query->getStatement(), null, $e);
         }
     } else {
         $qom = $query;
     }
     $qomWalker = new QOMWalker($this->nodeTypeManager, $this->api, $this->getNamespaces());
     list($selectors, $selectorAliases, $query) = $qomWalker->walkQOMQuery($qom);
     $primarySource = reset($selectors);
     $primaryType = $primarySource->getSelectorName() ?: $primarySource->getNodeTypeName();
     $data = $this->api->forms()->everything->ref($this->ref)->query($query)->submit();
     // TODO implement
     $results = array();
     return $results;
 }
예제 #13
0
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function createEventFilter()
 {
     return $this->factory->get('Jackalope\\Observation\\EventFilter', array($this->session));
 }
예제 #14
0
 /**
  * {@inheritDoc}
  */
 public function query(Query $query)
 {
     $this->assertLoggedIn();
     if (!$query instanceof QueryObjectModelInterface) {
         $parser = new Sql2ToQomQueryConverter($this->factory->get('Query\\QOM\\QueryObjectModelFactory'));
         try {
             $qom = $parser->parse($query->getStatement());
             $qom->setLimit($query->getLimit());
             $qom->setOffset($query->getOffset());
         } catch (\Exception $e) {
             throw new InvalidQueryException('Invalid query: ' . $query->getStatement(), null, $e);
         }
     } else {
         $qom = $query;
     }
     $qomWalker = new QOMWalker($this->nodeTypeManager, $this->getConnection(), $this->getNamespaces());
     list($selectors, $selectorAliases, $sql) = $qomWalker->walkQOMQuery($qom);
     $primarySource = reset($selectors);
     $primaryType = $primarySource->getSelectorName() ?: $primarySource->getNodeTypeName();
     $data = $this->getConnection()->fetchAll($sql, array($this->workspaceName));
     $results = $properties = $standardColumns = array();
     foreach ($data as $row) {
         $result = array();
         /** @var SelectorInterface $selector */
         foreach ($selectors as $selector) {
             $selectorName = $selector->getSelectorName() ?: $selector->getNodeTypeName();
             $columnPrefix = isset($selectorAliases[$selectorName]) ? $selectorAliases[$selectorName] . '_' : $selectorAliases[''] . '_';
             if ($primaryType === $selector->getNodeTypeName()) {
                 $result[] = array('dcr:name' => 'jcr:path', 'dcr:value' => $row[$columnPrefix . 'path'], 'dcr:selectorName' => $selectorName);
             }
             $result[] = array('dcr:name' => 'jcr:path', 'dcr:value' => $row[$columnPrefix . 'path'], 'dcr:selectorName' => $selectorName);
             $result[] = array('dcr:name' => 'jcr:score', 'dcr:value' => 0, 'dcr:selectorName' => $selectorName);
             if (0 === count($qom->getColumns())) {
                 $selectorPrefix = null !== $selector->getSelectorName() ? $selectorName . '.' : '';
                 $result[] = array('dcr:name' => $selectorPrefix . 'jcr:primaryType', 'dcr:value' => $primaryType, 'dcr:selectorName' => $selectorName);
             }
             if (isset($row[$columnPrefix . 'props'])) {
                 $propertyNames = array();
                 $columns = $qom->getColumns();
                 // Always populate jcr:created and jcr:createdBy if a wildcard selector is used.
                 // This emulates the behavior of Jackrabbit
                 if (0 === count($columns)) {
                     $propertyNames = array('jcr:created', 'jcr:createdBy');
                 }
                 foreach ($columns as $column) {
                     if (!$column->getSelectorName() || $column->getSelectorName() == $selectorName) {
                         $propertyNames[] = $column->getPropertyName();
                     }
                 }
                 $properties[$selectorName] = (array) $this->xmlToColumns($row[$columnPrefix . 'props'], $propertyNames);
             } else {
                 $properties[$selectorName] = array();
             }
             // TODO: add other default columns that Jackrabbit provides to provide a more consistent behavior
             if (isset($properties[$selectorName]['jcr:createdBy'])) {
                 $standardColumns[$selectorName]['jcr:createdBy'] = $properties[$selectorName]['jcr:createdBy'];
             }
             if (isset($properties[$selectorName]['jcr:created'])) {
                 $standardColumns[$selectorName]['jcr:created'] = $properties[$selectorName]['jcr:created'];
             }
         }
         $reservedNames = array('jcr:path', 'jcr:score');
         foreach ($qom->getColumns() as $column) {
             $selectorName = $column->getSelectorName();
             $columnName = $column->getPropertyName();
             $columnPrefix = isset($selectorAliases[$selectorName]) ? $selectorAliases[$selectorName] . '_' : $selectorAliases[''] . '_';
             if (in_array($column->getColumnName(), $reservedNames)) {
                 throw new InvalidQueryException(sprintf('Cannot reserved name "%s". Reserved names are "%s"', $column->getColumnName(), implode('", "', $reservedNames)));
             }
             $dcrValue = 'jcr:uuid' === $columnName ? $row[$columnPrefix . 'identifier'] : (isset($properties[$selectorName][$columnName]) ? $properties[$selectorName][$columnName] : '');
             if (isset($standardColumns[$selectorName][$columnName])) {
                 unset($standardColumns[$selectorName][$columnName]);
             }
             $result[] = array('dcr:name' => $column->getColumnName() === $columnName && isset($properties[$selectorName][$columnName]) ? $selectorName . '.' . $columnName : $column->getColumnName(), 'dcr:value' => $dcrValue, 'dcr:selectorName' => $selectorName ?: $primaryType);
         }
         foreach ($standardColumns as $selectorName => $columns) {
             foreach ($columns as $columnName => $value) {
                 $result[] = array('dcr:name' => $primaryType . '.' . $columnName, 'dcr:value' => $value, 'dcr:selectorName' => $selectorName);
             }
         }
         $results[] = $result;
     }
     return $results;
 }
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function createQuery(SourceInterface $source, ConstraintInterface $constraint = null, array $orderings = array(), array $columns = array())
 {
     return $this->factory->get('Query\\QOM\\QueryObjectModel', array($this->objectManager, $source, $constraint, $orderings, $columns));
 }
예제 #16
0
 /**
  * {@inheritDoc}
  */
 public function createWorkspace($name, $srcWorkspace = null)
 {
     if (null != $srcWorkspace) {
         // https://issues.apache.org/jira/browse/JCR-3144
         throw new UnsupportedRepositoryOperationException('Can not create a workspace from a source workspace as we neither implemented clone nor have native support for this');
     }
     $curl = $this->getCurl();
     $uri = $this->server . $name;
     $request = $this->factory->get('Transport\\Jackrabbit\\Request', array($this, $curl, Request::MKWORKSPACE, $uri));
     $request->setCredentials($this->credentials);
     foreach ($this->defaultHeaders as $header) {
         $request->addHeader($header);
     }
     if (!$this->sendExpect) {
         $request->addHeader("Expect:");
     }
     $request->execute();
 }
예제 #17
0
 /**
  * {@inheritDoc}
  *
  * @api
  */
 public function getQOMFactory()
 {
     return $this->factory->get('Query\\QOM\\QueryObjectModelFactory', array($this->objectManager));
 }