<?php
namespace MultilingualBundle\EventListener;
use Pimcore\Event\Model\ElementEventInterface;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Event\Model\AssetEvent;
use Pimcore\Event\Model\DocumentEvent;
use Pimcore\Model\Asset;
use Pimcore\Model\Asset\Document;
use Pimcore\Tool;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class DocumentListener {
protected static $_tableName = 'plugin_multilingual_keys';
protected static $_tableDocumentTrans = 'documents_translations';
protected static $_tableDocumentElements = 'documents_editables';
private $dbMultiLang;
public function __construct(){
$container = \Pimcore::getContainer();
$this->dbMultiLang = $container->get('doctrine.dbal.default_connection');
}
public function createDocument (ElementEventInterface $e)
{
if($e instanceof DocumentEvent) {
// Check if this function is not in progress
if (\Pimcore\Cache\Runtime::isRegistered('Multilingual_add') && \Pimcore\Cache\Runtime::get('Multilingual_add') == 1) {
return;
}
// Lock this event-trigger
\Pimcore\Cache\Runtime::set('Multilingual_add', 1);
$doc = $e->getDocument();
if($doc->getParentId() != 1){ // TODO: check if this is site or subsite
// Get current language
// $sourceLanguage = $doc->getProperty('language');
$sourceParent = $doc->getParent();
$sourceLanguage = $sourceParent->getProperty('language');
$doc->setProperty("language",'text', $sourceLanguage, true, true);
$doc->save();
$sourceHash = $doc->getFullPath();
$sourceDocId = $doc->getId();
// Add Link to other languages
$this->dbMultiLang->createQueryBuilder()
->insert(self::$_tableName)
->setValue('document_id', '?')
->setValue('language', '?')
->setValue('sourcePath', '?')
->setParameter(0, $doc->getId())
->setParameter(1, $sourceLanguage)
->setParameter(2, $sourceHash)
->execute();
// Create folders for each Language
$languages = Tool::getValidLanguages();
foreach ($languages as $language) {
if ($language != $sourceLanguage) {
// throw new NotFoundHttpException("Page found ". $sourceParent->getId(). ' & '.$language);
$targetParent = \MultilingualBundle\Document\Document::getDocumentInOtherLanguage($sourceParent, $language);
if ($targetParent) {
/** @var \Pimcore\Model\Document\Page $target */
$target = clone $doc;
// Reset ID (so it will create a new document)
$target->setId(null);
// Set new parent
$target->setParent($targetParent);
$languageTarget = $targetParent->getProperty("language");
$target->setProperty("language",'text', $languageTarget, false, true);
// Check if we can link a master document
$editableDocumentTypes = array('page', 'email', 'snippet');
if (in_array($doc->getType(), $editableDocumentTypes)) {
$target->setContentMasterDocument($doc);
}
// Save the new document
$target->save();
// Add Link to other languages
$this->dbMultiLang->createQueryBuilder()
->insert(self::$_tableName)
->setValue('document_id', '?')
->setValue('language', '?')
->setValue('sourcePath', '?')
->setParameter(0, $target->getId())
->setParameter(1, $language)
->setParameter(2, $sourceHash)
->execute();
// Connect to other lang
$this->dbMultiLang->createQueryBuilder()
->insert(self::$_tableDocumentTrans)
->setValue('id', '?')
->setValue('sourceId', '?')
->setValue('language', '?')
->setParameter(0, $target->getId())
->setParameter(1, $sourceDocId)
->setParameter(2, $language)
->execute();
// Remove elementlinks
$this->dbMultiLang->createQueryBuilder()
->delete(self::$_tableDocumentElements)
->where('documentId = '.$target->getId())
->execute();
}
}
}
}
// Unlock this event-trigger
\Pimcore\Cache\Runtime::set('Multilingual_add', 0);
}
}
public function deleteDocument (ElementEventInterface $e)
{
if($e instanceof DocumentEvent) {
// Check if this function is not in progress
if (\Pimcore\Cache\Runtime::isRegistered('Multilingual_delete') && \Pimcore\Cache\Runtime::get('Multilingual_delete') == 1) {
return;
}
// Lock this event-trigger
\Pimcore\Cache\Runtime::set('Multilingual_delete', 1);
$sourceDocument = $e->getDocument();
// Get current language
$sourceLanguage = $sourceDocument->getProperty('language');
// Remove document in each language
$languages = Tool::getValidLanguages();
foreach ($languages as $language) {
if ($language != $sourceLanguage) {
$target = \MultilingualBundle\Document\Document::getDocumentInOtherLanguage($sourceDocument, $language);
if ($target) {
// Remove link to other documents
$this->dbMultiLang->createQueryBuilder()
->delete(self::$_tableName)
->where('document_id = :docid')
->setParameter('docid', $target->getId())
->execute();
$target->delete();
}
}
}
// Remove link to other documents
$this->dbMultiLang->createQueryBuilder()
->delete(self::$_tableName)
->where('document_id = :docid')
->setParameter('docid', $sourceDocument->getId())
->execute();
// Remove connection to other lang
$this->dbMultiLang->createQueryBuilder()
->delete(self::$_tableDocumentTrans)
->where('sourceId = :docid')
->setParameter('docid', $sourceDocument->getId())
->execute();
// Unlock this event-trigger
\Pimcore\Cache\Runtime::set('Multilingual_delete', 0);
}
}
public function updateDocument (ElementEventInterface $e)
{
if ($e instanceof DocumentEvent) {
if ($e->hasArgument('saveVersionOnly') && $e->getArgument('saveVersionOnly')) {
return;
}
$sourceDocument = $e->getDocument();
if ($sourceDocument->getId() == 1) {
return;
}
// Check if this function is not in progress
if (\Pimcore\Cache\Runtime::isRegistered('Multilingual_' . __FUNCTION__) && \Pimcore\Cache\Runtime::get('Multilingual_' . __FUNCTION__) == 1) {
return;
}
// Lock this event-trigger
\Pimcore\Cache\Runtime::set('Multilingual_' . __FUNCTION__, 1);
// Get current language
// $sourceLanguage = $sourceDocument->getProperty('language');
$sourceParent = $sourceDocument->getParent();
if($sourceParent->getId() != 1){
// Fetch FullDocumentUrl Primary
$languages = Tool::getValidLanguages();
$primaryLanguage = $languages[0];
$sourceDocumentFullPathDoc = \MultilingualBundle\Document\Document::getDocumentInOtherLanguage($sourceDocument,$primaryLanguage);
if($sourceDocumentFullPathDoc){
$sourceDocumentFullPath = $sourceDocumentFullPathDoc->getFullPath();
}else{
$sourceDocumentFullPath = $sourceDocument->getFullPath();
}
// throw new NotFoundHttpException("Page found ". $sourceDocumentFullPath. ' & '.$primaryLanguage);
$sourceLanguage = $sourceParent->getProperty('language');
if($sourceLanguage != ''){
$sourceDocument->setProperty("language",'text', $sourceLanguage, false, true);
$sourceDocument->save();
// Get the Source Parent (we have to do it this way, due to a bug in Pimcore)
$sourceParent = \Pimcore\Model\Document::getById($sourceDocument->getParentId());
// Update each language
$languages = Tool::getValidLanguages();
foreach ($languages as $language) {
if ($language != $sourceLanguage) {
// Find the target document
/** @var Document $targetDocument */
$targetDocument = \MultilingualBundle\Document\Document::getDocumentInOtherLanguage($sourceDocument,$language);
if ($targetDocument) {
// Find the parent
// If the parent is the root, document, no need to do a lookup
if ($sourceParent->getId() == 1) {
$targetParent = $sourceParent;
} else {
$targetParent = \MultilingualBundle\Document\Document::getDocumentInOtherLanguage($sourceParent,$language);
}
// Only sync properties when it is allowed
if (!$targetDocument->hasProperty('doNotSyncProperties') && !$sourceDocument->hasProperty('doNotSyncProperties')) {
$typeHasChanged = false;
// Set document type (for conversion)
if ($targetDocument->getType() != $sourceDocument->getType()) {
$typeHasChanged = true;
$targetDocument->setType($sourceDocument->getType());
if ($targetDocument->getType() == "hardlink" || $targetDocument->getType() == "folder") {
// remove navigation settings
foreach ([
"name",
"title",
"target",
"exclude",
"class",
"anchor",
"parameters",
"relation",
"accesskey",
"tabindex"
] as $propertyName) {
$targetDocument->removeProperty("navigation_" . $propertyName);
}
}
\Pimcore\Cache\Runtime::set("document_" . $targetDocument->getId(), $targetDocument);
}
// Set the controller the same
$editableDocumentTypes = array('page', 'email', 'snippet');
if (!$typeHasChanged && in_array($sourceDocument->getType(), $editableDocumentTypes)) {
/** @var \Pimcore\Model\Document\Page $targetDocument */
$targetDocument->setController($sourceDocument->getController());
}
// Set the properties the same
// But only if they have not been added already
$sourceProperties = $sourceDocument->getProperties();
/** @var string $key
* @var Property $value
*/
foreach ($sourceProperties as $key => $value) {
if (strpos($key, 'navigation_') === false) {
if (!$targetDocument->hasProperty($key)) {
$propertyValue = $value->getData();
if ($value->getType() == 'document') {
$propertyValue = \MultilingualBundle\Document\Document::getDocumentIdInOtherLanguage(
$value->getData()->getId(),
$language
);
}
$targetDocument->setProperty(
$key,
$value->getType(),
$propertyValue,
false,
$value->getInheritable()
);
}
}
}
}
// Make sure the parent stays the same
$targetDocument->setParent($targetParent);
$targetDocument->setParentId($targetParent->getId());
$targetDocument->setPath($targetParent->getFullPath() . '/');
// Make sure the index stays the same
$targetDocument->setIndex($sourceDocument->getIndex());
// Make sure the index follows in all the pages at current level
$list = new \Pimcore\Model\Document\Listing();
$list->setCondition(
"parentId = ? AND id != ?",
array($targetParent->getId(), $sourceDocument->getId())
);
$list->setOrderKey("index");
$list->setOrder("asc");
$childsList = $list->load();
$count = 0;
/** @var Document $child */
foreach ($childsList as $child) {
if ($count == intval($targetDocument->getIndex())) {
$count++;
}
$child->saveIndex($count);
$count++;
}
$targetDocument->save();
// change url
$this->dbMultiLang->createQueryBuilder()
->update(self::$_tableName)
->set('sourcePath', ':docFullPath')
->where('document_id = :docId')
->setParameter('docFullPath', $sourceDocumentFullPath)
->setParameter('docId', $targetDocument->getId())
->execute();
}
}
}
}
// change url
$this->dbMultiLang->createQueryBuilder()
->update(self::$_tableName)
->set('sourcePath', ':docFullPath')
->where('document_id = :docId')
->setParameter('docFullPath', $sourceDocumentFullPath)
->setParameter('docId', $sourceDocument->getId())
->execute();
}
}
// Lock this event-trigger
\Pimcore\Cache\Runtime::set('Multilingual_' . __FUNCTION__, 0);
}
}