443 lines
12 KiB
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;
|
|
}
|
|
}
|