<?php
class Pages extends Buyers
{
    // Список указателей на категории в дереве категорий (ключ = id категории)
    private $all_pages;
    // Дерево категорий
    private $pages_tree;

    public function __construct()
    {
        // Создаем папку для ресайзов изображений, если её нет
        if(!is_dir($this->config->root_dir.$this->images->pages_images_dir))
            mkdir($this->config->root_dir.$this->images->pages_images_dir, 0755);
    }

    public function get_pages($filter = array())
    {
        $result = array();
        $sorting = 'position';
        $visible_filter = '';
        $url_filter = '';
        $template_filter = '';
        $parent_id_filter = '';
        $limit_filter = '';

        if(!isset($this->pages_tree))
            $this->init_pages();

        if(isset($filter['template']))
            $template_filter = $this->db->placehold('AND template = ?', $filter['template']);

        if(isset($filter['limit']))
            $limit_filter = $this->db->placehold('LIMIT ?', $filter['limit']);

        if(isset($filter['visible']))
            $visible_filter = $this->db->placehold('AND visible = ?', intval($filter['visible']));

        if(isset($filter['url']))
            $url_filter = $this->db->placehold('AND url = ?', $filter['url']);

        if(isset($filter['parent_id']))
            $parent_id_filter = $this->db->placehold('AND parent_id = ?', $filter['parent_id']);

        if(isset($filter['sorting']))
            $sorting = $filter['sorting'];

        $this->db->query("SELECT id FROM pages WHERE 1 $visible_filter $url_filter $parent_id_filter $template_filter ORDER BY $sorting ASC $limit_filter");
        $res = $this->db->results('id');
        foreach($res AS $id)
        {
            if(isset($this->all_pages[$id]))
                $result[$id] = $this->all_pages[$id];
        }

        return $result;
    }

    // Функция возвращает дерево категорий
    public function get_pages_tree()
    {
        if(!isset($this->pages_tree))
            $this->init_pages();

        return $this->pages_tree;
    }

    // Функция возвращает все ветки категории
    public function get_all_pages()
    {
        if(!isset($this->all_pages))
            $this->init_pages();

        return $this->all_pages;
    }

    // Функция возвращает заданную страницу
    public function get_page($id)
    {
        if(!isset($this->all_pages))
            $this->init_pages();

        if($page = $this->all_pages[$id] ?? null)
            return $page;

        if(is_string($id))
        {
            foreach($this->all_pages as $page)
            {
                if ($page->url == $id || $page->name == $id)
                    return $page;
            }
        }
        return false;
    }

    // Добавление страницы
    public function add_page($page)
    {
        if(empty($page->url))
            $page->url = $this->custom->translit($page->name);

        $query = $this->db->placehold("INSERT INTO pages SET ?%", $page);
        if(!$this->db->query($query))
            return false;

        $id = $this->db->insert_id();
		$this->db->query("UPDATE pages SET position=id WHERE id=?", $id);

        unset($this->pages_tree);
        unset($this->all_pages);
        return $id;
    }

    // Изменение страницы
    public function update_page($id, $page)
    {
        $query = $this->db->placehold("UPDATE pages SET ?% WHERE id=? LIMIT 1", $page, intval($id));
        if(!$this->db->query($query))
            return false;
        unset($this->pages_tree);
        unset($this->all_pages);
        return intval($id);
    }

    // Удаление страницы
    public function delete_page($ids)
    {
        $ids = (array) $ids;
        foreach($ids as $id)
        {
            if($page = $this->get_page(intval($id)))
            {
                $this->db->query("DELETE FROM properties WHERE page_id IN(?@)", $page->children);
                foreach($page->children AS $child)
                {
                    $page = $this->get_page($child);
                    $this->images->delete_images(array_keys($page->images));

                    if($files = $this->files->get_files(array("relation"=>"page", "relation_id"=>$child)))
                    foreach($files AS $file)
                        $this->files->delete_file($file->id);

                    $this->delete_related_pages($child);
                }
                $this->db->query("DELETE FROM pages WHERE id IN(?@)", $page->children);
            }
        }
        unset($this->pages_tree);
        unset($this->all_pages);
    }

    public function add_related_pages($page_id, $related_pages)
    {
        if(empty($related_pages))
            return false;

        $pos = 0;
        foreach($related_pages as $related_page)
        {
            $pos++;
            $related_page->position = $pos;
            $this->db->query("INSERT IGNORE INTO related_pages SET ?%", $related_page);
        }

        return true;
    }

    public function get_properties($template)
    {
        $query = $this->db->placehold("SELECT id AS uid, name AS id, page_id, template, name, value, description FROM properties WHERE template = ? GROUP BY name ORDER BY uid ASC", $template);
        $this->db->query($query);
        return $this->db->results();
    }

    public function add_properties($properties)
    {
        if(empty($properties))
            return false;

        foreach($properties AS $prop)
        {
            if($prop->value && $prop->name)
                $this->db->query("INSERT INTO properties SET ?%", $prop);
        }

        return true;
    }

    public function delete_related_pages($page_id)
    {
        $query = $this->db->placehold("DELETE FROM related_pages WHERE page_id=?", intval($page_id));
        $this->db->query($query);
    }

    public function get_related_pages($page_id = array())
    {
        $related_pages = array();
        if(empty($page_id))
            return $related_pages;

        $this->db->query("SELECT * FROM related_pages WHERE page_id IN(?@) ORDER BY position", (array)$page_id);
        if($tmp = $this->db->results())
        foreach($tmp as $p)
            $related_pages[] = $this->get_page(intval($p->related_id));

        return $related_pages;
    }

    public function get_path($page_id)
    {
        $pages = array();
        while($page_id > 0)
        {
            $pages[] = $p = $this->get_page(intval($page_id));
            $page_id = $p->parent_id;
        }
        return array_reverse($pages);
    }

    private function init_pages()
    {
        $tree = new stdClass();
        $tree->subpages = array();

        $pointers = array();
        $pointers[0] = &$tree;
        //$pointers[0]->path = array();
        $pointers[0]->level = 0;

        //соберем все данные, которые нужны: фотки, файлы, свойства
        $images = array();
        $tmp = $this->images->get_images(array("relation"=>"pages"));
        foreach($tmp AS $image)
            $images[$image->relation_id][$image->id] = $image;

        $files = array();
        $tmp = $this->files->get_files(array("relation"=>"pages"));
        foreach($tmp AS $file)
            $files[$file->relation_id][$file->id] = $file;

        $properties = array();
        $tmp = $this->db->query("SELECT name, page_id, value FROM properties")->results();
        foreach($tmp AS $prop)
            $properties[$prop->page_id][$prop->name] = $prop->value;

        $pages = $this->db->query("SELECT * FROM pages ORDER BY parent_id ASC, position")->results();
        foreach($pages AS $id => $page)
        {
            $page->files = $files[$id] ?? array();
            $page->images = $images[$id] ?? array();
            $page->properties = $properties[$id] ?? array();

            $page->image = !empty($page->images) ? reset($page->images) : null;
            $page->file = !empty($page->files) ? reset($page->files) : null;

            //подгрузим все свойства страницы для возможности обращения по названию в шаблоне {$page->property_name}
            foreach($page->properties AS $name => $value)
                $page->{$name} = $value;

            if(isset($pointers[$page->parent_id]))
            {
                $pointers[$id] = $pointers[$page->parent_id]->subpages[] = $page;
                //$pointers[$id]->path = array_merge($pointers[$page->parent_id]->path, array($pointers[$id]));
                $pointers[$id]->level = $pointers[$page->parent_id]->level+1;
            }
        }

        $ids = array_reverse(array_keys($pointers));
        foreach($ids as $id)
        {
            if(!empty($id))
            {
                $pointers[$id]->children[] = $id;
                $ppc = &$pointers[$pointers[$id]->parent_id]->children;
                $ppc = isset($ppc) ? array_merge(array($id), $ppc) : array($id);
            }
        }

        unset($pointers[0]);

        $this->pages_tree = $tree->subpages;
        $this->all_pages = $pointers;
    }
}
