/**
  * Adds object $contentObject to the search database.
  *
  * @param \eZContentObject $contentObject Object to add to search engine
  * @param bool $commit Whether to commit after adding the object
  *
  * @return bool True if the operation succeeded.
  */
 public function addObject($contentObject, $commit = true)
 {
     // Indexing is not implemented in eZ Publish 5 legacy search engine
     if ($this->searchHandler instanceof LegacyHandler) {
         $searchEngine = new eZSearchEngine();
         $searchEngine->addObject($contentObject, $commit);
         return true;
     }
     try {
         // If the method is called for restoring from trash we'll be inside a transaction,
         // meaning created Location(s) will not be visible outside of it.
         // We check that Content's Locations are visible from the new stack, if not Content
         // will be registered for indexing.
         foreach ($contentObject->assignedNodes() as $node) {
             $this->persistenceHandler->locationHandler()->load($node->attribute('node_id'));
         }
         $content = $this->persistenceHandler->contentHandler()->load((int) $contentObject->attribute('id'), (int) $contentObject->attribute('current_version'));
     } catch (NotFoundException $e) {
         $pendingAction = new eZPendingActions(array('action' => 'index_object', 'created' => time(), 'param' => (int) $contentObject->attribute('id')));
         $pendingAction->store();
         return true;
     }
     $this->searchHandler->indexContent($content);
     if ($commit) {
         $this->commit();
     }
     return true;
 }
 /**
  * Adds object $contentObject to the search database.
  *
  * @param \eZContentObject $contentObject Object to add to search engine
  * @param bool $commit Whether to commit after adding the object
  *
  * @return bool True if the operation succeeded.
  */
 public function addObject($contentObject, $commit = true)
 {
     // Indexing is not implemented in eZ Publish 5 legacy search engine
     if ($this->searchEngine == 'legacy') {
         $searchEngine = new eZSearchEngine();
         $searchEngine->addObject($contentObject, $commit);
     } else {
         $content = $this->persistenceHandler->contentHandler()->load((int) $contentObject->attribute('id'), (int) $contentObject->attribute('current_version'));
         $this->searchHandler->indexContent($content);
     }
     if ($commit) {
         $this->commit();
     }
     return true;
 }
 /**
  * Removes a relation of type COMMON from a draft.
  *
  * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the user is not allowed edit this version
  * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException if the version is not a draft
  * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if there is no relation of type COMMON for the given destination
  *
  * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo $sourceVersion
  * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $destinationContent
  */
 public function deleteRelation(APIVersionInfo $sourceVersion, ContentInfo $destinationContent)
 {
     $sourceVersion = $this->loadVersionInfoById($sourceVersion->contentInfo->id, $sourceVersion->versionNo);
     if ($sourceVersion->status !== APIVersionInfo::STATUS_DRAFT) {
         throw new BadStateException('$sourceVersion', 'Relations of type common can only be removed from versions of status draft');
     }
     if (!$this->repository->canUser('content', 'edit', $sourceVersion)) {
         throw new UnauthorizedException('content', 'edit', array('contentId' => $sourceVersion->contentInfo->id));
     }
     $spiRelations = $this->persistenceHandler->contentHandler()->loadRelations($sourceVersion->getContentInfo()->id, $sourceVersion->versionNo, APIRelation::COMMON);
     if (empty($spiRelations)) {
         throw new InvalidArgumentException('$sourceVersion', 'There are no relations of type COMMON for the given destination');
     }
     // there should be only one relation of type COMMON for each destination,
     // but in case there were ever more then one, we will remove them all
     // @todo: alternatively, throw BadStateException?
     $this->repository->beginTransaction();
     try {
         foreach ($spiRelations as $spiRelation) {
             if ($spiRelation->destinationContentId == $destinationContent->id) {
                 $this->persistenceHandler->contentHandler()->removeRelation($spiRelation->id, APIRelation::COMMON);
             }
         }
         $this->repository->commit();
     } catch (Exception $e) {
         $this->repository->rollback();
         throw $e;
     }
 }
 /**
  * Deletes $location and all its descendants.
  *
  * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If the current user is not allowed to delete this location or a descendant
  *
  * @param \eZ\Publish\API\Repository\Values\Content\Location $location
  */
 public function deleteLocation(APILocation $location)
 {
     $location = $this->loadLocation($location->id);
     if (!$this->repository->canUser('content', 'manage_locations', $location->getContentInfo())) {
         throw new UnauthorizedException('content', 'manage_locations');
     }
     if (!$this->repository->canUser('content', 'remove', $location->getContentInfo(), $location)) {
         throw new UnauthorizedException('content', 'remove');
     }
     /** Check remove access to descendants
      * @var boolean|\eZ\Publish\API\Repository\Values\Content\Query\Criterion $contentReadCriterion
      */
     $contentReadCriterion = $this->permissionsCriterionHandler->getPermissionsCriterion('content', 'remove');
     if ($contentReadCriterion === false) {
         throw new UnauthorizedException('content', 'remove');
     } else {
         if ($contentReadCriterion !== true) {
             // Query if there are any content in subtree current user don't have access to
             $query = new Query(array('limit' => 0, 'filter' => new CriterionLogicalAnd(array(new CriterionSubtree($location->pathString), new CriterionLogicalNot($contentReadCriterion)))));
             $result = $this->repository->getSearchService()->findContent($query, array(), false);
             if ($result->totalCount > 0) {
                 throw new UnauthorizedException('content', 'remove');
             }
         }
     }
     $this->repository->beginTransaction();
     try {
         $this->persistenceHandler->locationHandler()->removeSubtree($location->id);
         $this->persistenceHandler->urlAliasHandler()->locationDeleted($location->id);
         $this->repository->commit();
     } catch (Exception $e) {
         $this->repository->rollback();
         throw $e;
     }
 }
 /**
  * Returns a collection of Trashed locations contained in the trash.
  *
  * $query allows to filter/sort the elements to be contained in the collection.
  *
  * @param \eZ\Publish\API\Repository\Values\Content\Query $query
  *
  * @return \eZ\Publish\API\Repository\Values\Content\SearchResult
  */
 public function findTrashItems(Query $query)
 {
     if ($query->filter !== null && !$query->filter instanceof Criterion) {
         throw new InvalidArgumentValue("query->filter", $query->filter, "Query");
     }
     if ($query->sortClauses !== null) {
         if (!is_array($query->sortClauses)) {
             throw new InvalidArgumentValue("query->sortClauses", $query->sortClauses, "Query");
         }
         foreach ($query->sortClauses as $sortClause) {
             if (!$sortClause instanceof SortClause) {
                 throw new InvalidArgumentValue("query->sortClauses", "only instances of SortClause class are allowed");
             }
         }
     }
     if ($query->offset !== null && !is_numeric($query->offset)) {
         throw new InvalidArgumentValue("query->offset", $query->offset, "Query");
     }
     if ($query->limit !== null && !is_numeric($query->limit)) {
         throw new InvalidArgumentValue("query->limit", $query->limit, "Query");
     }
     $spiTrashItems = $this->persistenceHandler->trashHandler()->findTrashItems($query->filter !== null ? $query->filter : null, $query->offset !== null && $query->offset > 0 ? (int) $query->offset : 0, $query->limit !== null && $query->limit >= 1 ? (int) $query->limit : null, $query->sortClauses !== null ? $query->sortClauses : null);
     $trashItems = array();
     foreach ($spiTrashItems as $spiTrashItem) {
         $trashItems[] = $this->buildDomainTrashItemObject($spiTrashItem);
     }
     $searchResult = new SearchResult();
     $searchResult->count = count($trashItems);
     $searchResult->items = $trashItems;
     $searchResult->query = $query;
     return $searchResult;
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     @trigger_error(sprintf('%s is deprecated since 6.7. Use ezplatform:reindex command instead', $this->getName()), E_USER_DEPRECATED);
     $bulkCount = $input->getArgument('bulk_count');
     // Indexing Content
     $totalCount = $this->getContentObjectsTotalCount($this->databaseHandler, ContentInfo::STATUS_PUBLISHED);
     $query = $this->databaseHandler->createSelectQuery();
     $query->select('id', 'current_version')->from('ezcontentobject')->where($query->expr->eq('status', ContentInfo::STATUS_PUBLISHED));
     $stmt = $query->prepare();
     $stmt->execute();
     $this->searchHandler->purgeIndex();
     $output->writeln('Indexing Content...');
     /* @var \Symfony\Component\Console\Helper\ProgressHelper $progress */
     $progress = $this->getHelperSet()->get('progress');
     $progress->start($output, $totalCount);
     $i = 0;
     do {
         $contentObjects = [];
         for ($k = 0; $k <= $bulkCount; ++$k) {
             if (!($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
                 break;
             }
             try {
                 $contentObjects[] = $this->persistenceHandler->contentHandler()->load($row['id'], $row['current_version']);
             } catch (NotFoundException $e) {
                 $this->logWarning($output, $progress, "Could not load current version of Content with id {$row['id']}, so skipped for indexing. Full exception: " . $e->getMessage());
             }
         }
         $this->searchHandler->bulkIndex($contentObjects, function (Content $content, NotFoundException $e) use($output, $progress) {
             $this->logWarning($output, $progress, 'Content with id ' . $content->versionInfo->id . ' has missing data, so skipped for indexing. Full exception: ' . $e->getMessage());
         });
         $progress->advance($k);
     } while (($i += $bulkCount) < $totalCount);
     $progress->finish();
 }
示例#7
0
    /**
     * Returns a persistence Handler mock
     *
     * @return \eZ\Publish\SPI\Persistence\Handler|\PHPUnit_Framework_MockObject_MockObject
     */
    protected function getPersistenceMock()
    {
        if ( !isset( $this->persistenceMock ) )
        {
            $this->persistenceMock = $this->getMock(
                "eZ\\Publish\\SPI\\Persistence\\Handler",
                array(),
                array(),
                '',
                false
            );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'contentHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'searchHandler' )
                ->will(  $this->returnValue( $this->getSPIMockHandler( 'Search\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'contentTypeHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\Type\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'contentLanguageHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\Language\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'locationHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\Location\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'objectStateHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\ObjectState\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'trashHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\Location\\Trash\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'userHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'User\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'sectionHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\Section\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'urlAliasHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\UrlAlias\\Handler' ) ) );

            $this->persistenceMock->expects( $this->any() )
                ->method( 'urlWildcardHandler' )
                ->will(  $this->returnValue( $this->getPersistenceMockHandler( 'Content\\UrlWildcard\\Handler' ) ) );
        }

        return $this->persistenceMock;
    }
 /**
  * Persists relation data for a content version.
  *
  * This method creates new relations and deletes removed relations.
  *
  * @param array $inputRelations
  * @param mixed $sourceContentId
  * @param mixed $sourceContentVersionNo
  * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType
  * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $existingRelations An array of existing relations for Content version (empty when creating new content)
  *
  * @return void
  */
 public function processFieldRelations(array $inputRelations, $sourceContentId, $sourceContentVersionNo, ContentType $contentType, array $existingRelations = array())
 {
     // Map existing relations for easier handling
     $mappedRelations = array();
     foreach ($existingRelations as $relation) {
         if ($relation->type === Relation::FIELD) {
             $fieldDefinitionId = $contentType->getFieldDefinition($relation->sourceFieldDefinitionIdentifier)->id;
             $mappedRelations[$relation->type][$fieldDefinitionId][$relation->destinationContentInfo->id] = $relation;
         }
         // Using bitwise AND as Legacy Stack stores COMMON, LINK and EMBED relation types
         // in the same entry using bitmask
         if ($relation->type & Relation::LINK) {
             $mappedRelations[Relation::LINK][$relation->destinationContentInfo->id] = $relation;
         }
         if ($relation->type & Relation::EMBED) {
             $mappedRelations[Relation::EMBED][$relation->destinationContentInfo->id] = $relation;
         }
     }
     // Add new relations
     foreach ($inputRelations as $relationType => $relationData) {
         if ($relationType === Relation::FIELD) {
             foreach ($relationData as $fieldDefinitionId => $contentIds) {
                 foreach (array_keys($contentIds) as $destinationContentId) {
                     if (isset($mappedRelations[$relationType][$fieldDefinitionId][$destinationContentId])) {
                         unset($mappedRelations[$relationType][$fieldDefinitionId][$destinationContentId]);
                     } else {
                         $this->persistenceHandler->contentHandler()->addRelation(new SPIRelationCreateStruct(array("sourceContentId" => $sourceContentId, "sourceContentVersionNo" => $sourceContentVersionNo, "sourceFieldDefinitionId" => $fieldDefinitionId, "destinationContentId" => $destinationContentId, "type" => $relationType)));
                     }
                 }
             }
         } else {
             if ($relationType === Relation::LINK || $relationType === Relation::EMBED) {
                 foreach (array_keys($relationData) as $destinationContentId) {
                     if (isset($mappedRelations[$relationType][$destinationContentId])) {
                         unset($mappedRelations[$relationType][$destinationContentId]);
                     } else {
                         $this->persistenceHandler->contentHandler()->addRelation(new SPIRelationCreateStruct(array("sourceContentId" => $sourceContentId, "sourceContentVersionNo" => $sourceContentVersionNo, "sourceFieldDefinitionId" => null, "destinationContentId" => $destinationContentId, "type" => $relationType)));
                     }
                 }
             }
         }
     }
     // Remove relations not present in input set
     foreach ($mappedRelations as $relationType => $relationData) {
         foreach ($relationData as $relationEntry) {
             switch ($relationType) {
                 case Relation::FIELD:
                     foreach ($relationEntry as $relation) {
                         $this->persistenceHandler->contentHandler()->removeRelation($relation->id, $relationType);
                     }
                     break;
                 case Relation::LINK:
                 case Relation::EMBED:
                     $this->persistenceHandler->contentHandler()->removeRelation($relationEntry->id, $relationType);
             }
         }
     }
 }
示例#9
0
 /**
  * Rollback transaction
  *
  * Rollback transaction, or throw exceptions if no transactions has been started.
  *
  * @throws RuntimeException If no transaction has been started
  */
 public function rollback()
 {
     try {
         $this->persistenceHandler->rollback();
         --$this->transactionDepth;
         unset($this->commitEventsQueue[$this->transactionCount]);
     } catch (Exception $e) {
         throw new RuntimeException($e->getMessage(), 0, $e);
     }
 }
示例#10
0
 /**
  * @return \eZ\Publish\SPI\Persistence\Content\UrlWildcard\Handler
  * @todo Create cache implementation so we can avoid injecting persistenceHandler and logger
  */
 public function urlWildcardHandler()
 {
     $this->logger->logUnCachedHandler(__METHOD__);
     return $this->persistenceHandler->urlWildcardHandler();
 }
 /**
  * Test that instance is of correct type
  *
  * @covers eZ\Publish\Core\Persistence\Factory::getUrlWildcardHandler
  * @depends testGetPersistenceHandler
  */
 public function testGetUrlWildcardHandler()
 {
     $this->persistenceMock->expects($this->once())->method('urlWildcardHandler');
     $this->persistenceFactory->getUrlWildcardHandler();
 }