Газетное приложение Codeigniter 3

Я работаю над онлайн-газета / приложение для ведения блога с CodeIgniter 3.1.8 и Веточка.

Приложение предназначено для того, чтобы предложить разработчикам и дизайнерам возможность очень легко превратить свои HTML-шаблоны в веб-сайты на базе баз данных. Для этого я использовал Веточка шаблонизатор для внешнего интерфейса.

Я заинтересован в улучшении той части приложения, которая связана с отображением сообщений.

В Сообщения контроллер:

class Posts extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
    }
    
    private function _initPagination($path, $totalRows, $query_string_segment="page")
    {
        //load and configure pagination 
        $this->load->library('pagination');
        $config['base_url']             = base_url($path);
        $config['query_string_segment'] = $query_string_segment;
        $config['enable_query_strings'] = TRUE;
        $config['reuse_query_string']   = TRUE;
        $config['total_rows']           = $totalRows;
        $config['per_page']             = 12;
        if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
            $_GET[$config['query_string_segment']] = 1;
        }
        $this->pagination->initialize($config);
        
        $limit  = $config['per_page'];
        $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
        
        return array(
            'limit' => $limit,
            'offset' => $offset
        );
    }
    
    public function index()
    {
        
        //call initialization method
        $config = $this->_initPagination("/", $this->Posts_model->get_num_rows());
        
        $data                  = $this->Static_model->get_static_data();
        $data['base_url']      = base_url("/");
        $data['pages']         = $this->Pages_model->get_pages();
        $data['categories']    = $this->Categories_model->get_categories();
        $data['search_errors'] = validation_errors();
        
        //use limit and offset returned by _initPaginator method
        $data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
        $this->twig->addGlobal('pagination', $this->pagination->create_links());
        
        // featured posts
        if ($data['is_featured']) {
            $data['featured'] = $this->Posts_model->featured_posts();
            $this->twig->addGlobal('featuredPosts', "themes/{$data['theme_directory']}/partials/hero.twig");
        }
        
        $this->twig->display("themes/{$data['theme_directory']}/layout", $data);
    }
    
    public function search()
    {
        // Force validation since the form's method is GET
        $this->form_validation->set_data($this->input->get());
        $this->form_validation->set_rules('search', 'search term', 'required|trim|min_length[3]', array(
            'min_length' => 'The search term must be at least 3 characters long.'
        ));
        $this->form_validation->set_error_delimiters('<p class = "error search-error">', '</p>');
        // If search fails
        if ($this->form_validation->run() === FALSE) {
            $data['search_errors'] = validation_errors();
            return $this->index();
        } else {
            $expression           = $this->input->get('search');
            $posts_count          = $this->Posts_model->search_count($expression);
            $query_string_segment="page";
            $config               = $this->_initPagination("/posts/search", $posts_count, $query_string_segment);
            $data                 = $this->Static_model->get_static_data();
            $data['base_url']     = base_url("/");
            $data['pages']        = $this->Pages_model->get_pages();
            $data['categories']   = $this->Categories_model->get_categories();
            //use limit and offset returned by _initPaginator method
            $data['posts']        = $this->Posts_model->search($expression, $config['limit'], $config['offset']);
            $data['expression']   = $expression;
            $data['posts_count']  = $posts_count;
            $this->twig->addGlobal('pagination', $this->pagination->create_links());
            $this->twig->display("themes/{$data['theme_directory']}/layout", $data);
        }
    }
    
    public function byauthor($authorid)
    {
        //load and configure pagination 
        $this->load->library('pagination');
        $config['base_url']             = base_url('/posts/byauthor/' . $authorid);
        $config['query_string_segment'] = 'page';
        $config['total_rows']           = $this->Posts_model->posts_by_author_count($authorid);
        $config['per_page']             = 12;
        
        if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
            $_GET[$config['query_string_segment']] = 1;
        }
        
        $limit  = $config['per_page'];
        $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
        $this->pagination->initialize($config);
        
        $data                 = $this->Static_model->get_static_data();
        $data['base_url']     = base_url("/");
        $data['pages']        = $this->Pages_model->get_pages();
        $data['categories']   = $this->Categories_model->get_categories();
        $data['posts']        = $this->Posts_model->get_posts_by_author($authorid, $limit, $offset);
        $data['posts_count']  = $this->Posts_model->posts_by_author_count($authorid);
        $data['posts_author'] = $this->Posts_model->posts_author($authorid);
        $data['tagline']      = "Posts by " . $data['posts_author']->first_name . " " . $data['posts_author']->last_name;
        
        $this->twig->addGlobal('pagination', $this->pagination->create_links());
        $this->twig->display("themes/{$data['theme_directory']}/layout", $data);
    }
    
    public function post($slug)
    {
        $data                 = $this->Static_model->get_static_data();
        $data['base_url']     = base_url("/");
        $data['pages']        = $this->Pages_model->get_pages();
        $data['categories']   = $this->Categories_model->get_categories();
        $data['authors']      = $this->Usermodel->getAuthors();
        $data['posts']        = $this->Posts_model->sidebar_posts($limit = 5, $offset = 0);
        $data['post']         = $this->Posts_model->get_post($slug);
        $data['next_post']    = $this->Posts_model->get_next_post($slug);
        $data['prev_post']    = $this->Posts_model->get_prev_post($slug);
        $data['author_image'] = isset($data['post']->avatar) && $data['post']->avatar !== '' ? $data['post']->avatar : 'default-avatar.png';
        
        if ($data['categories']) {
            foreach ($data['categories'] as &$category) {
                $category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
            }
        }
        
        if (!empty($data['post'])) {
            // Overwrite the default tagline with the post title
            $data['tagline']  = $data['post']->title;
            // Get post comments
            $post_id          = $data['post']->id;
            $data['comments'] = $this->Comments_model->get_comments($post_id);
            $this->twig->addGlobal('singlePost', "themes/{$data['theme_directory']}/templates/singlepost.twig");
        } else {
            $data['tagline'] = "Page not found";
            $this->twig->addGlobal('notFound', "themes/{$data['theme_directory']}/templates/404.twig");
        }
        $this->twig->display("themes/{$data['theme_directory']}/layout", $data);
    }
}

В Posts_model модель:

class Posts_model extends CI_Model {

    public function get_num_rows() {
        $query = $this->db->get('posts');
        return $query->num_rows(); 
    }

    public function get_posts($limit, $offset) {
        $this->db->select('posts.*, categories.name as post_category, authors.first_name as author_fname, authors.last_name as author_lname');
        $this->db->order_by('posts.id', 'DESC');
        $this->db->join('categories', 'posts.cat_id = categories.id', 'inner');
        $this->db->join('authors', 'posts.author_id = authors.id', 'inner');
        $query = $this->db->get('posts', $limit, $offset);
        return $query->result();
    }

    public function featured_posts() {
        $this->db->select('posts.*, categories.name as post_category, authors.first_name as author_fname, authors.last_name as author_lname');
        $this->db->order_by('posts.id', 'DESC');
        $this->db->join('categories', 'posts.cat_id = categories.id', 'inner');
        $this->db->join('authors', 'posts.author_id = authors.id', 'inner');
        $query = $this->db->get_where('posts', array('featured' => 1));
        return $query->result();
    }

    public function search_count($expression) {
        $query = $this->db->like('title', $expression)
            ->or_like('description', $expression)
            ->or_like('content', $expression);
        $query = $this->db->get('posts');
        return $query->num_rows();  
    }

    public function search($expression, $limit, $offset) {
        $query = $this->db->like('title', $expression)
                ->or_like('description', $expression)
                ->or_like('content', $expression);
        $this->db->select('posts.*,categories.name as post_category');
        $this->db->order_by('posts.id', 'DESC');
        $this->db->join('categories', 'posts.cat_id = categories.id', 'inner');
        $query = $this->db->get('posts', $limit, $offset);
        return $query->result();
    }

    public function sidebar_posts($limit, $offset) {
        $this->db->order_by('id', 'DESC');
        $query = $this->db->get('posts', $limit, $offset);
        return $query->result();
    }

    public function get_num_rows_by_category($category_id) { 
        $query = $this->db->get_where('posts', array('cat_id' => $category_id));
        return $query->num_rows(); 
    }

    public function get_posts_by_category($category_id, $limit, $offset) {
        $this->db->select('posts.*, categories.name as post_category, authors.first_name as author_fname, authors.last_name as author_lname');
        $this->db->order_by('posts.id', 'DESC');
        $this->db->limit($limit, $offset);
        $this->db->join('categories', 'posts.cat_id = categories.id', 'inner');
        $this->db->join('authors', 'posts.author_id = authors.id', 'inner');
        $query = $this->db->get_where('posts', array('cat_id' => $category_id));
        return $query->result();
    }

    public function count_posts_in_category($category_id) {
        return $this->db
            ->where('cat_id', $category_id)
            ->count_all_results('posts');
    }

    public function get_posts_by_author($authorid, $limit, $offset) {
        $this->db->select('posts.*, categories.name as post_category, authors.first_name as author_fname, authors.last_name as author_lname');
    $this->db->order_by('posts.id', 'DESC');
    $this->db->limit($limit, $offset);
        $this->db->join('categories', 'posts.cat_id = categories.id', 'inner');
        $this->db->join('authors', 'posts.author_id = authors.id', 'inner');
        $query = $this->db->get_where('posts', array('posts.author_id' => $authorid));
        return $query->result();
    }

    public function posts_by_author_count($authorid) {
        $query = $this->db->get_where('posts', array('posts.author_id' => $authorid));
        return $query->num_rows();  
    }

    public function posts_author($authorid) {
        $this->db->select('authors.first_name,last_name');
        $query = $this->db->get_where('authors', array('id' => $authorid));
        return $query->row();
    }

    /* Single post */
    public function get_post($slug) {
        $query = $this->db->get_where('posts', array('slug' => $slug));
        if ($query->num_rows() > 0) {
            $data = $query->row();
      // run separate query for author name
            $author_query = $this->db->get_where('authors', array('id' => $data->author_id));
            if ($author_query->num_rows() == 1) {
                $author = $author_query->row();
                $data->first_name = $author->first_name;
                $data->last_name = $author->last_name;
                $data->avatar = $author->avatar;              
            } else {
                $data->first_name="Unknown";
                $data->last_name="";
                $data->avatar="";
            }

            $category_query = $this->db->get_where('categories', array('id' => $data->cat_id));
            if ($category_query->num_rows() == 1) {
                $category = $category_query->row();
                $data->category_name = $category->name;    
            }
            
            return $data;
        }
    }

    public function get_next_post($slug) {
        $this->db->where('id >', $this->get_post($slug)->id);
        $this->db->limit(1);
        return $this->db->get('posts')->row_array();
    }

    public function get_prev_post($slug) {
        $this->db->where('id <', $this->get_post($slug)->id);
        $this->db->order_by('id', 'desc'); 
        $this->db->limit(1);
        return $this->db->get('posts')->row_array();
    }

    public function slug_count($slug, $id){
    $this->db->select('count(*) as slugcount');
    $this->db->from('posts');
    $this->db->where('slug', $slug);
    // if its an update
    if ($id != null) {
        $this->db->where('id !=', $id);
    }
    $query = $this->db->get();
    return $query->row(0)->slugcount;
    }

  // Create, post
    public function create_post($post_image, $slug, $featured) {
        $data = [
            'title' => $this->input->post('title'),
            'slug' => $slug,
            'description' => $this->input->post('desc'),
            'content' => $this->input->post('body'),
            'post_image' => $post_image,
            'featured' => $featured,
            'author_id' => $this->session->userdata('user_id'),
            'cat_id' => $this->input->post('category'),
            'created_at' => date('Y-m-d H:i:s')
        ];
        return $this->db->insert('posts', $data);
    }

    // Update post
    public function update_post($id, $post_image, $slug, $featured) {
        $data = [
            'title' => $this->input->post('title'),
            'slug' => $slug,
            'description' => $this->input->post('desc'),
            'content' => $this->input->post('body'),
            'post_image' => $post_image,
            'featured' => $featured,
            'cat_id' => $this->input->post('category'),
            'updated_at' => date('Y-m-d H:i:s')
        ];

        $this->db->where('id', $id);
        return $this->db->update('posts', $data);
    }

    //Delete post
    public function delete_post($slug) {
        $this->db->where('slug', $slug);
        $this->db->delete('posts');
        return true;
    }

    public function delete_post_image($id) {
        $this->db->update('posts', array('post_image'=>'default.jpg'), ['id'=>$id]);
    }
}

Представление layout.php:

<!DOCTYPE html>
<html>
    <head>
        <title>{{site_title}} | {{tagline}}</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="{{base_url}}themes/{{theme_directory}}/assets/css/main.css">
    </head>
    <body>

        <!-- Header -->
        <header id="header">
            <div class="logo"><a href="{{base_url}}">{{site_title}}</a></div>
        </header>

        <section id="main">
            <div class="inner">
                {% if singlePost is defined %}
                    {{include(singlePost)}}
                {% elseif pageTemplate is defined  %}
                    {{include(pageTemplate)}}
                {% elseif contactForm is defined  %}
                {{include(contactForm)}}
                {% elseif notFound is defined  %}
                    {{include(notFound)}}
                {% else %}
                    {{ include('themes/' ~ theme_directory ~ '/templates/posts.twig') }}                
                {% endif %}
            </div>
        </section>

        <!-- Footer -->
        <footer id="footer">
            <div class="container">
                <ul class="icons">
                    <li><a href="{{twitter}}" target="_blank" class="icon fa-twitter"><span class="label">Twitter</span></a></li>
                    <li><a href="{{facebook}}" target="_blank" class="icon fa-facebook"><span class="label">Facebook</span></a></li>
                    <li><a href="{{instagram}}" target="_blank" class="icon fa-instagram"><span class="label">Instagram</span></a></li>
                    <li><a href="mailto:{{company_email}}" class="icon fa-envelope-o"><span class="label">Email</span></a></li>
                </ul>

                {% if pages %}
                    <ul class="footer-links">
                        {% for page in pages %}
                            <li><a href="{{base_url}}/pages/page/{{page.id}}">{{page.title}}</a></li>
                        {% endfor %}
                        <li><a class="nav-link" href="{{base_url}}contact">Contact</a></li>
                    </ul>
                {% endif %}
            </div>
            <div class="copyright">
                &copy; {{company_name}}. All rights reserved. Design by <a href="https://templated.co" target="_blank">TEMPLATED</a>
            </div>
        </footer>

        <script src="{{base_url}}/assets/js/jquery.min.js"></script>
    </body>
</html>

Меня больше всего беспокоит то, является ли код (разумно) СУХИМ или нет. и является ли приложение безопасным.

Но любая конструктивная критика будет оценена.

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *