<?php

class PolylangPolylangContentUpdateProcessor extends modObjectUpdateProcessor
{
    public $classKey = 'PolylangContent';
    public $languageTopics = array('polylang:default');
    public $beforeSaveEvent = 'OnBeforeSavePolylangContent';
    public $afterSaveEvent = 'OnSavePolylangContent';
    public $permission = 'polylang_localization_save';
    /** @var Polylang $polylang */
    public $polylang;
    /** @var PolylangTools $tools */
    public $tools;

    public function initialize()
    {
        if (!$this->modx->hasPermission($this->permission)) {
            return $this->modx->lexicon('access_denied');
        }
        $this->polylang = $this->modx->getService('polylang', 'Polylang');
        $this->tools = $this->polylang->getTools();
        return parent::initialize();
    }

    /**
     * @return array|string
     */
    public function beforeSet()
    {
        $canSet = parent::beforeSet();
        if ($canSet) {
            $properties = array('foreign_properties' => array());
            $classes = $this->tools->getContentClasses();
            $classes['tvpolylang'] = 'PolylangContent';
            $data = $this->getProperties();
            $contentId = $this->modx->getOption('polylangcontent_content_id', $data);
            $cultureKey = $this->modx->getOption('polylangcontent_culture_key', $data);
            foreach ($data as $key => $value) {
                if (preg_match('/^([a-zA-Z0-9]+)(?=_)/', $key, $match)) {
                    $classKey = $match[1];
                    if (isset($classes[$classKey])) {
                        $class = $classes[$classKey];
                        $prefix = $this->modx->call($class, 'getFieldPrefix', array($classKey));
                        $key = $prefix . str_replace("{$classKey}_", '', $key);
                        if ($class == $this->classKey) {
                            $properties[$key] = $value;
                        } else {
                            if (!isset($properties['foreign_properties'][$class])) {
                                $properties['foreign_properties'][$class] = array(
                                    'content_id' => $contentId,
                                    'culture_key' => $cultureKey,
                                );
                            }
                            $properties['foreign_properties'][$class][$key] = $value;
                        }
                    }
                }
            }

            $this->setProperties($properties);
            $this->setProperty('editedon', time());
            $this->setProperty('editedby', $this->modx->user->id);
        }
        return $canSet;
    }


    public function afterSave()
    {
        $canSave = parent::afterSave();

        if ($canSave) {
            $this->object->saveTVs();
            $properties = $this->getProperty('foreign_properties', array());
            $autocreateDependentLanguages = $this->getProperty('dependent_languages', 0);
            if ($properties) {
                foreach ($properties as $class => $data) {
                    /** @var xPDOSimpleObject $o */
                    $q = $this->modx->newQuery($class);
                    $q->where(array(
                        'content_id' => $data['content_id'],
                        'culture_key' => $data['culture_key']
                    ));
                    if (!$o = $this->modx->getObject($class, $q)) {
                        $o = $this->modx->newObject($class);
                    }
                    $o->fromArray($data);
                    if (!$o->save()) {
                        $this->modx->log(modX::LOG_LEVEL_ERROR, "Error save data for class {$class}. Data:\n" . print_r($data, 1));
                    }
                }
            }
            if ($autocreateDependentLanguages) {
                $cultureKey = $this->object->get('culture_key');
                $dependentLanguages = $this->tools->getDependentLanguages($cultureKey);
                if ($dependentLanguages) {
                    $this->setProperty('dependent_languages', 0);
                    $errors = array();
                    foreach ($dependentLanguages as $language) {
                        $this->setProperty('polylangcontent_culture_key', $language['culture_key']);
                        $localization = $this->modx->getObject($this->classKey, array(
                            'content_id' => $this->object->get('content_id'),
                            'culture_key' => $language['culture_key']
                        ));
                        if (!$localization) {
                            $action = 'create';
                        } else {
                            $this->setProperty('id', $localization->get('id'));
                            $action = 'update';
                        }
                        /** @var modProcessorResponse $response */
                        $response = $this->polylang->runProcessor('mgr/polylangcontent/' . $action, $this->getProperties());
                        if ($response->isError()) {
                            $errors[] = $response->getMessage();
                        }
                    }
                    if (!empty($errors)) {
                        $this->modx->log(modX::LOG_LEVEL_ERROR, print_r($errors, 1));
                        $canSave = false;
                    }
                }
            }
        }
        if ($canSave) {
            $this->tools->clearCacheHasError404($this->object->get('content_id'), $this->object->get('culture_key'));
        }
        return $canSave;
    }

}

return 'PolylangPolylangContentUpdateProcessor';