<?php

require_once(dirname(__FILE__) . '/fix.php');

use Acms\Services\Facades\Application;

class Import
{
    public $categoryRAM;
    public $entryRAM;
    public $moduleRAM;
    public $ruleRAM;
    public $columnRAM;
    public $userRAM;
    public $formRAM;
    public $commentRAM;
    public $scheduleRAM;
    public $layoutGridRAM;
    public $mediaRAM;
    public $configSetRAM;

    protected $UID;
    protected $BID;
    protected $CID;

    public $staticBID;
    public $parentRAM;
    /**
     * @var \Acms\Services\Entry\EntryRepository $entryRepository
     */
    protected $entryRepository;

    /**
     * Import constructor
     */
    public function __construct()
    {
        $this->entryRepository = Application::make('entry.repository');
    }

    protected function setRAM($fd, $old, $new)
    {
        switch ($fd) {
            case 'column':
                $this->columnRAM[$old] = $new;
                break;
            case 'entry':
                $this->entryRAM[$old] = $new;
                break;
            case 'category':
                $this->categoryRAM[$old] = $new;
                break;
            case 'rule':
                $this->ruleRAM[$old] = $new;
                break;
            case 'module':
                $this->moduleRAM[$old] = $new;
                break;
            case 'comment':
                $this->commentRAM[$old] = $new;
                break;
            case 'user':
                $this->userRAM[$old] = $new;
                break;
            case 'form':
                $this->formRAM[$old] = $new;
                break;
            case 'schedule':
                $this->scheduleRAM[$old] = $new;
                break;
            case 'media':
                $this->mediaRAM[$old] = $new;
                break;
            case 'config_set':
                $this->configSetRAM[$old] = $new;
                break;
        }
    }

    protected function getRAM($fd, $old)
    {
        $new = null;
        if (empty($old)) {
            return $new;
        }

        switch ($fd) {
            case 'column':
                if (isset($this->columnRAM[$old])) {
                    $new = $this->columnRAM[$old];
                }
                break;
            case 'entry':
                if (isset($this->entryRAM[$old])) {
                    $new = $this->entryRAM[$old];
                }
                break;
            case 'category':
                if (isset($this->categoryRAM[$old])) {
                    $new = $this->categoryRAM[$old];
                }
                break;
            case 'rule':
                if (isset($this->ruleRAM[$old])) {
                    $new = $this->ruleRAM[$old];
                }
                break;
            case 'module':
                if (isset($this->moduleRAM[$old])) {
                    $new = $this->moduleRAM[$old];
                }
                break;
            case 'comment':
                if (isset($this->commentRAM[$old])) {
                    $new = $this->commentRAM[$old];
                }
                break;
            case 'user':
                if (isset($this->userRAM[$old])) {
                    $new = $this->userRAM[$old];
                }
                break;
            case 'form':
                if (isset($this->formRAM[$old])) {
                    $new = $this->formRAM[$old];
                }
                break;
            case 'schedule':
                if (isset($this->scheduleRAM[$old])) {
                    $new = $this->scheduleRAM[$old];
                }
                break;
            case 'media':
                if (isset($this->mediaRAM[$old])) {
                    $new = $this->mediaRAM[$old];
                }
                break;
            case 'config_set':
                if (isset($this->configSetRAM[$old])) {
                    $new = $this->configSetRAM[$old];
                }
                break;
        }

        if (!empty($this->parentRAM) && empty($new)) {
            if (isset($this->parentRAM[$fd][$old])) {
                $new = $this->parentRAM[$fd][$old];
            }
        }
        if (empty($new)) {
            return $old;
        }

        return $new;
    }

    protected function fixPrimaryImage()
    {
        $DB = DB::singleton(dsn());
        if (is_array($this->entryRAM)) {
            foreach ($this->entryRAM as $old => $new) {
                $SQL = SQL::newSelect('entry');
                $SQL->addSelect('entry_primary_image');
                $SQL->addWhereOpr('entry_id', $new);
                $SQL->addWhereOpr('entry_blog_id', $this->BID);
                $primary = intval($DB->query($SQL->get(dsn()), 'one'));

                $SQL = SQL::newUpdate('entry');
                $SQL->addUpdate('entry_primary_image', $this->getRAM('column', $primary));
                $SQL->addWhereOpr('entry_id', $new);
                $SQL->addWhereOpr('entry_blog_id', $this->BID);
                $DB->query($SQL->get(dsn()), 'exec');
            }
        }
    }

    protected function fixShortcut(&$array)
    {
        if (is_array($array)) {
            $_array = [];
            foreach ($array as $row) {
                if ('shortcut' == substr($row['dashboard_key'], 0, 8)) {
                    $token  = explode('_', $row['dashboard_key']);
                    $id     = $token[1];
                    $num    = $token[2];

                    $index  = [
                        'bid' => 'blog',
                        'cid' => 'category',
                        'eid' => 'entry',
                        'rid' => 'rule',
                        'mid' => 'module',
                        'fmid' => 'form',
                        'scid' => 'schedule',
                    ];

                    $id = !empty($index[$id]) ? $index[$id] : $id;

                    if ($id === 'blog') {
                        $token[2] = $this->BID;
                        $row['dashboard_key'] = implode('_', $token);
                    } else {
                        $new = $this->getRAM($id, $num);
                        $token[2] = !empty($new) ? $new : $num;
                        $row['dashboard_key'] = implode('_', $token);
                    }
                }

                $_array[] = $row;
            }
            $array = $_array;
            unset($_array);
        }
    }

    protected function fixConfig(&$array)
    {
        if (is_array($array)) {
            $_array = [];
            foreach ($array as $row) {
                if (preg_match('/^schedule.*@(\d+)$/', $row['config_key'], $matches)) {
                    $new = $this->getRAM('schedule', $matches[1]);
                    $row['config_key'] = preg_replace('/\d+$/', $new, $row['config_key']);
                } elseif ($row['config_key'] === 'schedule_key') {
                    $row['config_value'] = $this->getRAM('schedule', $row['config_value']);
                } elseif ($row['config_key'] === 'media_banner_mid') {
                    $row['config_value'] = $this->getRAM('media', $row['config_value']);
                }
                $_array[] = $row;
            }
            $array = $_array;
            unset($_array);
        }
    }

    protected function fixArchivesLocation(&$array)
    {
        if (is_array($array)) {
            $_array = [];
            foreach ($array as $row) {
                if ($row['column_type'] === 'image' || $row['column_type'] === 'file') {
                    $loc = $row['column_field_2'];
                    if (!empty($loc)) {
                        $row['column_field_2'] = preg_replace('@^\d{3}/@', sprintf("%03d", $this->BID) . '/', $loc);
                    }
                }
                $_array[] = $row;
            }
            $array = $_array;
            unset($_array);
        }
    }

    protected function fixArchivesLocationFd(&$array)
    {
        if (is_array($array)) {
            $_array = [];
            foreach ($array as $row) {
                if (!!preg_match('/@path$/', $row['field_key'])) {
                    $loc = $row['field_value'];
                    if (!empty($loc)) {
                        $row['field_value'] = preg_replace('@^\d{3}/@', sprintf("%03d", $this->BID) . '/', $loc);
                    }
                }
                $_array[] = $row;
            }
            $array = $_array;
            unset($_array);
        }
    }

    protected function fixHalfSpace(&$array, $marker)
    {
        if (is_array($array) && !empty($marker)) {
            $marker = preg_replace('/(\.|\*|\+|\?|\^|\$|\(|\)|\{|\}|\[|\]|\\\|\|)/', '\\\$1', $marker);
            $_array = [];
            foreach ($array as $row) {
                if (!!preg_match('/^' . $marker . '/m', $row['column_field_1']) && 'text' === $row['column_type']) {
                    $fixed = preg_replace('/^' . $marker . '/m', '', $row['column_field_1']);
                    $row['column_field_1'] = $fixed;
                }
                $_array[] = $row;
            }
            $array = $_array;
            unset($_array);
        }
    }

    protected function fixCRLF($fd, &$array)
    {
        if (is_array($array)) {
            $_array = [];
            foreach ($array as $row) {
                if ($fd === 'fulltext') {
                    $row['fulltext_value'] = SetupCommon::fixCRLF($row['fulltext_value']);
                    $_array[] = $row;
                }
            }
            $array = $_array;
            unset($_array);
        }
    }

    protected function fixSort($fd, &$array)
    {
        if (is_array($array)) {
            $DB = DB::singleton(dsn());
            $SQL = SQL::newSelect($fd);
            $SQL->addSelect($fd . '_sort', 'max_sort', null, 'max');
            $SQL->addWhereOpr($fd . '_blog_id', $this->BID);
            $sort = intval($DB->query($SQL->get(dsn()), 'one')) + 1;

            $_array = [];
            foreach ($array as $row) {
                if (empty($row[$fd . '_parent'])) {
                    $row[$fd . '_sort'] = $sort++;
                }
                $_array[] = $row;
            }
            $array = $_array;
            unset($_array);
        }
    }

    protected function fixParent($fd)
    {
        $DB = DB::singleton(dsn());
        $RAM = null;
        switch ($fd) {
            case 'category':
                $RAM = $this->categoryRAM;
                break;
            case 'comment':
                $RAM = $this->commentRAM;
                break;
        }

        if (is_array($RAM)) {
            foreach ($RAM as $old => $new) {
                $SQL = SQL::newSelect($fd);
                $SQL->addSelect($fd . '_parent');
                $SQL->addWhereOpr($fd . '_id', $new);
                $SQL->addWhereOpr($fd . '_blog_id', $this->BID);
                $parent = intval($DB->query($SQL->get(dsn()), 'one'));

                $SQL = SQL::newUpdate($fd);
                $SQL->addUpdate($fd . '_parent', $this->getRAM($fd, $parent));
                $SQL->addWhereOpr($fd . '_id', $new);
                $SQL->addWhereOpr($fd . '_blog_id', $this->BID);
                $DB->query($SQL->get(dsn()), 'exec');
            }
        }
    }

    protected function initSeq()
    {
        $DB = DB::singleton(dsn());

        $SQL = SQL::newSelect('sequence');
        $row = $DB->query($SQL->get(dsn()), 'row');
        if (!empty($row)) {
            return true;
        } else {
            $SQL = SQL::newInsert('sequence');
            $seq = SetupCommon::getSequence();
            foreach ($seq as $key => $val) {
                $SQL->addInsert('sequence_' . $key, $val);
            }
            $res = $DB->query($SQL->get(dsn()), 'exec');
            if (!empty($res)) {
                return true;
            }
        }

        return false;
    }

    protected function generateUser($user)
    {
        $DB = DB::singleton(dsn());
        $this->UID = $DB->query(SQL::nextval('user_id', dsn()), 'seq');

        $SQL = SQL::newInsert('user');
        $SQL->addInsert('user_id', $this->UID);
        $SQL->addInsert('user_code', $user['code']);
        $SQL->addInsert('user_status', 'open');
        $SQL->addInsert('user_sort', '1');
        $SQL->addInsert('user_name', $user['name']);
        $SQL->addInsert('user_pass', acmsUserPasswordHash($user['pass']));
        $SQL->addInsert('user_pass_generation', PASSWORD_ALGORITHM_GENERATION);
        $SQL->addInsert('user_pass_reset', '');
        $SQL->addInsert('user_mail', $user['mail']);
        $SQL->addInsert('user_mail_magazine', 'on');
        $SQL->addInsert('user_mail_mobile', '');
        $SQL->addInsert('user_mail_mobile_magazine', 'on');
        $SQL->addInsert('user_url', '');
        $SQL->addInsert('user_auth', 'administrator');
        $SQL->addInsert('user_indexing', 'on');
        $SQL->addInsert('user_mode', 'debug');
        $SQL->addInsert('user_generated_datetime', date('Y-m-d H:i:s'));
        $SQL->addInsert('user_login_anywhere', 'on');
        $SQL->addInsert('user_login_expire', '9999-12-31');
        $SQL->addInsert('user_blog_id', $this->BID);
        $DB->query($SQL->get(dsn()), 'exec');

        $this->saveFulltext('uid', $this->UID, $this->loadUserFulltext($this->UID), $this->BID);
    }

    protected function generateBlog($blog)
    {
        $DB = DB::singleton(dsn());
        $this->BID = $blog['id'];

        /**
         * detect right, left, sort Numbers.
         */
        $SQL = SQL::newSelect('blog');
        $SQL->addSelect('blog_right');
        $SQL->addSelect('blog_sort');
        $SQL->addWhereOpr('blog_parent', $blog['parent']);
        $SQL->setOrder('blog_right', 'DESC');
        $SQL->setLimit(1);
        if ($row = $DB->query($SQL->get(dsn()), 'row')) {
            $left   = $row['blog_right'];
            $right  = $left + 1;
            $sort   = $row['blog_sort'] + 1;
        } else {
            $SQL = SQL::newSelect('blog');
            $SQL->addSelect('blog_right', 'blog_right_max', null, 'max');
            $max = $DB->query($SQL->get(dsn()), 'one');

            $left   = $max ? $max : 1;
            $right  = $left + 1;
            $sort   = 1;
        }

        /**
         * adjust blog align
         */
        $SQL = SQL::newUpdate('blog');
        $SQL->addUpdate('blog_left', SQL::newOpr('blog_left', 2, '+'));
        $SQL->addWhereOpr('blog_left', $left, '>');
        $DB->query($SQL->get(dsn()), 'exec');

        $SQL = SQL::newUpdate('blog');
        $SQL->addUpdate('blog_right', SQL::newOpr('blog_right', 2, '+'));
        $SQL->addWhereOpr('blog_right', $left, '>=');
        $DB->query($SQL->get(dsn()), 'exec');

        $bcd = explode('@', $blog['code']);
        /**
         * insert blog
         */
        $SQL = SQL::newInsert('blog');
        $SQL->addInsert('blog_id', $this->BID);
        $SQL->addInsert('blog_code', $bcd[0]);
        $SQL->addInsert('blog_status', 'open');
        $SQL->addInsert('blog_parent', $blog['parent']);
        $SQL->addInsert('blog_sort', $sort);
        $SQL->addInsert('blog_left', $left);
        $SQL->addInsert('blog_right', $right);
        $SQL->addInsert('blog_name', $blog['name']);
        $SQL->addInsert('blog_domain', $blog['domain']);
        $SQL->addInsert('blog_indexing', 'on');
        $SQL->addInsert('blog_generated_datetime', date('Y-m-d H:i:00'));
        $DB->query($SQL->get(dsn()), 'exec');

        return $this->BID;
    }

    protected function fixEntrySorts(&$record)
    {
        $old_u = $record['entry_user_id'];
        $old_c = $record['entry_category_id'];

        $UID = ($this->UID != null) ? $this->UID : $this->getRAM('user', $old_u);
        $CID = ($this->CID != null) ? $this->CID : $this->getRAM('category', $old_c);

        $record['entry_user_sort'] = $this->entryRepository->nextUserSort($UID, $this->BID);
        $record['entry_category_sort'] = $this->entryRepository->nextCategorySort($CID, $this->BID);
    }

    protected function fieldRotation($fd, $records)
    {
        /* adjust sorting id */
        $mediaFieldFix = [];

        $DB = DB::singleton(dsn());
        if (is_array($records) && !empty($records)) {
            while ($record = array_shift($records)) {
                if (!is_array($record)) {
                    continue;
                }

                /**
                 * fix entry sorts : このメソッドはすごく気に入らない
                 */
                if ($fd == 'entry') {
                    $this->fixEntrySorts($record);
                }

                $SQL = SQL::newInsert($fd);
                foreach ($record as $key => $val) {
                    $_key = substr($key, strlen($fd . '_'));

                    /**
                     * overload from RAM
                     */
                    if ($_key === 'user_id') {
                        $val = ($this->UID != null) ? $this->UID : $this->getRAM('user', $val);
                    }
                    if ($_key === 'blog_id') {
                        $val = $this->BID;
                    }
                    if ($_key === 'category_id') {
                        $val = ($this->CID != null) ? $this->CID : $this->getRAM('category', $val);
                    }
                    if ($_key === 'entry_id') {
                        $val = $this->getRAM('entry', $val);
                    }
                    if ($_key === 'rule_id') {
                        $val = $this->getRAM('rule', $val);
                    }
                    if ($_key === 'module_id') {
                        $val = $this->getRAM('module', $val);
                    }
                    if ($_key === 'set_id' || $_key === 'config_set_id' || $_key === 'theme_set_id' || $_key === 'editor_set_id') {
                        $val = $this->getRAM('config_set', $val);
                    }
                    if ($_key === 'media_id') {
                        $val = $this->getRAM('media', $val);
                    }
                    if ($fd === 'layout_grid' && $_key === 'mid') {
                        $val = $this->getRAM('module', $val);
                    }
                    if ($fd === 'field' && $_key === 'value' && preg_match('/@media$/', $record['field_key'])) {
                        $val = $this->getRAM('media', $val);
                        $mediaFieldFix[] = [
                            'name' => substr($record['field_key'], 0, -6),
                            'value' => $val,
                            'sort' => $record['field_sort'],
                            'eid' => $record['field_eid'],
                            'cid' => $record['field_cid'],
                            'uid' => $record['field_uid'],
                            'bid' => $record['field_bid'],
                            'mid' => $record['field_mid'],
                        ];
                    }
                    if ($fd === 'column' && $_key === 'field_1' && strncmp($record['column_type'], 'media', 5) === 0) {
                        $val = $this->getRAM('media', $val);
                    }
                    if ($fd === 'column' && $_key === 'field_1' && strncmp($record['column_type'], 'module', 6) === 0) {
                        $val = $this->getRAM('module', $val);
                    }
                    if ($fd === 'column' && $_key === 'field_6' && strncmp($record['column_type'], 'custom', 6) === 0) {
                        $data = acmsDangerUnserialize($val);
                        if ($data instanceof \Field && method_exists($data, 'listFields')) {
                            $fixMediaField = [];
                            foreach ($data->listFields() as $unitField) {
                                foreach ($data->getArray($unitField, true) as $i => $unitValue) {
                                    if (strpos($unitField, '@media') !== false) {
                                        $sourceFd = substr($unitField, 0, -6);
                                        if (!isset($fixMediaField[$sourceFd])) {
                                            $fixMediaField[$sourceFd] = [];
                                        }
                                        $unitValue = $this->getRAM('media', $unitValue);
                                        $fixMediaField[$sourceFd][] = $unitValue;
                                    } else {
                                        $unitValue = preg_replace(
                                            '@([\d]{3})/(.*)\.([^\.]{2,6})@ui',
                                            sprintf("%03d", $this->BID) . '/$2.$3',
                                            $unitValue,
                                            -1
                                        );
                                    }
                                    if ($i === 0) {
                                        $data->set($unitField, $unitValue);
                                    } else {
                                        $data->add($unitField, $unitValue);
                                    }
                                }
                            }
                            // fix media id
                            foreach ($fixMediaField as $mediaFieldName => $mediaIds) {
                                foreach ($mediaIds as $j => $mid) {
                                    if ($j === 0) {
                                        $data->set($mediaFieldName, $mid);
                                    } else {
                                        $data->add($mediaFieldName, $mid);
                                    }
                                }
                            }
                            $val = acmsSerialize($data);
                        }
                    }

                    /**
                     * fix rule & module & fulltext & field
                     */
                    if (
                        0
                        || $fd == 'rule'
                        || $fd == 'module'
                        || $fd == 'fulltext'
                        || $fd == 'field'
                    ) {
                        if (!empty($val)) {
                            if ($_key === 'bid') {
                                if ($fd === 'fulltext') {
                                    continue 2;
                                }
                                $val = ($fd === 'fulltext' || ($this->staticBID == true && $fd == 'module'))
                                        ? $val
                                        : $this->BID;
                            }
                            if ($_key === 'cid') {
                                $val = $this->getRAM('category', $val);
                            }
                            if ($_key === 'eid') {
                                $val = $this->getRAM('entry', $val);
                            }
                            if ($_key === 'uid') {
                                $val = ($this->UID != null) ? $this->UID : $this->getRAM('user', $val);
                            }
                            if ($_key === 'mid') {
                                $val = $this->getRAM('module', $val);
                            }
                        }
                    }

                    /**
                     * memory on RAM
                     */
                    if ($_key === 'id') {
                        $new = $DB->query(SQL::nextval($fd . '_id', dsn()), 'seq');
                        $old = $val;
                        $this->setRAM($fd, $old, $new);
                        $val = $new;
                    }

                    /**
                     * fix schedule's year and month
                     */
                    if ($key === 'schedule_month') {
                        $val = '00';
                    } elseif ($key === 'schedule_year') {
                        $val = '0000';
                    }

                    /**
                     * fix entry_summary_range variables. detected string is null or, int is zero.
                     */
                    if ($key === 'entry_summary_range') {
                        if (is_string($val)) {
                            $SQL->addInsert($key, strval(intval($val)));
                        } elseif (is_int($val)) {
                            $SQL->addInsert($key, strval($val));
                        }
                    } elseif (!empty($val)) {
                        $SQL->addInsert($key, strval($val));
                    } elseif ($val === 0) {
                        $SQL->addInsert($key, strval($val));
                    }
                }
                $DB->query($SQL->get(dsn()), 'exec');
            }
        }
        foreach ($mediaFieldFix as $data) {
            $SQL = SQL::newUpdate('field');
            $SQL->addUpdate('field_value', $data['value']);
            $SQL->addWhereOpr('field_key', $data['name']);
            $SQL->addWhereOpr('field_sort', $data['sort']);
            $SQL->addWhereOpr('field_bid', $data['bid']);
            $SQL->addWhereOpr('field_eid', $this->getRAM('entry', $data['eid']));
            $SQL->addWhereOpr('field_cid', $this->getRAM('category', $data['cid']));
            $SQL->addWhereOpr('field_uid', $this->getRAM('user', $data['uid']));
            $SQL->addWhereOpr('field_mid', $this->getRAM('module', $data['mid']));
            $DB->query($SQL->get(dsn()), 'exec');
        }
    }

    protected function generateFulltext()
    {
        $DB = DB::singleton(dsn());
        foreach (['category', 'entry'] as $type) {
            $SQL = SQL::newSelect($type);
            $SQL->addSelect($type . '_id');
            $SQL->addWhereOpr($type . '_blog_id', $this->BID);
            $all = $DB->query($SQL->get(dsn()), 'all');

            foreach ($all as $row) {
                $id = $row[$type . '_id'];
                switch ($type) {
                    case 'category':
                        $this->saveFulltext('cid', $id, $this->loadCategoryFulltext($id), $this->BID);
                        break;
                    case 'entry':
                        $this->saveFulltext('eid', $id, $this->loadEntryFulltext($id), $this->BID);
                        break;
                }
            }
        }
    }

    protected function updateBlogConfigSet($blog)
    {
        if (!isset($blog[0])) {
            return;
        }
        $blog = $blog[0];

        $sql = SQL::newUpdate('blog');
        if (isset($blog['blog_config_set_id'])) {
            $sql->addUpdate('blog_config_set_id', $this->getRAM('config_set', $blog['blog_config_set_id']));
        }
        if (isset($blog['blog_config_set_scope'])) {
            $sql->addUpdate('blog_config_set_scope', $blog['blog_config_set_scope']);
        }
        if (isset($blog['blog_theme_set_id'])) {
            $sql->addUpdate('blog_theme_set_id', $this->getRAM('config_set', $blog['blog_theme_set_id']));
        }
        if (isset($blog['blog_theme_set_scope'])) {
            $sql->addUpdate('blog_theme_set_scope', $blog['blog_theme_set_scope']);
        }
        if (isset($blog['blog_editor_set_id'])) {
            $sql->addUpdate('blog_editor_set_id', $this->getRAM('config_set', $blog['blog_editor_set_id']));
        }
        if (isset($blog['blog_editor_set_scope'])) {
            $sql->addUpdate('blog_editor_set_scope', $blog['blog_editor_set_scope']);
        }
        $sql->addWhereOpr('blog_id', $this->BID);
        DB::query($sql->get(dsn()), 'exec');
    }

    protected function loadEntryFulltext($eid)
    {
        return Common::loadEntryFulltext($eid);
    }

    protected function loadCategoryFulltext($cid)
    {
        return Common::loadCategoryFulltext($cid);
    }

    protected function loadUserFulltext($uid)
    {
        return Common::loadUserFulltext($uid);
    }

    protected function saveFulltext($type, $id, $fulltext = null, $bid = 1)
    {
        Common::saveFulltext($type, $id, $fulltext, $bid);
    }

    protected function deleteCategory()
    {
        $this->clearTable('category');
    }

    protected function deleteEntry()
    {
        $this->clearTable('entry');
    }

    protected function deleteColumn()
    {
        $this->clearTable('column');
    }

    protected function deleteComment()
    {
        $this->clearTable('comment');
    }

    protected function deleteTrackback()
    {
        $this->clearTable('trackback');
    }

    protected function deleteTag()
    {
        $this->clearTable('tag');
    }

    protected function deleteFulltext()
    {
        $this->clearTable('fulltext');
    }

    protected function deleteField()
    {
        $this->clearTable('field');
    }

    protected function deleteConfig()
    {
        $this->clearTable('config');
    }

    protected function deleteConfigSet()
    {
        $this->clearTable('config_set');
    }

    protected function deleteLayout()
    {
        $this->clearTable('layout_grid');
    }

    protected function deleteModule()
    {
        $this->clearTable('module');
    }

    protected function deleteRule()
    {
        $this->clearTable('rule');
    }

    protected function deleteDashboard()
    {
        $this->clearTable('dashboard');
    }

    protected function deleteSchedule()
    {
        $this->clearTable('schedule');
    }

    protected function deleteForm()
    {
        $this->clearTable('form');
    }

    protected function clearTable($fd)
    {
        $DB = DB::singleton(dsn());
        $SQL = SQL::newDelete($fd);
        if ($fd === 'fulltext') {
            $SQL->addWhereOpr($fd . '_bid', null, '<>');
        } else {
            $SQL->addWhereOpr($fd . '_blog_id', $this->BID);
        }
        $DB->query($SQL->get(dsn()), 'exec');
    }

    protected function insertUser($users)
    {
        $this->fieldRotation('user', $users);
    }

    protected function insertCategory($categories, $sort = true)
    {
        if ($sort) {
            $this->fixSort('category', $categories);
        }
        $this->fieldRotation('category', $categories);
        $this->fixParent('category');

        $Fix = new Fix_CategoryAlign(['bid' => $this->BID]);
        $Fix->execute();
    }

    protected function insertSubCategory($subCategory)
    {
        $this->fieldRotation('entry_sub_category', $subCategory);
    }

    protected function insertEntry($entries, $sort = true)
    {
        if ($sort) {
            $this->fixSort('entry', $entries);
        }
        $this->fieldRotation('entry', $entries);
    }

    protected function insertColumn($columns, $marker = null)
    {
        $this->fixHalfSpace($columns, $marker);
        $this->fieldRotation('column', $columns);
    }

    protected function insertTrackback($trackbacks)
    {
        $this->fieldRotation('trackback', $trackbacks);
    }

    protected function insertTag($tags)
    {
        $this->fieldRotation('tag', $tags);
    }

    protected function insertComment($comments)
    {
        $this->fieldRotation('comment', $comments);
        $this->fixParent('comment');
        $Fix = new Fix_CommentAlign(['bid' => $this->BID]);
        $Fix->execute();
    }

    protected function insertFulltext($fulltexts)
    {
        $this->fixCRLF('fulltext', $fulltexts);
        $this->fieldRotation('fulltext', $fulltexts);
    }

    protected function insertModule($modules)
    {
        $this->fieldRotation('module', $modules);
    }

    protected function insertRule($rules)
    {
        $this->fixSort('rule', $rules);
        $this->fieldRotation('rule', $rules);
    }

    protected function insertConfigSet($configs)
    {
        $this->fieldRotation('config_set', $configs);
    }

    protected function insertMedia($medias)
    {
        $this->fieldRotation('media', $medias);
    }

    protected function insertMediaTag($mediaTags)
    {
        $this->fieldRotation('media_tag', $mediaTags);
    }

    protected function insertGeo($geo)
    {
        $this->fieldRotation('geo', $geo);
    }

    protected function insertConfig($configs)
    {
        $this->fixConfig($configs);
        $this->fieldRotation('config', $configs);
    }

    protected function insertLayout($layout)
    {
        $this->fieldRotation('layout_grid', $layout);
    }

    protected function insertForm($forms)
    {
        $this->fieldRotation('form', $forms);
    }

    protected function insertSchedule($schedules)
    {
        $this->fieldRotation('schedule', $schedules);
    }

    protected function insertDashboard($dashboards)
    {
        $this->fixShortcut($dashboards);
        $this->fixSort('dashboard', $dashboards);
        $this->fieldRotation('dashboard', $dashboards);
    }

    protected function insertField($fields)
    {
        $this->fieldRotation('field', $fields);
    }

    protected function copyArchives($from, $to)
    {
        if (!Storage::isDirectory($from)) {
            return true;
        }

        $from = SetupCommon::fixPathSeparator($from);
        $to = SetupCommon::fixPathSeparator($to);

        try {
            Storage::copyDirectory($from, $to);
        } catch (\Exception $e) {
        }
    }

    protected function copyThemes($from, $to)
    {
        if (!Storage::isDirectory($from)) {
            return true;
        }

        $from = SetupCommon::fixPathSeparator($from);
        $to = SetupCommon::fixPathSeparator($to);

        try {
            Storage::copyDirectory($from, $to);
        } catch (\Exception $e) {
        }
    }

    protected function fixArchivesBlogNum($from)
    {
        $res = false;
        $i = 1;
        $new = $from . sprintf("%03d", $this->BID);

        do {
            $old = $from . sprintf("%03d", $i);
            if (Storage::exists($old)) {
                Storage::changeMod($old, 0777);
                $res = Storage::move($old, $new);
            } else {
                $i++;
            }
        } while ($res === false);
    }
}
