205 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
|     defined('BASEPATH') OR exit('No direct script access allowed');
 | |
| 
 | |
|     class SearchModel extends CI_Model
 | |
|     {
 | |
|         public function __construct()
 | |
|         {
 | |
|             parent::__construct();
 | |
|             $this->lang->load('search', $_SESSION['site_lang']);
 | |
|         }
 | |
| 
 | |
|         public function search($query, $amount, $offset, $filters)
 | |
|         {
 | |
|             $results = $this->getRawResults($query, $amount, $offset, $filters);
 | |
|             $results = $this->prepareResults($results);
 | |
|             return $results;
 | |
|         }
 | |
| 
 | |
|         private function getRawResults($query, $amount, $offset, $filters)
 | |
|         {
 | |
|             mb_language('uni');
 | |
|             mb_internal_encoding('UTF-8');
 | |
| 
 | |
|             $lang = $_SESSION['site_lang'];
 | |
| 
 | |
|             $query = strtolower($query);
 | |
|             $offset *= $amount;
 | |
| 
 | |
|             list($sql, $attr) = $this->buildQuery($filters);
 | |
|             $attr = str_split($attr);
 | |
|             foreach ($attr as $i => $a) {
 | |
|                 $a = $a === 'l' ? $lang : $query;
 | |
|                 $attr[$i] = $a;
 | |
|             }
 | |
|             $attr[] = $amount;
 | |
|             $attr[] = $offset;
 | |
| 
 | |
|             $this->db->cache_off();
 | |
|             $results = $this->db->query($sql, $attr)->result_array();
 | |
|             $this->db->cache_on();
 | |
| 
 | |
|             return $results;
 | |
|         }
 | |
| 
 | |
|         private function buildQuery($filters)
 | |
|         {
 | |
|             $attributes = '';
 | |
|             $query = 'SELECT a.*, u.username authorName, u.displayname authorDisplayname
 | |
|                 FROM (';
 | |
| 
 | |
|             $possibilities = [
 | |
|                 'blogPost' => [
 | |
|                     'sql' => 'SELECT "blogPost" type, bp.postUrl url, bp.postAuthorID author, bp.postImage image, bt.postTitle title, bt.postDesc content, bp.postPublishDate date
 | |
|                        FROM blog_posts bp
 | |
|                               INNER JOIN blog_translations bt ON bt.postID = bp.postID AND bt.language = ?
 | |
|                               LEFT JOIN blog_content bc ON bc.postID = bp.postID AND bc.isActive = TRUE AND bc.language = ?
 | |
|                        WHERE (LOWER(bt.postTitle) RLIKE ?
 | |
|                           OR LOWER(bt.postDesc) RLIKE ?
 | |
|                           OR LOWER(bc.content) RLIKE ?
 | |
|                           OR bp.postID IN (SELECT bpt.post_id FROM blog_post_tags bpt WHERE bpt.tag_id IN(SELECT bt.ID FROM blog_tags bt WHERE bt.name RLIKE ? OR LOWER(bt.display_name) RLIKE ?))
 | |
|                           OR (SELECT username FROM users WHERE ID = bp.postAuthorID) RLIKE ?
 | |
|                           OR (SELECT display_name FROM blog_categories WHERE ID = bp.postCategoryID) RLIKE ?)
 | |
|                           AND postState = 1 AND postIsDeleted = FALSE',
 | |
|                     'attributes' => 'llqqqqqqq'
 | |
|                 ],
 | |
|                 'blogCategory' => [
 | |
|                     'sql' => 'SELECT "blogCategory" type, c.name url, 1 author, null image, c.display_name title, null content, null date
 | |
|                       FROM blog_categories c
 | |
|                       WHERE c.name RLIKE ? OR LOWER(c.display_name) RLIKE ?',
 | |
|                     'attributes' => 'qq'
 | |
|                 ],
 | |
|                 'blogTag' => [
 | |
|                     'sql' => 'SELECT "blogTag" type, t.name url, 1 author, null image, t.display_name title, null content, null date
 | |
|                       FROM blog_tags t
 | |
|                       WHERE t.name RLIKE ? OR LOWER(t.display_name) RLIKE ?',
 | |
|                     'attributes' => 'qq'
 | |
|                 ],
 | |
|                 'user' => [
 | |
|                     'sql' => 'SELECT "user" type, u.username url, u.ID author, u.header_image image, u.displayname title, u.about content, u.date_created date
 | |
|                        FROM users u
 | |
|                        WHERE (username RLIKE ?
 | |
|                           OR lower(about) RLIKE ?)
 | |
|                           AND is_activated AND isDeleted = FALSE',
 | |
|                     'attributes' => 'qq',
 | |
|                 ],
 | |
|                 'userPost' => [
 | |
|                     'sql' => 'SELECT "userPost" type, p.uuid url, p.user_id author, null image, p.content title, null content, p.date date
 | |
|                        FROM user_posts p
 | |
|                        WHERE LOWER(p.content) RLIKE ?
 | |
|                           OR (SELECT username FROM users WHERE ID = p.user_id) RLIKE ?',
 | |
|                     'attributes' => 'qq',
 | |
|                 ],
 | |
|                 'project' => [
 | |
|                     'sql' => 'SELECT "project" type, p.name url, 1 as author, p.source image, t.title title, t.description content, p.datetime date
 | |
|                        FROM projects p
 | |
|                               INNER JOIN projects_translations t ON t.projectID = p.ID AND t.lang = ?
 | |
|                        WHERE LOWER(t.title) RLIKE ?
 | |
|                           OR LOWER(t.description) RLIKE ?
 | |
|                           OR LOWER(t.content) RLIKE ?',
 | |
|                     'attributes' => 'lqqq',
 | |
|                 ],
 | |
|                 'projectCategory' => [
 | |
|                     'sql' => 'SELECT "projectCategory" type, c.collection url, 1 author, null image, c.displayname title, c.displayname content, null date
 | |
|                        FROM projects_categories c
 | |
|                        WHERE lower(collection) RLIKE ?
 | |
|                           OR lower(displayname) RLIKE ?',
 | |
|                     'attributes' => 'qq'
 | |
|                 ],
 | |
|             ];
 | |
| 
 | |
|             $filters = array_intersect(array_keys($possibilities), $filters);
 | |
| 
 | |
|             if (empty($filters))
 | |
|                 $filters = array_keys($possibilities);
 | |
| 
 | |
|             foreach ($filters as $filter) {
 | |
|                 $data = $possibilities[$filter];
 | |
|                 if (empty($data))
 | |
|                     continue;
 | |
| 
 | |
|                 $query .= $data['sql'];
 | |
|                 $query .= ' UNION ';
 | |
|                 $attributes .= $data['attributes'];
 | |
|             }
 | |
| 
 | |
|             $query = substr($query, 0, -6);
 | |
| 
 | |
|             $query .= ') a
 | |
|                        LEFT JOIN users u ON a.author = u.ID
 | |
|                 ORDER BY date desc LIMIT ? OFFSET ?';
 | |
| 
 | |
|             return [$query, $attributes];
 | |
|         }
 | |
| 
 | |
|         private function prepareResults($results)
 | |
|         {
 | |
|             foreach ($results as $i => $result) {
 | |
|                 list(
 | |
|                     'author' => $author,
 | |
|                     'authorDisplayname' => $displayname,
 | |
|                     'authorName' => $username,
 | |
|                     'content' => $content,
 | |
|                     'date' => $date,
 | |
|                     'image' => $image,
 | |
|                     'title' => $title,
 | |
|                     'type' => $type,
 | |
|                     'url' => $url,
 | |
|                     ) = $result;
 | |
| 
 | |
|                 $date = date('d.m.Y', strtotime($date));
 | |
| 
 | |
|                 if (strlen($title) > 75) {
 | |
|                     $title = utf8_encode($title);
 | |
|                     $title = substr($title, 0, 75) . '...';
 | |
|                     $title = utf8_decode($title);
 | |
|                 }
 | |
| 
 | |
|                 if (strlen($content) > 200) {
 | |
|                     $content = utf8_encode($content);
 | |
|                     $content = substr($content, 0, 200) . '...';
 | |
|                     $content = utf8_decode($content);
 | |
|                 }
 | |
| 
 | |
|                 $showUser = TRUE;
 | |
|                 switch ($type) {
 | |
|                     case 'blogPost':
 | |
|                         $url = base_url('blog/post/' . $url);
 | |
|                         break;
 | |
|                     case 'project':
 | |
|                         $url = base_url('project/' . $url);
 | |
|                         break;
 | |
|                     case 'projectCategory':
 | |
|                         $url = base_url('projects/' . $url);
 | |
|                         $showUser = FALSE;
 | |
|                         break;
 | |
|                     case 'user':
 | |
|                         $url = base_url('user/' . $url);
 | |
|                         break;
 | |
|                     case 'userPost':
 | |
|                         $url = base_url('user/' . $username . '/post/' . $url);
 | |
|                         break;
 | |
|                 }
 | |
| 
 | |
|                 $type = lang('search_type_' . $type);
 | |
| 
 | |
|                 $newArray = [
 | |
|                     'showUser' => $showUser,
 | |
|                     'username' => $displayname,
 | |
|                     'authorUrl' => base_url('user/' . $username),
 | |
|                     'content' => $content,
 | |
|                     'date' => $date,
 | |
|                     'image' => $image,
 | |
|                     'title' => $title,
 | |
|                     'type' => $type,
 | |
|                     'url' => $url,
 | |
|                 ];
 | |
| 
 | |
| 
 | |
|                 $results[$i] = $newArray;
 | |
|             }
 | |
| 
 | |
|             return $results;
 | |
|         }
 | |
| 
 | |
|     } |