Executes revert action on content and its draft.

@param  AbstractClassContent $content
@param  Revision             $draft
@param  array                $data

@return ClassContentManager
191542
private function executeRevert(AbstractClassContent $content, Revision $draft, array $data)
    {
        $content->setDraft(null);
        if ($content instanceof ContentSet) {
            if (isset($data['elements']) && true === $data['elements']) {
                $draft->clear();
                foreach ($content->getData() as $element) {
                    if ($element instanceof AbstractClassContent) {
                        $draft->push($element);
                    }
                }
            }
        } else {
            foreach ($content->getData() as $key => $element) {
                if (isset($data['elements']) && in_array($key, $data['elements'])) {
                    $draft->$key = $content->$key;
                }

                if (in_array('Element\Keyword', $content->getAccept()[$key])) {
                    $this->entityManager
                        ->getRepository('BackBee\ClassContent\Element\Keyword')
                        ->cleanKeywordLinks($content, $element);
                }
            }
        }

        if (isset($data['parameters'])) {
            foreach ($content->getDefaultParams() as $key => $params) {
                if (in_array($key, $data['parameters'])) {
                    $draft->setParam($key, $content->getParamValue($key));
                }
            }
        }

        return $this;
    }
1252662
public function publishDraft( Content $content )
    {
        $this->getRepository()->sudo(
            function(Repository $repository) use ( $content )
            {
                $repository->getContentService()->publishVersion($content->versionInfo->id);
            }
        );
    }
337814
public function push(AbstractClassContent $var)
    {
        if (!($this->_content instanceof ContentSet)) {
            throw new ClassContentException(
                sprintf('Can not push in a content %s.', get_class($this)),
                ClassContentException::UNKNOWN_ERROR
            );
        }

        if ($this->isAccepted($var)) {
            $this->_data[] = array(get_class($var) => $var->getUid());
        }

        return $this->getContent();
    }
1115723
public static function onFlushElementFile(Event $event)
    {
        $revision = $event->getTarget();
        $content = $revision->getContent();

        if (!($content instanceof ElementFile) || !is_file($content->path)) {
            return;
        }

        $application = $event->getApplication();
        $em = $application->getEntityManager();
        $uow = $em->getUnitOfWork();

        if ($uow->isScheduledForDelete($content)) {
            return;
        }

        $fileRepository = $em->getRepository('BackBee\ClassContent\Element\File');
        $fileRepository->setDirectories($application);

        $fileRepository->commitFile($content);

        $moveFrom = $content->path;
        File::resolveFilepath($moveFrom, null, array('base_dir' => $application->getMediaDir()));

        if (file_exists($moveFrom)) {
            $content->setParam('stat', json_encode(stat($moveFrom)));

            if ($content instanceof ElementImage) {
                list($width, $height) = getimagesize($moveFrom);

                $content->setParam('width', $width);
                $content->setParam('height', $height);
            }
        }

        $uow->recomputeSingleEntityChangeSet($em->getClassMetadata('BackBee\ClassContent\Revision'), $revision);
    }
210300
protected function update($step)
    {
        $contentTypeCollection = $this->matchContentTypes('update', $step);

        if (count($contentTypeCollection) > 1 && array_key_exists('references', $step->dsl)) {
            throw new \Exception("Can not execute Content Type update because multiple types match, and a references section is specified in the dsl. References can be set when only 1 type matches");
        }

        if (count($contentTypeCollection) > 1 && array_key_exists('new_identifier', $step->dsl)) {
            throw new \Exception("Can not execute Content Type update because multiple roles match, and a new_identifier is specified in the dsl.");
        }

        $contentTypeService = $this->repository->getContentTypeService();
        $lang = $this->getLanguageCode($step);
        foreach ($contentTypeCollection as $key => $contentType) {

            if (isset($step->dsl['remove_drafts']) && $step->dsl['remove_drafts']) {
                try {
                    $draft = $contentTypeService->loadContentTypeDraft($contentType->id);
                    $contentTypeService->deleteContentType($draft);
                } catch (NotFoundException $e) {
                }
            }

            $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);

            $contentTypeUpdateStruct = $contentTypeService->newContentTypeUpdateStruct();
            $contentTypeUpdateStruct->mainLanguageCode = $lang;

            $newIdentifier = null;
            if (isset($step->dsl['new_identifier'])) {
                $newIdentifier = $this->referenceResolver->resolveReference($step->dsl['new_identifier']);
                $contentTypeUpdateStruct->identifier = $newIdentifier;
            }

            if (isset($step->dsl['name'])) {
                $contentTypeUpdateStruct->names = $this->getMultilingualValue($step->dsl['name'], $lang, $contentTypeDraft->getNames());
            }

            if (isset($step->dsl['description'])) {
                $contentTypeUpdateStruct->descriptions = $this->getMultilingualValue($step->dsl['description'], $lang, $contentTypeDraft->getDescriptions());
            }

            if (isset($step->dsl['name_pattern'])) {
                $contentTypeUpdateStruct->nameSchema = $step->dsl['name_pattern'];
            }

            if (isset($step->dsl['url_name_pattern'])) {
                $contentTypeUpdateStruct->urlAliasSchema = $step->dsl['url_name_pattern'];
            }

            if (isset($step->dsl['is_container'])) {
                $contentTypeUpdateStruct->isContainer = $step->dsl['is_container'];
            }

            if (isset($step->dsl['default_always_available'])) {
                $contentTypeUpdateStruct->defaultAlwaysAvailable = $step->dsl['default_always_available'];
            }

            if (isset($step->dsl['default_sort_field'])) {
                $contentTypeUpdateStruct->defaultSortField = $this->sortConverter->hash2SortField($step->dsl['default_sort_field']);
            }

            if (isset($step->dsl['default_sort_order'])) {
                $contentTypeUpdateStruct->defaultSortOrder = $this->sortConverter->hash2SortOrder($step->dsl['default_sort_order']);
            }

            // Add/edit attributes
            if (isset($step->dsl['attributes'])) {
                // NB: seems like eZ gets mixed up if we pass some attributes with a position and some without...
                // We go out of our way to avoid collisions and preserve order
                $maxFieldDefinitionPos = count($contentType->fieldDefinitions);
                $newFieldDefinitions = array();
                foreach ($step->dsl['attributes'] as $attribute) {

                    // allow easy reuse of attribute defs by storing them in references
                    if (is_string($attribute)) {
                        $attribute = $this->referenceResolver->resolveReference($attribute);
                    }

                    $existingFieldDefinition = $this->contentTypeHasFieldDefinition($contentType, $attribute['identifier']);

                    if ($existingFieldDefinition) {
                        // Edit existing attribute
                        $fieldDefinitionUpdateStruct = $this->updateFieldDefinition(
                            $contentTypeService, $attribute, $attribute['identifier'], $contentType->identifier, $lang, $existingFieldDefinition
                        );
                        $contentTypeService->updateFieldDefinition(
                            $contentTypeDraft,
                            $existingFieldDefinition,
                            $fieldDefinitionUpdateStruct
                        );
                        if ($fieldDefinitionUpdateStruct->position > 0) {
                            $maxFieldDefinitionPos = $fieldDefinitionUpdateStruct->position > $maxFieldDefinitionPos ? $fieldDefinitionUpdateStruct->position : $maxFieldDefinitionPos;
                        } else {
                            $maxFieldDefinitionPos = $existingFieldDefinition->position > $maxFieldDefinitionPos ? $existingFieldDefinition->position : $maxFieldDefinitionPos;
                        }

                    } else {
                        // Create new attributes, keep them in temp array
                        $newFieldDefinition = $this->createFieldDefinition($contentTypeService, $attribute, $contentType->identifier, $lang);
                        $maxFieldDefinitionPos = $newFieldDefinition->position > $maxFieldDefinitionPos ? $newFieldDefinition->position : $maxFieldDefinitionPos;
                        $newFieldDefinitions[] = $newFieldDefinition;
                    }
                }

                // Add new attributes
                foreach($newFieldDefinitions as $newFieldDefinition) {
                    if ($newFieldDefinition->position == 0) {
                        $newFieldDefinition->position = ++$maxFieldDefinitionPos;
                    }
                    $contentTypeService->addFieldDefinition($contentTypeDraft, $newFieldDefinition);
                }
            }

            // Remove attributes
            if (isset($step->dsl['remove_attributes'])) {

                // allow the '*' string to mean 'all attributes excepts the ones specified in this step'
                if ($step->dsl['remove_attributes'] === '*') {
                    $modifiedAttributeIdentifiers = array();
                    foreach ($step->dsl['attributes'] as $attribute) {
                        $modifiedAttributeIdentifiers[] = $attribute['identifier'];
                    }

                    foreach ($contentType->getFieldDefinitions() as $existingFieldDefinition) {
                        if (!in_array($existingFieldDefinition->identifier, $modifiedAttributeIdentifiers)) {
                            $contentTypeService->removeFieldDefinition($contentTypeDraft, $existingFieldDefinition);
                        }
                    }
                } else {
                    // we assume that $step->dsl['remove_attributes'] is an array of field identifiers
                    foreach ($step->dsl['remove_attributes'] as $attribute) {
                        $existingFieldDefinition = $this->contentTypeHasFieldDefinition($contentType, $attribute);
                        if ($existingFieldDefinition) {
                            $contentTypeService->removeFieldDefinition($contentTypeDraft, $existingFieldDefinition);
                        }
                        /// @todo log a warning if the specified field is not present
                    }
                }
            }

            $contentTypeService->updateContentTypeDraft($contentTypeDraft, $contentTypeUpdateStruct);
            $contentTypeService->publishContentTypeDraft($contentTypeDraft);

            if (isset($step->dsl['content_type_group'])) {
                $this->setContentTypeGroup($contentType, $step->dsl['content_type_group']);
            }

            if (isset($step->dsl['remove_content_type_group'])) {
                $this->unsetContentTypeGroup($contentType, $step->dsl['remove_content_type_group']);
            }

            // Set references
            if ($newIdentifier !== null) {
                $contentType = $contentTypeService->loadContentTypeByIdentifier($newIdentifier);
            } else {
                $contentType = $contentTypeService->loadContentTypeByIdentifier($contentTypeDraft->identifier);
            }

            $contentTypeCollection[$key] = $contentType;
        }

        $this->setReferences($contentTypeCollection, $step);

        return $contentTypeCollection;
    }
278496
public static RedirectionAction buildFormPostContentAction(final WebContext context, final String content) {
        if (ContextHelper.isPost(context) && useModernHttpCodes) {
            return new TemporaryRedirectAction(content);
        } else {
            return new OkAction(content);
        }
    }
199974
public static function onPrerenderContent(Event $event)
    {
        $dispatcher = $event->getDispatcher();
        if (null === $application = $dispatcher->getApplication()) {
            return;
        }
        if (null === $token = $application->getBBUserToken()) {
            return;
        }

        $renderer = $event->getEventArgs();
        if (!is_a($renderer, 'BackBee\Renderer\AbstractRenderer')) {
            return;
        }

        $content = $renderer->getObject();
        if (!is_a($content, 'BackBee\ClassContent\AbstractClassContent')) {
            return;
        }

        $em = $application->getEntityManager();
        if (null !== $revision = $em->getRepository('BackBee\ClassContent\Revision')->getDraft($content, $token)) {
            $content->setDraft($revision);
            $application->debug(sprintf(
                'Revision found for `%s` content and `%s` user',
                $content->getUid(),
                $token->getUsername()
            ));
        }

        if (!($content instanceof ContentSet)) {
            foreach ($content->getData() as $key => $subcontent) {
                if (null === $subcontent) {
                    $contenttype = $content->getAcceptedType($key);
                    if (0 === strpos($contenttype, 'BackBee\ClassContent\\')) {
                        if (null === $content->getDraft()) {
                            $revision = $em
                                ->getRepository('BackBee\ClassContent\Revision')
                                ->getDraft($content, $token, true)
                            ;
                            $content->setDraft($revision);
                        }
                        $content->$key = new $contenttype();
                    }
                }
            }
        }
    }
209084
public function revert_to_draft($userid) {
        global $DB, $USER;

        // Need grade permission.
        require_capability('mod/assign:grade', $this->context);

        if ($this->get_instance()->teamsubmission) {
            $submission = $this->get_group_submission($userid, 0, false);
        } else {
            $submission = $this->get_user_submission($userid, false);
        }

        if (!$submission) {
            return false;
        }
        $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
        $this->update_submission($submission, $userid, false, $this->get_instance()->teamsubmission);

        // Give each submission plugin a chance to process the reverting to draft.
        $plugins = $this->get_submission_plugins();
        foreach ($plugins as $plugin) {
            if ($plugin->is_enabled() && $plugin->is_visible()) {
                $plugin->revert_to_draft($submission);
            }
        }
        // Update the modified time on the grade (grader modified).
        $grade = $this->get_user_grade($userid, true);
        $grade->grader = $USER->id;
        $this->update_grade($grade);

        $completion = new completion_info($this->get_course());
        if ($completion->is_enabled($this->get_course_module()) &&
                $this->get_instance()->completionsubmit) {
            $completion->update_state($this->get_course_module(), COMPLETION_INCOMPLETE, $userid);
        }
        \mod_assign\event\submission_status_updated::create_from_submission($this, $submission)->trigger();
        return true;
    }
1197626
protected function setRevNum($revNum)
    {
        if (!is_numeric($revNum)) {
            throw new InvalidArgumentException(sprintf(
                'Revision must be an integer, received %s.',
                (is_object($revNum) ? get_class($revNum) : gettype($revNum))
            ));
        }

        $this->revNum = (int)$revNum;

        return $this;
    }
969872
public function deleteRevision($contentId, $revisionId)
    {
        $this->loadModel('Content.ContentRevisions');
        $revision = $this->ContentRevisions->find()
            ->where(['id' => $revisionId, 'content_id' => $contentId])
            ->first();

        if ($this->ContentRevisions->delete($revision, ['atomic' => true])) {
            $this->Flash->success(__d('content', 'Revision was successfully removed!'));
        } else {
            $this->Flash->danger(__d('content', 'Unable to remove this revision, please try again.'));
        }

        $this->title(__d('content', 'Editing Content Revision'));
        $this->redirect($this->referer());
    }
374422
private function executePlainRendering($content, $data)
    {
        $this->obFlushAndStar();

        extract($data);

        $filename = $this->createTmpFile($content);

        require $filename;

        @unlink($filename);

        return $this->obGetContent();
    }
649075
@Override
	protected Revision readRevision()
		throws IOException, ArticleReaderException
	{

		Revision rev = super.readRevision();
		this.readRevisionCounter++;
		return rev;
	}
1332694
public function reset($data = null, $instance = false)
    {
        if (!is_null($data)) {
            $this->_baseContents = $data;
        }

        if ($instance) {
            $self = new self();
            $self->collect($this->_baseContents);

            return $self;
        }

        $this->_map = $this->_baseContents;
        $this->reProcess();

        return $this;
    }
1124826
public function revert(AbstractClassContent $content, array $data = [])
    {
        if (0 === count($data)) {
            $data['parameters'] = array_keys($content->getAllParams());
            if ($content instanceof ContentSet) {
                $data['elements'] = true;
            } else {
                $data['elements'] = array_keys($content->getData());
            }
        }

        if (!isset($data['parameters']) && !isset($data['elements'])) {
            throw new \InvalidArgumentException('Provided data are not valids for ClassContentManager::revert.');
        }

        if (null === $draft = $this->getDraft($content)) {
            throw new InvalidArgumentException(sprintf(
                '%s with identifier "%s" has not draft, nothing to revert.',
                $content->getContentType(),
                $content->getUid()
            ));
        }

        $this->executeRevert($content, $draft, $data);
        $this->revertPostProcess($content, $draft);

        return $this;
    }
1192575
public function find($id, $draft = false)
    {
        if ($draft) {
            $this->setDraftVersionFilter(! $draft);
        }

        $block = $this->getRepository()->find($id);

        if ($draft) {
            if (null !== $revision = $this->revisionManager->getDraftRevision($block)) {
                $this->revisionManager->revert($block, $revision);
            }
        }

        return $block;
    }
1116970
@Override
    @InterfaceAudience.Private
    protected void processInbox(final RevisionList changes) {

        Log.v(TAG, "processInbox() changes=" + changes.size());

        // Generate a set of doc/rev IDs in the JSON format that _revs_diff wants:
        // <http://wiki.apache.org/couchdb/HttpPostRevsDiff>
        Map<String, List<String>> diffs = new HashMap<String, List<String>>();
        for (RevisionInternal rev : changes) {
            String docID = rev.getDocID();
            List<String> revs = diffs.get(docID);
            if (revs == null) {
                revs = new ArrayList<String>();
                diffs.put(docID, revs);
            }
            revs.add(rev.getRevID());
            addPending(rev);
        }

        // Call _revs_diff on the target db:
        Log.v(TAG, "%s: posting to /_revs_diff", this);

        CustomFuture future = sendAsyncRequest("POST", "_revs_diff", diffs, new RemoteRequestCompletion() {

            @Override
            public void onCompletion(RemoteRequest remoteRequest, Response httpResponse, Object response, Throwable e) {

                Log.v(TAG, "%s: got /_revs_diff response", this);
                Map<String, Object> results = (Map<String, Object>) response;
                if (e != null) {
                    setError(e);
                } else {
                    if (results.size() != 0) {
                        // Go through the list of local changes again, selecting the ones the destination server
                        // said were missing and mapping them to a JSON dictionary in the form _bulk_docs wants:
                        List<Object> docsToSend = new ArrayList<Object>();
                        RevisionList revsToSend = new RevisionList();
                        long bufferedSize = 0;
                        for (RevisionInternal rev : changes) {
                            // Is this revision in the server's 'missing' list?
                            Map<String, Object> properties = null;
                            Map<String, Object> revResults = (Map<String, Object>) results.get(rev.getDocID());
                            if (revResults == null) {
                                removePending(rev);
                                continue;
                            }
                            List<String> revs = (List<String>) revResults.get("missing");
                            if (revs == null || !revs.contains(rev.getRevID())) {
                                removePending(rev);
                                continue;
                            }

                            // NOTE: force to load body by Database.loadRevisionBody()
                            // In SQLiteStore.loadRevisionBody() does not load data from database
                            // if sequence != 0 && body != null
                            rev.setSequence(0);
                            rev.setBody(null);

                            RevisionInternal loadedRev;
                            try {
                                loadedRev = db.loadRevisionBody(rev);
                            } catch (CouchbaseLiteException e1) {
                                Log.w(TAG, "%s Couldn't get local contents of %s", rev, PusherInternal.this);
                                continue;
                            }

                            if (loadedRev.getPropertyForKey("_removed") != null &&
                                    ((Boolean) loadedRev.getPropertyForKey("_removed")).booleanValue()) {
                                // Filter out _removed revision:
                                removePending(rev);
                                continue;
                            }

                            RevisionInternal populatedRev = transformRevision(loadedRev);

                            List<String> possibleAncestors = (List<String>) revResults.get("possible_ancestors");

                            properties = new HashMap<String, Object>(populatedRev.getProperties());
                            Map<String, Object> revisions = db.getRevisionHistoryDictStartingFromAnyAncestor(populatedRev, possibleAncestors);
                            properties.put("_revisions", revisions);
                            populatedRev.setProperties(properties);

                            // Strip any attachments already known to the target db:
                            if (properties.containsKey("_attachments")) {
                                // Look for the latest common ancestor and stub out older attachments:
                                int minRevPos = findCommonAncestor(populatedRev, possibleAncestors);

                                Status status = new Status(Status.OK);
                                if (!db.expandAttachments(populatedRev, minRevPos + 1, !dontSendMultipart, false, status)) {
                                    Log.w(TAG, "%s: Couldn't expand attachments of %s", this, populatedRev);
                                    continue;
                                }

                                properties = populatedRev.getProperties();
                                if (!dontSendMultipart && uploadMultipartRevision(populatedRev)) {
                                    continue;
                                }
                            }

                            if (properties == null || !properties.containsKey("_id")) {
                                throw new IllegalStateException("properties must contain a document _id");
                            }

                            revsToSend.add(rev);
                            docsToSend.add(properties);

                            bufferedSize += JSONUtils.estimate(properties);
                            if (bufferedSize > kMaxBulkDocsObjectSize) {
                                uploadBulkDocs(docsToSend, revsToSend);
                                docsToSend = new ArrayList<Object>();
                                revsToSend = new RevisionList();
                                bufferedSize = 0;
                            }
                        }

                        // Post the revisions to the destination:
                        uploadBulkDocs(docsToSend, revsToSend);

                    } else {
                        // None of the revisions are new to the remote
                        for (RevisionInternal revisionInternal : changes) {
                            removePending(revisionInternal);
                        }
                    }
                }
            }

        });
        future.setQueue(pendingFutures);
        pendingFutures.add(future);
        pauseOrResume();
    }
913734
public function deleteContent(AbstractClassContent $content, $mainContent = true)
    {
        if (!$this->getEntityManager()->contains($content)) {
            // Ensure $content is managed
            $content = $this->getEntityManager()
                    ->getRepository(AbstractClassContent::getFullClassname($content))
                    ->find($content->getUid());
        }

        if (null === $content) {
            return;
        }

        $parents = $this->getParentContents($content);
        $media = $this->_em->getRepository('BackBee\NestedNode\Media')->findOneBy([
            '_content' => $content->getUid(),
        ]);

        if ((1 >= count($parents) && null === $media) || true === $mainContent) {
            foreach ($content->getData() as $element) {
                if ($element instanceof AbstractClassContent) {
                    $this->deleteContent($element, false);
                }
            }

            if ($content instanceof ContentSet) {
                $content->clear();
            }

            foreach ($parents as $parent) {
                if (
                    true === $mainContent
                    && !($parent instanceof ContentSet)
                    && !$this->_em->getUnitOfWork()->isScheduledForDelete($parent)
                ) {
                    foreach ($parent->getData() as $key => $element) {
                        if ($element instanceof AbstractClassContent && $element === $content) {
                            $classname = get_class($element);
                            $newContent = new $classname();
                            $this->_em->persist($newContent);
                            $parent->$key = $newContent;
                        }
                    }
                } else {
                    $parent->unsetSubContent($content);
                }
            }

            $this->cleanUpContentHardDelete($content);
            $this->_em->remove($content->setMainNode(null));
        }
    }