<?php

class PolylangPolylangContentCopyProcessor extends modProcessor
{
    public $languageTopics = array('polylang:default');
    public $permission = 'polylang_localization_clone';
    /** @var Polylang $polylang */
    public $polylang;
    /** @var PolylangTools $tools */
    public $tools = null;
    /** @var  PolylangContent $source */
    public $source;

    public function initialize()
    {
        if (!$this->modx->hasPermission($this->permission)) {
            return $this->modx->lexicon('access_denied');
        }
        $initialized = parent::initialize();
        if ($initialized) {
            $id = $this->getProperty('id', 0);
            $this->source = $this->modx->getObject('PolylangContent', $id);
            if ($this->source) {
                $this->polylang = $this->modx->getService('polylang', 'Polylang');
                $this->tools = $this->polylang->getTools();
            } else {
                $initialized = $this->modx->lexicon('polylang_content_err_nf_localization', array('id' => $id));
            }
        }
        return $initialized;
    }

    public function process()
    {
        $languages = $this->getProperty('languages');
        if ($languages) {
            $field = $this->getProperty('field', '');
            if ($field) {
                $field = $this->prepareFieldName($field);
            }
            foreach ($languages as $key => $val) {
                if (!$val) continue;
                if (!$this->copy($key, $field)) {
                    $err = $this->modx->lexicon('polylang_content_err_save_copy', array('id' => $this->source->get('id')));
                    return $this->failure($err);
                }
            }
        }
        return $this->success();
    }

    /**
     * @param string $cultureKey
     * @param string $field
     *
     * @return bool
     */
    public function copy($cultureKey, $field = '')
    {
        $classes = $this->polylang->getTools()->getContentClasses();
        foreach ($classes as $class) {
            $isNew = false;
            if (!class_exists($class)) {
                $this->modx->loadClass($class);
            }
            $source = $this->modx->getObject($class, array(
                'culture_key' => $this->source->get('culture_key'),
                'content_id' => $this->source->get('content_id'),
            ));
            if ($source) {
                $criteria = array(
                    'culture_key' => $cultureKey,
                    'content_id' => $this->source->get('content_id'),
                );
                $target = $this->modx->getObject($class, $criteria);
                if (!$target) {
                    $isNew = true;
                    $target = $this->modx->newObject($class, $criteria);
                }
                if ($target) {
                    if ($class == 'PolylangContent') {
                        $source->loadTVs('tv');
                        $target->loadTVs('tv');
                    }
                    $data = $source->toArray();
                    unset($data['culture_key']);
                    if ($field) {
                        if (!isset($data[$field])) continue;
                        if (!$isNew) {
                            $data = array_merge($target->toArray(), array(
                                $field => $data[$field]
                            ));
                        }
                    }
                    $target->fromArray($data);
                    if (!$target->save()) {
                        $this->modx->log(modX::LOG_LEVEL_ERROR, "[{$class}] Error save copy localization. Data: " . print_r($data, 1));
                        return false;
                    }
                    if ($field) {
                        return true;
                    }
                }
            }
        }
        return true;
    }

    /**
     * @param string $field
     *
     * @return string
     */
    public function prepareFieldName($field)
    {
        $classes = $this->tools->getContentClasses();
        $classes['tvpolylang'] = 'PolylangContent';
        if (preg_match('/^([a-zA-Z0-9]+)(?=_)/', $field, $match)) {
            $classKey = $match[1];
            if (isset($classes[$classKey])) {
                $class = $classes[$classKey];
                if (!class_exists($class)) {
                    $this->modx->loadClass($class);
                }
                $prefix = $this->modx->call($class, 'getFieldPrefix', array($classKey));
                $field = $prefix . str_replace("{$classKey}_", '', $field);
            }
        }
        return rtrim($field, '[]');
    }
}

return 'PolylangPolylangContentCopyProcessor';