<?php

class Fix
{
    protected $args = [];

    public function __construct($args = [])
    {
        $this->args = $args;
    }
}

class Fix_BlogAlign extends Fix
{
    public function execute()
    {
        @set_time_limit(0);
        $DB = DB::singleton(dsn());

        $que = [0];    // FIFO
        $aryPid = [];
        while (true) {
            $pid = array_shift($que);

            $pos = 0;
            if (!empty($pid)) {
                $SQL = SQL::newSelect('blog');
                $SQL->addWhereOpr('blog_id', $pid);
                if (!!($row = $DB->query($SQL->get(dsn()), 'row'))) {
                    $pos = intval($row['blog_left']); // - 1;
                } else {
                    continue;
                }
            }

            $SQL = SQL::newSelect('blog');
            $SQL->setSelect('blog_id');
            $SQL->addWhereOpr('blog_parent', $pid);
            $SQL->setOrder('blog_sort');

            $cnt = 0;
            if (!!($DB->query($SQL->get(dsn()), 'all'))) {
                foreach ($DB->query($SQL->get(dsn()), 'all') as $row) {
                    $cnt++;
                    $bid = intval($row['blog_id']);
                    $right = ($cnt * 2) + $pos;
                    $left = $right - 1;

                    $SQL = SQL::newUpdate('blog');
                    $SQL->addUpdate('blog_left', $left);
                    $SQL->addUpdate('blog_right', $right);
                    $SQL->addUpdate('blog_sort', $cnt);
                    $SQL->addWhereOpr('blog_id', $bid);
                    $DB->query($SQL->get(dsn()), 'exec');

                    array_push($que, $bid);
                }

                if (!empty($aryPid)) {
                    $SQL = SQL::newUpdate('blog');
                    $SQL->setUpdate('blog_left', SQL::newOpr('blog_left', ($cnt * 2), '+'));
                    $SQL->addWhereOpr('blog_left', $pos, '>');
                    $SQL->addWhereIn('blog_parent', $aryPid);
                    $DB->query($SQL->get(dsn()), 'exec');

                    $SQL = SQL::newUpdate('blog');
                    $SQL->setUpdate('blog_right', SQL::newOpr('blog_right', ($cnt * 2), '+'));
                    $SQL->addWhereOpr('blog_right', $pos, '>=');
                    $SQL->addWhereIn('blog_parent', $aryPid);
                    $DB->query($SQL->get(dsn()), 'exec');
                }
                array_push($aryPid, $pid);
            }

            if (empty($que)) {
                break;
            }
        }

        return true;
    }
}

class Fix_BlogDelete extends Fix
{
    public function execute($Post)
    {
        do {
            $selected = $this->args['selected'];
            $count = $this->args['count'];

            if (
                0
                || 1 > $selected
                || $count < $selected
            ) {
                //$Post->setMethod('delete', 'operable', false);
                return false;
                break;
            }

            $DB     = DB::singleton(dsn());
            for ($i = 1; $i <= $count; $i++) {
                if ($selected === $i) {
                    continue;
                }

                $SQL = SQL::newSelect('blog');
                $SQL->setSelect('blog_id', 'blog_amount', null, 'count');
                $SQL->addWhereOpr('blog_id', intval($Post->get('bid_' . $i)));
                $SQL->addWhereOpr('blog_code', strval($Post->get('code_' . $i)));
                $SQL->addWhereOpr('blog_status', strval($Post->get('status_' . $i)));
                $SQL->addWhereOpr('blog_parent', intval($Post->get('parent_' . $i)));
                $SQL->addWhereOpr('blog_sort', intval($Post->get('sort_' . $i)));
                $SQL->addWhereOpr('blog_left', intval($Post->get('left_' . $i)));
                $SQL->addWhereOpr('blog_right', intval($Post->get('right_' . $i)));
                $SQL->addWhereOpr('blog_name', strval($Post->get('name_' . $i)));
                $SQL->addWhereOpr('blog_domain', strval($Post->get('domain_' . $i)));
                $SQL->addWhereOpr('blog_indexing', strval($Post->get('indexing_' . $i)));
                $SQL->setGroup('blog_id');

                if (2 <= $DB->query($SQL->get(dsn()), 'one')) {
                    break;
                }

                $SQL    = SQL::newDelete('blog');
                $SQL->addWhereOpr('blog_id', intval($Post->get('bid_' . $i)));
                $SQL->addWhereOpr('blog_code', strval($Post->get('code_' . $i)));
                $SQL->addWhereOpr('blog_status', strval($Post->get('status_' . $i)));
                $SQL->addWhereOpr('blog_parent', intval($Post->get('parent_' . $i)));
                $SQL->addWhereOpr('blog_sort', intval($Post->get('sort_' . $i)));
                $SQL->addWhereOpr('blog_left', intval($Post->get('left_' . $i)));
                $SQL->addWhereOpr('blog_right', intval($Post->get('right_' . $i)));
                $SQL->addWhereOpr('blog_name', strval($Post->get('name_' . $i)));
                $SQL->addWhereOpr('blog_domain', strval($Post->get('domain_' . $i)));
                $SQL->addWhereOpr('blog_indexing', strval($Post->get('indexing_' . $i)));
                $DB->query($SQL->get(dsn()), 'exec');
            }
        } while (false);

        return true;
    }
}

class Fix_CategoryAlign extends Fix
{
    public function execute()
    {
        $bid = $this->args['bid'];

        @set_time_limit(0);
        $DB = DB::singleton(dsn());

        $que = [0]; // FIFO
        $aryPid = [];
        while (true) {
            $pid = array_shift($que);

            $pos = 0;
            if (!empty($pid)) {
                $SQL = SQL::newSelect('category');
                $SQL->addWhereOpr('category_id', $pid);
                $SQL->addWhereOpr('category_blog_id', $bid);
                if (!!($row = $DB->query($SQL->get(dsn()), 'row'))) {
                    $pos = intval($row['category_left']); // - 1;
                } else {
                    continue;
                }
            }

            $SQL = SQL::newSelect('category');
            $SQL->setSelect('category_id');
            $SQL->addWhereOpr('category_parent', $pid);
            $SQL->addWhereOpr('category_blog_id', $bid);
            $SQL->setOrder('category_sort');

            $cnt = 0;
            if (!!($all = $DB->query($SQL->get(dsn()), 'all'))) {
                foreach ($all as $row) {
                    $cnt++;
                    $cid = intval($row['category_id']);
                    $right = ($cnt * 2) + $pos;
                    $left = $right - 1;

                    $SQL = SQL::newUpdate('category');
                    $SQL->addUpdate('category_left', $left);
                    $SQL->addUpdate('category_right', $right);
                    $SQL->addUpdate('category_sort', $cnt);
                    $SQL->addWhereOpr('category_id', $cid);
                    $SQL->addWhereOpr('category_blog_id', $bid);
                    $DB->query($SQL->get(dsn()), 'exec');

                    array_push($que, $cid);
                }

                if (!empty($aryPid)) {
                    $SQL = SQL::newUpdate('category');
                    $SQL->setUpdate('category_left', SQL::newOpr('category_left', ($cnt * 2), '+'));
                    $SQL->addWhereOpr('category_left', $pos, '>');
                    $SQL->addWhereIn('category_parent', $aryPid);
                    $SQL->addWhereOpr('category_blog_id', $bid);
                    $DB->query($SQL->get(dsn()), 'exec');

                    $SQL = SQL::newUpdate('category');
                    $SQL->setUpdate('category_right', SQL::newOpr('category_right', ($cnt * 2), '+'));
                    $SQL->addWhereOpr('category_right', $pos, '>=');
                    $SQL->addWhereIn('category_parent', $aryPid);
                    $SQL->addWhereOpr('category_blog_id', $bid);
                    $DB->query($SQL->get(dsn()), 'exec');
                }
                array_push($aryPid, $pid);
            }

            if (empty($que)) {
                break;
            }
        }

        return true;
    }
}

class Fix_CommentAlign extends Fix
{
    public function execute()
    {
        @set_time_limit(0);

        $bid = $this->args['bid'];

        $DB = DB::singleton(dsn());
        $SQL = SQL::newSelect('comment');
        $SQL->setSelect('comment_entry_id', 'eid', '', 'DISTINCT');
        $SQL->addWhereOpr('comment_blog_id', $bid);
        $SQL->setOrder('eid');
        $entryQ = $SQL->get(dsn());
        if ($DB->query($entryQ, 'fetch')) {
            while (!!($entryRow = $DB->fetch($entryQ))) {
                $eid = intval($entryRow['eid']);

                $SQL = SQL::newSelect('comment');
                $SQL->setSelect('comment_parent', 'pid', '', 'DISTINCT');
                $SQL->addWhereOpr('comment_entry_id', $eid);
                $SQL->addWhereOpr('comment_blog_id', $bid);
                $SQL->setOrder('pid');
                $parentQ = $SQL->get(dsn());
                $aryPid = [];

                if ($DB->query($parentQ, 'fetch')) {
                    while (!!($parentRow = $DB->fetch($parentQ))) {
                        $pid = intval($parentRow['pid']);

                        //-----
                        // pos
                        $pos = 0;
                        if (!empty($pid)) {
                            $SQL = SQL::newSelect('comment');
                            $SQL->setSelect('comment_right');
                            $SQL->addWhereOpr('comment_id', $pid);
                            $pos = intval($DB->query($SQL->get(dsn()), 'one')) - 1;
                        }

                        $SQL = SQL::newSelect('comment');
                        $SQL->setSelect('comment_id');
                        $SQL->addWhereOpr('comment_parent', $pid);
                        $SQL->addWhereOpr('comment_entry_id', $eid);
                        $SQL->addWhereOpr('comment_blog_id', $bid);
                        $cnt = 0;
                        foreach ($DB->query($SQL->get(dsn()), 'all') as $row) {
                            $cnt++;
                            $cmid = intval($row['comment_id']);

                            $right = ($cnt * 2) + $pos;
                            $left = $right - 1;

                            $SQL = SQL::newUpdate('comment');
                            $SQL->addUpdate('comment_left', $left);
                            $SQL->addUpdate('comment_right', $right);
                            $SQL->addWhereOpr('comment_id', $cmid);
                            $SQL->addWhereOpr('comment_entry_id', $eid);
                            $SQL->addWhereOpr('comment_blog_id', $bid);
                            $DB->query($SQL->get(dsn()), 'exec');
                        }

                        if (!empty($aryPid)) {
                            $SQL = SQL::newUpdate('comment');
                            $SQL->setUpdate('comment_left', SQL::newOpr('comment_left', ($cnt * 2), '+'));
                            $SQL->addWhereOpr('comment_left', $pos, '>');
                            $SQL->addWhereIn('comment_parent', $aryPid);
                            $SQL->addWhereOpr('comment_entry_id', $eid);
                            $SQL->addWhereOpr('comment_blog_id', $bid);
                            $DB->query($SQL->get(dsn()), 'exec');

                            $SQL = SQL::newUpdate('comment');
                            $SQL->setUpdate('comment_right', SQL::newOpr('comment_right', ($cnt * 2), '+'));
                            $SQL->addWhereOpr('comment_right', $pos, '>=');
                            $SQL->addWhereIn('comment_parent', $aryPid);
                            $SQL->addWhereOpr('comment_entry_id', $eid);
                            $SQL->addWhereOpr('comment_blog_id', $bid);
                            $DB->query($SQL->get(dsn()), 'exec');
                        }

                        $aryPid[] = $pid;
                    }
                }
            }
        }

        return true;
    }
}
