/**
  * Performs the publishing operations required to set the version identified by $updateStruct->versionNo and
  * $updateStruct->id as the published one.
  *
  * @param int $contentId
  * @param int $versionNo
  * @param \eZ\Publish\SPI\Persistence\Content\MetadataUpdateStruct $metaDataUpdateStruct
  *
  * @return \eZ\Publish\SPI\Persistence\Content The published Content
  */
 public function publish($contentId, $versionNo, MetadataUpdateStruct $metaDataUpdateStruct)
 {
     // Change Content currentVersionNo to the published version
     $this->backend->update('Content', $contentId, array('_currentVersionNo' => $versionNo));
     // Update ContentInfo published flag and change the currentVersionNo to the published version
     $contentInfoUpdateData = array("currentVersionNo" => $versionNo, "isPublished" => true);
     // Update ContentInfo with set properties in $metaDataUpdateStruct
     foreach ($metaDataUpdateStruct as $propertyName => $propertyValue) {
         if (isset($propertyValue)) {
             if ($propertyName === "alwaysAvailable") {
                 $contentInfoUpdateData["alwaysAvailable"] = $propertyValue;
             } else {
                 if ($propertyName === "mainLanguageId") {
                     $contentInfoUpdateData["mainLanguageCode"] = $this->handler->contentLanguageHandler()->load($propertyValue)->languageCode;
                 } else {
                     $contentInfoUpdateData[$propertyName] = $propertyValue;
                 }
             }
         }
     }
     $this->backend->update('Content\\ContentInfo', $contentId, $contentInfoUpdateData, true);
     // Update VersionInfo with modified timestamp and published status
     $this->backend->updateByMatch('Content\\VersionInfo', array('_contentId' => $contentId, 'versionNo' => $versionNo), array("modificationDate" => $metaDataUpdateStruct->modificationDate, "status" => VersionInfo::STATUS_PUBLISHED));
     return $this->load($contentId, $versionNo);
 }
 /**
  * Returns the user policies associated with the user (including inherited policies from user groups)
  *
  * @param mixed $userId
  *
  * @return \eZ\Publish\SPI\Persistence\User\Policy[]
  * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user (it's content object atm) is not found
  * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user is not of user Content Type
  */
 public function loadPoliciesByUserId($userId)
 {
     $list = $this->backend->find('Content', array('id' => $userId), array('versionInfo' => array('type' => 'Content\\VersionInfo', 'match' => array('_contentId' => 'id', 'versionNo' => '_currentVersionNo'), 'single' => true, 'sub' => array('contentInfo' => array('type' => 'Content\\ContentInfo', 'match' => array('id' => '_contentId'), 'single' => true)))));
     if (!$list) {
         throw new NotFound('User', $userId);
     }
     $policies = array();
     $this->getPermissionsForObject($list[0], 4, $policies);
     // crawl up path on all locations
     $locations = $this->handler->locationHandler()->loadLocationsByContent($list[0]->versionInfo->contentInfo->id);
     foreach ($locations as $location) {
         $parentIds = array_reverse(explode('/', trim($location->pathString, '/')));
         foreach ($parentIds as $parentId) {
             if ($parentId == $location->id) {
                 continue;
             }
             $location = $this->backend->load('Content\\Location', $parentId);
             $list2 = $this->backend->find('Content', array('id' => $location->contentId), array('versionInfo' => array('type' => 'Content\\VersionInfo', 'match' => array('_contentId' => 'id', 'versionNo' => '_currentVersionNo'), 'single' => true, 'sub' => array('contentInfo' => array('type' => 'Content\\ContentInfo', 'match' => array('id' => '_contentId'), 'single' => true)))));
             if (isset($list2[1])) {
                 throw new LogicException("'content tree' logic error, there is more than one item with parentId: {$parentId}");
             }
             if ($list2) {
                 $this->getPermissionsForObject($list2[0], 3, $policies);
             }
         }
     }
     return array_values($policies);
 }
 /**
  * Removes a location from its $locationId (but not its descendants)
  * Content which looses its main Location will get the first
  * of its other Locations assigned as the new main Location.
  * If content has no location left, it's removed from backend
  *
  * @param mixed $locationId
  */
 public function delete($locationId)
 {
     $location = $this->load($locationId);
     $this->backend->delete('Content\\Location', $locationId);
     $remainingLocations = $this->backend->find('Content\\Location', array('contentId' => $location->contentId));
     // If no remaining location for associated content, remove the content as well
     // Else, update the mainLocationId if needed
     if (empty($remainingLocations)) {
         try {
             $this->handler->contentHandler()->deleteContent($location->contentId);
         } catch (NotFound $e) {
         }
     } else {
         $this->backend->update('Content\\ContentInfo', $location->contentId, array('mainLocationId' => $remainingLocations[0]->id));
     }
 }
 /**
  * @see eZ\Publish\SPI\Persistence\Content\Location\Trash\Handler
  */
 public function deleteTrashItem($trashedId)
 {
     $vo = $this->loadTrashItem($trashedId);
     $this->handler->contentHandler()->deleteContent($vo->contentId);
     $this->backend->delete('Content\\Location\\Trashed', $trashedId);
 }
 /**
  * Generate match array for use with Backend based on criteria
  *
  * @param array $criteria
  * @param array $match
  *
  * @return void
  */
 protected function generateMatchByCriteria(array $criteria, array &$match)
 {
     foreach ($criteria as $criterion) {
         if ($criterion instanceof LogicalAnd) {
             $this->generateMatchByCriteria($criterion->criteria, $match);
         } else {
             if ($criterion instanceof LogicalOr && !isset($match['or'])) {
                 foreach ($criterion->criteria as $subCriterion) {
                     $subMatch = array();
                     $this->generateMatchByCriteria(array($subCriterion), $subMatch);
                     $match['or'][] = $subMatch;
                 }
             } else {
                 if ($criterion instanceof ContentId && !isset($match['id'])) {
                     $match['id'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                 } else {
                     if ($criterion instanceof ContentTypeId && !isset($match['versionInfo']['contentInfo']['typeId'])) {
                         $match['versionInfo']['contentInfo']['contentTypeId'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                     } else {
                         if ($criterion instanceof LocationId && !isset($match['locations']['id'])) {
                             $match['locations']['id'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                         } else {
                             if ($criterion instanceof RemoteId && !isset($match['versionInfo']['contentInfo']['remoteId'])) {
                                 $match['versionInfo']['contentInfo']['remoteId'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                             } else {
                                 if ($criterion instanceof LocationRemoteId && !isset($match['locations']['remoteId'])) {
                                     $match['locations']['remoteId'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                                 } else {
                                     if ($criterion instanceof ObjectStateId && !isset($match['objectStates']['id'])) {
                                         $match['objectStates']['id'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                                     } else {
                                         if ($criterion instanceof LanguageCode && !isset($match['versionInfo']['languageIds'])) {
                                             $languageHandler = $this->handler->contentLanguageHandler();
                                             $languageIds = array_map(function ($languageCode) use($languageHandler) {
                                                 return $languageHandler->loadByLanguageCode($languageCode)->id;
                                             }, $criterion->value);
                                             $match['versionInfo']['languageIds'] = $criterion->operator === Operator::IN ? $languageIds : $languageIds[0];
                                         } else {
                                             if ($criterion instanceof SectionId && !isset($match['versionInfo']['contentInfo']['sectionId'])) {
                                                 $match['versionInfo']['contentInfo']['sectionId'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                                             } else {
                                                 if ($criterion instanceof Status && !isset($match['versionInfo']['status'])) {
                                                     switch ($criterion->value[0]) {
                                                         case Status::STATUS_ARCHIVED:
                                                             $match['versionInfo']['status'] = VersionInfo::STATUS_ARCHIVED;
                                                             break;
                                                         case Status::STATUS_DRAFT:
                                                             $match['versionInfo']['status'] = VersionInfo::STATUS_DRAFT;
                                                             break;
                                                         case Status::STATUS_PUBLISHED:
                                                             $match['versionInfo']['status'] = VersionInfo::STATUS_PUBLISHED;
                                                             break;
                                                         default:
                                                             throw new Exception("Unsupported StatusCriterion->value[0]: " . $criterion->value[0]);
                                                     }
                                                 } else {
                                                     if ($criterion instanceof ParentLocationId && !isset($match['locations']['parentId'])) {
                                                         $match['locations']['parentId'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                                                     } else {
                                                         if ($criterion instanceof Subtree && !isset($match['locations']['pathString'])) {
                                                             $match['locations']['pathString'] = $criterion->value[0] . '%';
                                                         } else {
                                                             if ($criterion instanceof UserMetadata && $criterion->target !== $criterion::MODIFIER) {
                                                                 if ($criterion->target === $criterion::OWNER && !isset($match['versionInfo']['contentInfo']['ownerId'])) {
                                                                     $match['versionInfo']['contentInfo']['ownerId'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                                                                 } else {
                                                                     if ($criterion->target === $criterion::CREATOR && !isset($match['versionInfo']['creatorId'])) {
                                                                         $match['versionInfo']['creatorId'] = $criterion->operator === Operator::IN ? $criterion->value : $criterion->value[0];
                                                                     }
                                                                 }
                                                                 //else if ( $criterion->target === $criterion::MODIFIER && !isset( $match['version']['creatorId'] ) )
                                                                 //$match['version']['creatorId'] = $criterion->value[0];
                                                                 continue;
                                                             }
                                                             throw new Exception("Support for provided criterion not supported or used more then once: " . get_class($criterion));
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }