/** * Enables provided content by set its revision to 1 and * its state to 1001 (STATE_NORMAL) so it can be displayed in front. * * @param AbstractClassContent $content * @return self */ protected function enableContent(AbstractClassContent $content) { $content->setRevision(1)->setState(AbstractClassContent::STATE_NORMAL); foreach ($content->getData() as $element) { if ($element instanceof AbstractClassContent) { $this->enableContent($element); } } return $this; }
/** * Adds a subcontent to the colection. * * @param \BackBee\ClassContent\AbstractClassContent $value * @return string the unique identifier of the add subcontent * @codeCoverageIgnore */ protected function _addSubcontent(AbstractClassContent $value) { return $value->getUid(); }
/** * Returns every pages that contains provided classcontent. * * @param string $contentType * @param string $contentUid * * @return \Symfony\Component\HttpFoundation\Response */ private function doGetCollectionByContent($contentType, $contentUid) { $content = null; $classname = AbstractClassContent::getClassnameByContentType($contentType); $em = $this->getApplication()->getEntityManager(); try { $content = $em->find($classname, $contentUid); } catch (ClassNotFoundException $e) { throw new NotFoundHttpException("No classcontent found with provided type (:{$contentType})"); } if (null === $content) { throw new NotFoundHttpException("No `{$classname}` exists with uid `{$contentUid}`"); } $pages = $em->getRepository("BackBee\\ClassContent\\AbstractClassContent")->findPagesByContent($content); $response = $this->createResponse($this->formatCollection($pages)); if (0 < count($pages)) { $response->headers->set('Content-Range', '0-' . (count($pages) - 1) . '/' . count($pages)); } return $response; }
/** * @expectedException \InvalidArgumentException */ public function testIgnoreUnknownClassnameTrue() { AbstractClassContent::throwExceptionOnUnknownClassname(true); $this->content->mockedDefineData('unknown', '\\BackBee\\ClassContent\\UnknownClassname'); }
/** * {@inheritdoc} */ protected function defineParam($var, $options = null) { parent::defineParam($var, $options); if ('accept' === $var) { if (null !== $options) { $this->_addAcceptedType($this->getParamValue('accept')); } } return $this; }
/** * Updates states and revision number of the content. * * @param AbstractClassContent $content The content to be updated. * @param integer $revision Optional, the revision number (1 by default). * @param integer $state Optional, The state (STATE_NORMAL by default). * * @return PageBuilder The builder instance. * @codeCoverageIgnore */ private function updateContentRevision(AbstractClassContent $content, $revision = 1, $state = AbstractClassContent::STATE_NORMAL) { $content->setRevision((int) $revision); $content->setState((int) $state); return $this; }
public static function onPostCall(Event $event) { $response = $event->getResponse(); if ($response->headers->get('content-type') === 'text/html') { return; } $application = $event->getApplication(); $renderer = $application->getRenderer(); $content = json_decode($response->getContent()); $result = false; if ($content instanceof \StdClass) { if (isset($content->type) && isset($content->parameters)) { if (isset($content->parameters->rendermode)) { $result = true; } } } if (!$result) { return; } $rendermodeParam = $content->parameters->rendermode; $classname = AbstractClassContent::getClassnameByContentType($content->type); $modes = ['default' => 'Default mode']; foreach ($renderer->getAvailableRenderMode(new $classname()) as $mode) { $modes[$mode] = ucfirst(str_replace('_', ' ', $mode)); } $rendermodeParam->options = $modes; $response->setContent(json_encode($content)); }
/** * {@inheritdoc} */ protected function defineParam($var, $options = null) { parent::defineParam($var, $options); if ('accept' === $var) { if (null !== $options) { $accept = array_key_exists('value', $options) ? $options['value'] : $options; $this->_addAcceptedType(array_merge((array) $accept, $this->getParamValue('accept'))); } } return $this; }
/** * Update image with the new data * * @param AbstractClassContent|Revision $object * @param string $path * @param string $fullPath * * @return void */ protected function updateObject(&$object, $path, $fullPath) { $object->__set('path', $path); $object->setParam('width', $this->request->get('cropNewW')); $object->setParam('height', $this->request->get('cropNewH')); $object->setParam('stat', json_encode(stat($fullPath))); }
/** * Runs revert post action on content and its draft. * * @param AbstractClassContent $content * @param Revision $draft * * @return ClassContentManager */ private function revertPostProcess(AbstractClassContent $content, Revision $draft) { $data = $draft->jsonSerialize(); if (0 === count($data['parameters']) && ($content instanceof ContentSet && 0 === count($data['elements']['current']) && 0 === count($data['elements']['draft']) || 0 === count($data['elements']))) { $this->entityManager->remove($draft); if (AbstractClassContent::STATE_NEW === $content->getState()) { $this->entityManager->remove($content); } } return $this; }
/** * Auto commit content put or post in the library. * * @param AbstractClassContent $content */ private function autoCommitContent(AbstractClassContent $content) { // Commit subelement of the Media content foreach ($content->getData() as $subcontent) { if (!$subcontent instanceof AbstractClassContent) { continue; } $this->commit($subcontent); } // Commit the Media content itself $this->commit($content); }
/** * Occurs on event ``bbapplication.init`` to set AbstractContent::$ignoreUnknownClassname according to bbapp parameters. * * @param Event $event */ public static function onApplicationInit(Event $event) { $application = $event->getTarget(); $container = $application->getContainer(); if ($container->hasParameter('bbapp.classcontent.exception_on_unknown_classname')) { $parameter = $container->getParameter('bbapp.classcontent.exception_on_unknown_classname'); } else { $parameter = true; } if ('debug' === strtolower($parameter)) { AbstractClassContent::throwExceptionOnUnknownClassname($application->isDebugMode()); } else { AbstractClassContent::throwExceptionOnUnknownClassname($parameter); } }
public function mockedDefineParam($var, $options = null) { return parent::defineParam($var, $options); }
public function tryResolveParentObject(AbstractClassContent $parent, AbstractClassContent $element) { foreach ($parent->getData() as $key => $values) { if (!is_array($values)) { $values = array($values); } foreach ($values as $value) { if ($value instanceof AbstractClassContent) { if (!$value->isLoaded()) { // try to load subcontent if (null !== ($subcontent = $this->getApplication()->getEntityManager()->getRepository(\Symfony\Component\Security\Core\Util\ClassUtils::getRealClass($value))->load($value, $this->getRenderer()->getApplication()->getBBUserToken()))) { $value = $subcontent; } } if ($element->equals($value)) { $this->__currentelement = $key; $this->__object = $parent; $this->_parentuid = $parent->getUid(); } else { $this->tryResolveParentObject($value, $element); } } if (null !== $this->__currentelement) { break; } } if (null !== $this->__currentelement) { break; } } }
/** * Creates classcontent according to provided type. * * @param string $type * @param Request $request * * @return Symfony\Component\HttpFoundation\Response * * @Rest\Security("is_fully_authenticated() & has_role('ROLE_API_USER')") */ public function postAction($type, Request $request) { $classname = AbstractClassContent::getClassnameByContentType($type); $content = new $classname(); $this->granted('CREATE', $content); $this->getEntityManager()->persist($content); $content->setDraft($this->getClassContentManager()->getDraft($content, true)); $this->getEntityManager()->flush(); $data = $request->request->all(); if (0 < count($data)) { $data = array_merge($data, ['type' => $type, 'uid' => $content->getUid()]); $this->updateClassContent($type, $data['uid'], $data); $this->getEntityManager()->flush(); } return $this->createJsonResponse(null, 201, ['BB-RESOURCE-UID' => $content->getUid(), 'Location' => $this->getApplication()->getRouting()->getUrlByRouteName('bb.rest.classcontent.get', ['version' => $request->attributes->get('version'), 'type' => $type, 'uid' => $content->getUid()], '', false)]); }
/** * Resolves $content value. * * @param ContentSet $content * @param array $matches * * @return mixed */ private function resolveContentSet(ContentSet $content, array $matches) { if ('ContentSet' === $matches[1]) { return $content->item($matches[3]); } $index = intval($matches[3]); $classname = AbstractClassContent::getFullClassname(str_replace('/', NAMESPACE_SEPARATOR, $matches[1])); foreach ($content as $subcontent) { if (get_class($subcontent) !== $classname) { continue; } if (0 === $index) { return $subcontent; } $index--; } return $content; }
/** * Returns true if $key is a parameter name, false otherwise. * * @param string $key The parameter to be tested * * @return boolean */ public function hasParam($key) { return $this->_content->hasParam($key); }
/** * Runs revert post action on content and its draft. * * @param AbstractClassContent $content * @param Revision $draft * @return self */ private function revertPostProcess(AbstractClassContent $content, Revision $draft) { $data = $draft->jsonSerialize(); if (0 === count($data['parameters']) && 0 === count($data['elements'])) { $this->em->remove($draft); if (AbstractClassContent::STATE_NEW === $content->getState()) { $this->em->remove($content); } } }
/** * Returns classcontent if couple (type;uid) is valid. * * @param string $type short namespace of a classcontent * (full: BackBee\ClassContent\Block\paragraph => short: Block/paragraph) * @param string $uid * * @return AbstractClassContent */ public function findOneByTypeAndUid($type, $uid) { $content = null; $classname = AbstractClassContent::getClassnameByContentType($type); if (null === ($content = $this->findOneBy(['_uid' => $uid]))) { throw new \InvalidArgumentException(sprintf('No `%s` exists with uid `%s`.', $classname, $uid)); } return $content; }
/** * Update Status and revision value. * * @param \BackBee\ClassContent\AbstractClassContent $element * * @return AbstractConverterInterface */ protected function _updateRevision(AbstractClassContent $element) { $element->setRevision(1 + $element->getRevision())->setState(AbstractClassContent::STATE_NORMAL); return $this; }
/** * Removes stored site-content indexes for a content in a site. * * @param Site $site * @param AbstractClassContent $content * * @return IndexationRepository */ public function removeIdxSiteContent(Site $site, AbstractClassContent $content) { $query = 'DELETE FROM idx_site_content WHERE site_uid = :site AND (content_uid IN ' . '(SELECT content_uid FROM content_has_subcontent WHERE parent_uid = :content)' . 'OR content_uid = :content)'; $params = array('site' => $site->getUid(), 'content' => $content->getUid()); return $this->_executeQuery($query, $params); }
/** * Sets the layout for the page. * Adds as much ContentSet to the page main ContentSet than defined zones in layout. * * @param Layout $layout * @param AbstractClassContent $toPushInMainZone * * @return Page */ public function setLayout(Layout $layout, AbstractClassContent $toPushInMainZone = null) { $this->_layout = $layout; $count = count($layout->getZones()); // Add as much ContentSet to the page main ContentSet than defined zones in layout for ($i = $this->getContentSet()->count(); $i < $count; $i++) { // Do this case really exists ? if (null === ($zone = $layout->getZone($i))) { $this->getContentSet()->push(new ContentSet()); continue; } // Create a new column $contentset = new ContentSet(null, $zone->options); if (null !== $toPushInMainZone && true === $zone->mainZone) { // Existing content push in the main zone $contentset->push($toPushInMainZone->setMainNode($this)); } elseif ('inherited' === $zone->defaultClassContent) { // Inherited zone => same ContentSet than parent if exist $contentset = $this->getInheritedContent($i, $contentset); } elseif ($zone->defaultClassContent) { // New default content push $contentset->push($this->createNewDefaultContent('BackBee\\ClassContent\\' . $zone->defaultClassContent, $zone->mainZone)); } $this->getContentSet()->push($contentset); } return $this; }
/** * Build and/or hydrate Category object with provided classcontent. * * @param AbstractClassContent $content */ private function buildCategoryFromClassContent(AbstractClassContent $content) { foreach ((array) $content->getProperty('category') as $category) { $visible = true; if ('!' === $category[0]) { $visible = false; $category = substr($category, 1); } $id = $this->buildCategoryId($category); if (false === array_key_exists($id, $this->categories)) { $this->categories[$id] = new Category($category, $this->options); ksort($this->categories); } $this->categories[$id]->addBlock($content, $visible, $this->options); } }
/** * Unsets a subcontent to the current collection. * * @param \BackBee\ClassContent\AbstractClassContent $subContent * * @return \BackBee\ClassContent\AbstractClassContent */ public function unsetSubContent(AbstractClassContent $subContent) { foreach ($this->_data as $key => $value) { if (is_array($value)) { $totalContent = count($value); foreach ($value as $cKey => $cValue) { $contentUid = $cValue; if (is_array($cValue)) { $contentUid = array_values($cValue); $contentUid = end($contentUid); } if ($subContent->getUid() == $contentUid) { if (1 === $totalContent) { $this->_data[$key] = []; $this->_subcontent->removeElement($subContent); } else { unset($value[$cKey]); $this->_data[$key] = $value; } } } } } return $this; }
/** * Returns the vote for class content object, recursively till AbstractClassContent. * * @param \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token * @param \BackBee\ClassContent\AbstractClassContent $content * @param array $attributes * @return integer either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED */ private function voteForClassContent(TokenInterface $token, AbstractClassContent $content, array $attributes) { if (null === $content->getProperty('category')) { return self::ACCESS_GRANTED; } if (self::ACCESS_DENIED === ($result = $this->voteForObject($token, $content, $attributes))) { if (false !== ($parent_class = get_parent_class($content))) { if ('BackBee\\ClassContent\\AbstractClassContent' !== $parent_class) { $parent_class = NAMESPACE_SEPARATOR . $parent_class; $result = $this->voteForClassContent($token, new $parent_class('*'), $attributes); } else { $objectIdentity = new ObjectIdentity('all', 'BackBee\\ClassContent\\AbstractClassContent'); $result = parent::vote($token, $objectIdentity, $attributes); } } } return $result; }
/** * Deletes outdated keyword content joins. * * @param AbstractClassContent $content * @param mixed $keywords */ public function cleanKeywordLinks(AbstractClassContent $content, $keywords) { if (!is_array($keywords)) { $keywords = [$keywords]; } $keywordUids = []; foreach ($keywords as $keyword) { if ($keyword instanceof Keyword && !empty($keyword->value) && null !== ($realKeyword = $this->_em->find('BackBee\\NestedNode\\KeyWord', $keyword->value))) { $keywordUids[] = $realKeyword->getUid(); } } $query = $this->_em->getConnection()->createQueryBuilder()->select('c.keyword_uid')->from('keywords_contents', 'c'); $query->where($query->expr()->eq('c.content_uid', $query->expr()->literal($content->getUid()))); $savedKeywords = $query->execute()->fetchAll(\PDO::FETCH_COLUMN); $linksToBeRemoved = array_diff($savedKeywords, $keywordUids); if (count($linksToBeRemoved)) { $query = $this->_em->getConnection()->createQueryBuilder()->delete('keywords_contents'); array_walk($linksToBeRemoved, function (&$value, $key, $query) { $value = $query->expr()->literal($value); }, $query); $query->where($query->expr()->eq('content_uid', $query->expr()->literal($content->getUid())))->andWhere($query->expr()->in('keyword_uid', $linksToBeRemoved))->execute(); } }
/** * Update mainnode of the content if need during clonage. * * @param AbstractClassContent $content The cloned content. * @param array $cloningPages The cloned pages array. * @param BBUserToken|null $token Optional, the BBuser token to allow the update of revisions if set. * * @return PageRepository */ private function updateMainNodePostCloning(AbstractClassContent $content, array $cloningPages, BBUserToken $token = null) { $mainnode = $content->getMainNode(); if (null !== $mainnode && 0 < count($cloningPages) && true === in_array($mainnode->getUid(), array_keys($cloningPages))) { // Loading draft for content if (null !== $token && null !== ($draft = $this->_em->getRepository('BackBee\\ClassContent\\Revision')->getDraft($content, $token, true))) { $content->setDraft($draft); } $content->setMainNode($cloningPages[$mainnode->getUid()]); } return $this; }
/** * Runs revert post action on content and its draft. * * @param AbstractClassContent $content * @param Revision $draft * * @return ClassContentManager */ private function revertPostProcess(AbstractClassContent $content, Revision $draft) { $data = $draft->jsonSerialize(); if (0 === count($data['parameters']) && (0 === count($data['elements']) || $content instanceof ContentSet && $data['elements']['current'] === $data['elements']['draft'])) { if ($content instanceof ContentSet) { $draft->clear(); } if (AbstractClassContent::STATE_NEW === $content->getState()) { $classname = AbstractClassContent::getClassnameByContentType($content->getContentType()); $this->entityManager->getRepository($classname)->deleteContent($content); } else { $this->entityManager->remove($draft); } } return $this; }
/** * Return the user's draft of a content, optionally checks out a new one if not exists. * * @param AbstractClassContent $content * @param BBUserToken $token * @param boolean $checkoutOnMissing If true, checks out a new revision if none was found * * @return Revision|null */ public function getDraft(AbstractClassContent $content, BBUserToken $token, $checkoutOnMissing = false) { if (null === ($revision = $content->getDraft())) { try { if (false === $this->_em->contains($content)) { $content = $this->_em->find(get_class($content), $content->getUid()); if (null === $content) { return; } } $q = $this->createQueryBuilder('r')->andWhere('r._content = :content')->andWhere('r._owner = :owner')->andWhere('r._state IN (:states)')->orderBy('r._revision', 'desc')->orderBy('r._modified', 'desc')->setParameters(['content' => $content, 'owner' => '' . UserSecurityIdentity::fromToken($token), 'states' => [Revision::STATE_ADDED, Revision::STATE_MODIFIED, Revision::STATE_CONFLICTED]])->getQuery(); $revision = $q->getSingleResult(); } catch (\Exception $e) { if ($checkoutOnMissing) { $revision = $this->checkout($content, $token); $this->_em->persist($revision); } else { $revision = null; } } } return $revision; }
/** * Returns the indexed parameter value. * * @param AbstractClassContent $content The content flushed. * @param string $indexedParam The parameter to index. * * @return array An array of the parameter value and the content owner. */ private static function getParamValue(AbstractClassContent $content, $indexedParam) { $value = (array) $content->getParamValue($indexedParam); $owner = $content; return [implode(',', $value), $owner]; }