deblan.tv/vendor/trinity/src/Trinity/Bundle/ContentManagerBundle/Model/Page.php

443 lines
12 KiB
PHP

<?php
namespace Trinity\Bundle\ContentManagerBundle\Model;
use ZendSearch\Lucene\Document;
use ZendSearch\Lucene\Document\Field;
use Trinity\Bundle\ContentManagerBundle\Model\om\BasePage;
use Trinity\Bundle\ContentManagerBundle\Configuration\PageConfiguration;
use Trinity\Component\Utils\Propel;
use Trinity\Bundle\SearchBundle\Model\IndexableInterface;
class Page extends BasePage implements SeoPageInterface, IndexableInterface
{
protected $blocks = array();
protected $configuration = null;
protected $object = null;
protected $metaWords = array();
public function getConfiguration()
{
return $this->configuration;
}
protected function hasBlock($d)
{
return isset($this->blocks[is_object($d) ? $d->getName() : $d]);
}
public function setBlock(Block $block)
{
$block->setPageId($this->getId());
$this->blocks[$block->getName()] = $block;
return $this;
}
public function __construct($template = 'TrinityContentManagerBundle:Page:default.html.twig')
{
if ($template) {
$this->setTemplate($template);
}
parent::__construct();
$this->configuration = new PageConfiguration();
}
public function __toString()
{
$node = $this->getNode();
if (null === $node) {
return $this->name;
}
return $this->getNode()->getTitle();
}
public function getSeoTitle()
{
return $this->parsedWithObject($this->seo_title);
}
public function getMetaDescription()
{
return $this->parsedWithObject($this->meta_description);
}
public function getMetaKeywords()
{
return $this->parsedWithObject($this->meta_keywords);
}
public function getTemplating()
{
return $this->templating;
}
protected function parsedWithObject($string)
{
$object = $this->getObject();
if (!$object) {
return $string;
}
preg_match_all('`%([a-z]+)%`i', $string, $matches, PREG_SET_ORDER);
if (!$matches) {
return $string;
}
foreach ($matches as $match) {
$method = Propel::getGetter($match[1]);
if (method_exists($object, $method)) {
$string = str_replace($match[0], $object->$method(), $string);
}
}
return $string;
}
public function setTemplating($templating)
{
$this->templating = $templating;
return $this;
}
public function save(\PropelPDO $con = null)
{
parent::save($con);
if (!empty($this->blocks)) {
// Warning : do a duplicate save of blocks
foreach ($this->blocks as $block) {
$block->save();
}
} elseif ($this->getConfiguration()) {
foreach ($this->getConfiguration()->getBlocks() as $blockConfiguration) {
$this->getBlock($blockConfiguration->getName())->save($con);
}
}
return $this;
}
public function getBlock($name)
{
if (!$this->getId()) {
return $this->getNewBlock($name);
}
$qBlock = BlockQuery::create()->filterByName($name)->filterByPageId($this->getId())->findOne();
if ($qBlock) {
if (!$this->getConfiguration()->getBlock($name)) {
$block = $qBlock;
} else {
$type = $this->getConfiguration()->getBlock($name)->getType();
$form = new $type();
$formModel = $form->getOption('data_class') ? $form->getOption('data_class') : null;
if (null !== $formModel && !$qBlock instanceof $formModel) {
$block = $this->getNewBlock($name, $this->getId());
} else {
$block = $qBlock;
}
}
} else {
$block = $this->getNewBlock($name, $this->getId());
}
if (!$this->hasBlock($block->getName())) {
$this->setBlock($block);
}
return $block;
}
public function getBlockTitle()
{
return $this->getBlock('title');
}
public function getBlockSubtitle()
{
return $this->getBlock('subtitle');
}
public function getBlockContent()
{
return $this->getBlock('content');
}
public function setBlockTitle(Block $block)
{
return $this->setBlock($block);
}
public function setBlockSubtitle(Block $block)
{
return $this->setBlock($block);
}
public function setBlockContent(Block $block)
{
return $this->setBlock($block);
}
protected function getNewBlock($name, $pageId = null)
{
$type = $this->getConfiguration()->getBlock($name)->getType();
$form = new $type();
$formModel = $form->getOption('data_class') ? $form->getOption('data_class') : 'Trinity\Bundle\ContentManagerBundle\Model\Block';
$block = new $formModel();
$block
->setname($name)
->setClassKey($formModel);
if (null !== $pageId) {
$block->setPageId($pageId);
}
return $block;
}
public function isOrphan()
{
if (!$this->getId()) {
return true;
}
return NodeQuery::create()->findByPageId($this->getId())->count() ? false : true;
}
/**
* @return null|Node
*/
public function getNode()
{
if ($this->isOrphan()) {
return null;
}
return NodeQuery::create()->findOneByPageId($this->getId());
}
public function setObject($object)
{
$this->object = $object;
return $this;
}
public function getObject()
{
if (!$this->object) {
if ($this->getDataModel() && $this->getDataModelId()) {
$query = \PropelQuery::from($this->getDataModel());
if ($query) {
$this->object = $query->findPk($this->getDataModelId());
}
}
}
return $this->object;
}
/**
* @return string
*/
public function getIndexKey()
{
return 'cms_page_' . $this->getId();
}
/**
* @param $locale
* @return Document
*/
public function getLuceneDocument($locale)
{
if (!$this->getNode()) {
return null; // this page is orphan
}
// TODO: should we check for visible status ?
if (!$this->getNode()->isAccessible()) {
return null; // data isn't accessible
}
$document = new Document();
$nav = $this->getNode()->getNav();
if ($nav->getCulture() != $locale && $nav->getName() != $locale) {
return null;
}
$document->addField(Field::keyword('pk', 'cms_page_' . $this->getId()));
$document->addField(Field::keyword('model', 'Page'));
$document->addField(Field::keyword('nav', 'nav_' . $nav->getId()));
$document->addField($this->generateField('meta_title', $this->getSeoTitle(), 3));
$document->addField($this->generateField('meta_description', $this->getMetaDescription(), 3));
$content = '';
$blocksConfiguration = $this->getConfiguration()->getBlocks();
foreach ($this->getBlocks() as $block) {
if (array_key_exists($block->getName(),
$blocksConfiguration) && $block->getClassKey() == 'Trinity\Bundle\ContentManagerBundle\Block\TextBlock'
) {
switch ($block->getName()) {
case 'title':
$document->addField($this->generateField('title', $block->getValue(), 3));
break;
case 'subtitle':
$document->addField($this->generateField('subtitle', $block->getValue(), 3));
break;
case 'description':
$document->addField($this->generateField('description', $block->getValue(), 2));
break;
case 'resume':
$document->addField($this->generateField('resume', $block->getValue(), 2));
break;
case 'excerpt':
$document->addField($this->generateField('excerpt', $block->getValue(), 2));
break;
default:
$content .= $block->getValue() . ' ';
break;
}
}
}
$document->addField($this->generateField('content', $content, null, 'unstored'));
return $document;
}
private function generateField($name, $content, $boost = null, $type = 'text')
{
$raw_content = $content;
$raw_content = filter_var(
$raw_content,
FILTER_CALLBACK,
array(
'options' => array(
'Trinity\Component\Utils\VarFilter',
'sanitize_text'
)
)
);
switch ($type) {
case 'text':
$field = Field::text($name, $raw_content, 'utf-8');
break;
case 'unstored':
$field = Field::unStored($name, $raw_content, 'utf-8');
break;
default:
$field = Field::text($name, $raw_content, 'utf-8');
break;
}
if ($boost && is_int($boost)) {
$field->boost = $boost;
}
return $field;
}
public function preSave(\PropelPDO $con = null)
{
if ($this->isColumnModified(PagePeer::CLASS_KEY) && $this->getClassKey()) {
try {
$class = new \ReflectionClass($this->getClassKey());
$constructor = $class->getConstructor();
$template = isset($constructor->getParameters()[0]) ? $constructor->getParameters()[0]->getDefaultValue() : null;
if ($template !== null) {
$this->setTemplate($template);
}
} catch (\ReflectionException $e) {
throw new \RuntimeException('Invalid class_key.');
}
}
return parent::preSave($con);
}
public function setMetaWords(array $metaWords)
{
$this->metaWords = $metaWords;
return $this;
}
public function getMetaWords()
{
if ($class = $this->getDataModel()) {
$model = new $class();
$this->addMetaWordsByMap($model->getPeer()->getTableMap());
if (array_key_exists('i18n', $model->getPeer()->getTableMap()->getBehaviors())) {
$i18n_map = $model->getTranslation()->getPeer()->getTableMap();
$this->addMetaWordsByMap($model->getTranslation()->getPeer()->getTableMap());
}
}
return $this->metaWords;
}
public function addMetaWord($word)
{
$word = '%' . trim($word, '%') . '%';
if (!in_array($word, $this->metaWords)) {
$this->metaWords[] = $word;
}
return $this;
}
public function addMetaWordsByMap($map)
{
$behaviors = $map->getBehaviors();
$forbiddenWords = array('slug', 'locale');
foreach ($map->getColumns() as $column) {
if ($column->getType() != 'VARCHAR') {
continue;
}
if (array_key_exists('uploadable', $behaviors) && preg_match('`.*' . $column->getName() . '.*`',
$behaviors['uploadable']['fields'])
) {
continue;
}
if (in_array($column->getName(), $forbiddenWords)) {
continue;
}
$this->addMetaWord($column->getPhpName());
}
return $this;
}
}