imagecms/ImageCMS

View on GitHub
application/modules/tags/tags.php

Summary

Maintainability
F
3 days
Test Coverage
<?php

if (!defined('BASEPATH')) {
    exit('No direct script access allowed');
}

/**
 * Image CMS
 *
 * Page tags module
 */
class Tags extends MY_Controller
{

    public $min_font_size = 10;

    public $max_font_size = 26;

    public $min_count = -1;

    public $max_count = -1;

    public $delimiter = ' ';

    public $tag_url_prefix = '/tags/search/';

    public $tags = [];

    public function __construct() {
        parent::__construct();
        $this->load->module('core');
        $lang = new MY_Lang();
        $lang->load('tags');
    }

    public function index() {
        //$this->prepare_tags(); // Prepare tags array. Tags will be selected from content_tags table.

        /**
          $tags = array(
          array('value' => 'text 1', 'count' => '1'),
          array('value' => 'text 2', 'count' => '5'),
          array('value' => 'text 3', 'count' => '3'),
          );

          $this->prepare_tags($tags); // Prepare custom tags array.

          $this->_sort_tags(); // Sort tags by count or text.

          shuffle($this->tags); // Shuffle tags array.
         */
        //echo $this->build_cloud(); // Display tag cloud.
        $this->core->error_404();
    }

    // Autoload default function

    public function autoload() {
        $this->load->helper('tags');
    }

    public function initialize($config = []) {
        if (count($config) > 0) {
            foreach ($config as $k => $v) {
                if (isset($this->$k)) {
                    $this->$k = $v;
                }
            }
        }
    }

    /**
     * Search pages by tag
     */
    public function search($tag = '', $offset = 0) {
        $this->load->module('search');
        $this->search->search_tpl = 'search';

        $error = FALSE;

        $offset = $this->uri->segment($this->uri->total_segments());

        if ($offset < 0) {
            $offset = 0;
        }

        $tag = urldecode($tag);
        $tags = explode(':', $tag);
        $countTags = count($tags);
        if ($countTags > 0) {
            for ($i = 0; $i < $countTags; $i++) {
                $tags[$i] = urldecode($tags[$i]);
            }

            $this->db->where_in('value', $tags);

            $ids = $this->db->get('tags');
        } else {
            $this->search->_display(FALSE);
        }

        if ($ids->num_rows() == 0) {
            $error = TRUE;
        } else {
            // Get pages
            $pages_id = [];
            $tags_ids = [];

            foreach ($ids->result_array() as $row) {
                $tags_ids[] = $row['id'];
            }

            if (count($tags_ids) > 0) {
                $this->db->where_in('tag_id', $tags_ids);
                $query = $this->db->get('content_tags');
            }

            foreach ($query->result_array() as $key) {
                $pages_id[] = $key['page_id'];
            }

            $pages_id = array_unique($pages_id);

            if (count($pages_id) > 0) {

                $this->db->select('IF(route.parent_url <> \'\', concat(route.parent_url, \'/\', route.url), route.url) as full_url, content.*', FALSE);
                $this->db->where('post_status', 'publish');
                $this->db->where('publish_date <=', time());
                $this->db->where('lang', $this->config->item('cur_lang'));
                $this->db->join('route', 'route.id=content.route_id');
                $this->db->order_by('publish_date', 'DESC');
                $this->db->where_in('content.id', $pages_id);
                $pages = $this->db->get('content', $this->search->row_count, (int) $offset);

                if (NULL == $query) {
                    $this->search->_display(FALSE);
                    exit;
                } else {
                    $pages = $pages->result_array();

                    // Connect cfcm fields
                    ($hook = get_hook('core_return_category_pages')) ? eval($hook) : NULL;
                }

                //Pagination
                if (count($pages) >= $this->search->row_count) {
                    $this->load->library('Pagination');

                    $paginationConfig['base_url'] = site_url('tags/search/' . $tag . '/');
                    $paginationConfig['total_rows'] = count($pages_id);
                    $paginationConfig['per_page'] = $this->search->row_count;
                    $paginationConfig['uri_segment'] = $this->uri->total_segments();
                    $paginationConfig['first_link'] = lang('The first', 'tags');
                    $paginationConfig['last_link'] = lang('Last', 'tags');
                    include_once "./templates/{$this->config->item('template')}/paginations.php";
                    $paginationConfig['page_query_string'] = FALSE;

                    $this->pagination->initialize($paginationConfig);
                    $this->template->assign('pagination', $this->pagination->create_links());
                }
                //End pagination
            }

            if (count($pages_id) == 0) {
                $error = TRUE;
            } else {
                $this->core->set_meta_tags(lang('Search title', 'tags') . $this->search->title_delimiter . $tag);
                $this->template->assign('search_title', htmlspecialchars($tag));
                $this->search->_display($pages);
            }
        }

        if ($error === TRUE) {
            $this->search->_display(FALSE);
        }
    }

    public function prepare_tags($array = []) {
        $result = [];

        if (count($array) > 0) {
            $result = $array;
        } else {
            $tags = $this->get_all_tags();

            if (count($tags) > 0) {
                $frequency = [];
                $currentLanguageId = MY_Controller::getCurrentLanguage('id');

                $content_tags = $this->db
                    ->select('tag_id')
                    ->join('content', "content_tags.page_id=content.id AND content.lang=$currentLanguageId")
                    ->get('content_tags')->result_array();

                foreach ($content_tags as $val) {
                    $tag_id = $val['tag_id'];

                    if (isset($frequency[$tag_id])) {
                        $frequency[$tag_id] ++;
                    } else {
                        $frequency[$tag_id] = 1;
                    }
                }

                foreach ($tags as $tag) {
                    if ($frequency[$tag['id']]) {
                        array_push($result, ['value' => $tag['value'], 'count' => $frequency[$tag['id']]]);
                    }
                }
            }
        }

        // Find min. and max. tag count value
        foreach ($result as $v) {
            $count = $v['count'];

            if ($count > $this->max_count) {
                $this->max_count = $count;
            }

            if ($count < $this->min_count OR $this->min_count == -1) {
                $this->min_count = $count;
            }
        }

        $this->tags = $result;
    }

    /**
     * Build tags cloud
     *
     * @param string $return_type - possible values: html/array
     */
    public function build_cloud($return_type = 'html') {
        $this->load->helper('url');

        switch ($return_type) {
            case 'html':
                $tags_cloud = '';
                break;

            case 'array':
                $tags_cloud = [];
                break;
        }
        $tags = $this->tags;

        if (count($tags) > 0) {
            $font_size_diff = $this->max_font_size - $this->min_font_size;
            $count_diff = $this->max_count - $this->min_count;

            if ($font_size_diff > 0 AND $count_diff > 0) {
                $increase = $font_size_diff / $count_diff;
            } else {
                $increase = 0;
            }

            foreach ($tags as $tag) {
                $font_size = round($this->min_font_size + ($tag['count'] * $increase));

                if ($font_size > $this->max_font_size) {
                    $font_size = $this->max_font_size;
                }

                if ($font_size < $this->min_font_size) {
                    $font_size = $this->max_font_size;
                }

                if ($return_type == 'html') {
                    //$tags_cloud .= $this->delimiter.'<span style="font-size:'.$font_size.'px">'.anchor($this->tag_url_prefix.$tag['value'], $tag['value']).'</span>';
                    $tags_cloud .= $this->delimiter . anchor($this->tag_url_prefix . $tag['value'], $tag['value'], 'style="font-size:' . $font_size . 'px;text-decoration:none;"');
                } else {
                    $tag['font_size'] = $font_size;
                    array_push($tags_cloud, $tag);
                }
            }
        }

        return $tags_cloud;
    }

    /**
     * Sort tags
     *
     * @param string $sort_var - value to sort array.
     * @param string $order - possible values: SORT_DESC, SORT_ASC
     */
    public function _sort_tags($sort_var = 'count', $order = SORT_DESC) {
        $values = [];

        if ($sort_var != 'count' AND $sort_var != 'value') {
            $sort_var = 'count';
        }

        foreach ($this->tags as $k => $v) {
            $values[$k] = $v[$sort_var];
        }

        array_multisort($values, $order, $this->tags);
    }

    public function _set_page_tags($tags_str = '', $page_id) {
        $tags_arr = explode(',', $tags_str);

        $this->db->delete('content_tags', ['page_id' => $page_id]);

        if (count($tags_arr) > 0) {
            foreach ($tags_arr as $v) {
                if (trim($v) != '') {
                    // Check if tag exits
                    if ($this->db->get_where('tags', ['value' => trim($v)])->num_rows() > 0) {
                        $this->db->limit(1);
                        $query = $this->db->get_where('tags', ['value' => trim($v)])->row();
                        $tag_id = $query->id;
                    } else {
                        // Create new tag
                        $this->db->insert('tags', ['value' => trim($v)]);
                        $tag_id = $this->db->insert_id();
                    }

                    if (mb_strlen($v, 'utf-8') >= 1) {
                        $this->db->insert('content_tags', ['page_id' => $page_id, 'tag_id' => $tag_id]);
                    }
                }
            }
        }

        //        $this->_remove_orphans();
    }

    public function _remove_orphans($page_id = null) {
        $page = $this->db->where('id', $page_id)->get('content');
        $page = $page ? $page->row_array() : [];
        $page_id = $page['lang_alias'] ? $page['lang_alias'] : $page_id;

        if ($page_id) {
            $content_tags = $this->db
                ->select('content_tags.id')
                ->where('content.id', $page_id)
                ->or_where('content.lang_alias', $page_id)
                ->join('content', 'content_tags.page_id=content.id')
                ->get('content_tags');

            $content_tags = $content_tags ? $content_tags->result_array() : [];
            $content_tags_ids = [];
            foreach ($content_tags as $tag) {
                $content_tags_ids[] = $tag['id'];
            }

            $this->db->where_in('id', $content_tags_ids)->delete('content_tags');
        }

        $this->db->select('page_id, tag_id');
        $query = $this->db->get('content_tags');

        if (NULL != $query) {
            if ($query->num_rows() > 0) {
                $tags = [];

                foreach ($query->result_array() as $tag) {
                    $tags[] = $tag['tag_id'];
                }

                $this->db->where_not_in('id', $tags);
                $this->db->delete('tags');
            } else {
                $this->db->where('id > 0')->delete('tags');
            }
        }
    }

    public function get_page_tags($page_id) {
        $this->db->where('page_id', $page_id);
        $query = $this->db->get('content_tags');

        if (NULL != $query) {
            if ($query->num_rows() > 0) {
                $tags = [];

                foreach ($query->result_array() as $val) {
                    $tags[] = $val['tag_id'];
                }

                $this->db->where_in('id', $tags);
                return $this->db->get('tags')->result_array();
            }
        }
    }

    public function get_all_tags() {
        return $this->db->get('tags')->result_array();
    }

    public function search_tags($search_value) {
        $this->db->like('value', $search_value);
        return $this->db->get('tags')->result_array();
    }

    // Create content_tags table
    // TODO: move install/deinstall to model.

    public function _install() {
        if ($this->dx_auth->is_admin() == FALSE) {
            exit;
        }

        $this->load->dbforge();

        //content tags
        $fields = [
                   'id'      => [
                                 'type'           => 'INT',
                                 'constraint'     => 11,
                                 'auto_increment' => TRUE,
                                ],
                   'page_id' => [
                                 'type'       => 'INT',
                                 'constraint' => 11,
                                ],
                   'tag_id'  => [
                                 'type'       => 'INT',
                                 'constraint' => 11,
                                ],
                  ];

        $this->dbforge->add_key('id', TRUE);
        $this->dbforge->add_field($fields);
        $this->dbforge->create_table('content_tags', TRUE);

        //tags
        $fields = [
                   'id'    => [
                               'type'           => 'INT',
                               'constraint'     => 11,
                               'auto_increment' => TRUE,
                              ],
                   'value' => [
                               'type'       => 'VARCHAR',
                               'constraint' => 255,
                              ],
                  ];

        $this->dbforge->add_key('id', true);
        $this->dbforge->add_key('value');
        $this->dbforge->add_field($fields);
        $this->dbforge->create_table('tags');

        //autoload
        $this->db->where('name', 'tags');
        $this->db->update('components', ['autoload' => '1']);
    }

    // Delete tags table

    public function _deinstall() {
        if ($this->dx_auth->is_admin() == FALSE) {
            exit;
        }

        $this->load->dbforge();
        $this->dbforge->drop_table('content_tags');
        $this->dbforge->drop_table('tags');
    }

}

/* End of file tags.php */