2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								< ? php  namespace  BookStack\Services ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  BookStack\Book ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  BookStack\Chapter ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  BookStack\Entity ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  BookStack\Page ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  BookStack\SearchTerm ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Illuminate\Database\Connection ;  
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Illuminate\Database\Query\Builder ;  
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								use  Illuminate\Database\Query\JoinClause ;  
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:16:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Illuminate\Support\Collection ;  
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  SearchService  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  $searchTerm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  $book ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  $chapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  $page ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  $db ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    protected  $permissionService ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  $entities ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Acceptable  operators  to  be  used  in  a  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ var  array 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  $queryOperators  =  [ '<=' ,  '>=' ,  '=' ,  '<' ,  '>' ,  'like' ,  '!=' ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  SearchService  constructor . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  SearchTerm  $searchTerm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Book  $book 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Chapter  $chapter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Page  $page 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Connection  $db 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     *  @ param  PermissionService  $permissionService 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    public  function  __construct ( SearchTerm  $searchTerm ,  Book  $book ,  Chapter  $chapter ,  Page  $page ,  Connection  $db ,  PermissionService  $permissionService ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> searchTerm  =  $searchTerm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> book  =  $book ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> chapter  =  $chapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> page  =  $page ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> db  =  $db ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $this -> entities  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'page'  =>  $this -> page , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'chapter'  =>  $this -> chapter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'book'  =>  $this -> book 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> permissionService  =  $permissionService ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-30 18:38:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Set  the  database  connection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Connection  $connection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  setConnection ( Connection  $connection ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> db  =  $connection ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Search  all  entities  in  the  system . 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  @ param  string  $searchString 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     *  @ param  string  $entityType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  int  $page 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  int  $count 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  @ return  array [ int ,  Collection ]; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    public  function  searchEntities ( $searchString ,  $entityType  =  'all' ,  $page  =  1 ,  $count  =  20 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $terms  =  $this -> parseSearchString ( $searchString ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $entityTypes  =  array_keys ( $this -> entities ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $entityTypesToSearch  =  $entityTypes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $results  =  collect (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( $entityType  !==  'all' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $entityTypesToSearch  =  $entityType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( isset ( $terms [ 'filters' ][ 'type' ]))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $entityTypesToSearch  =  explode ( '|' ,  $terms [ 'filters' ][ 'type' ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $total  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        foreach  ( $entityTypesToSearch  as  $entityType )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! in_array ( $entityType ,  $entityTypes ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $search  =  $this -> searchEntityTable ( $terms ,  $entityType ,  $page ,  $count ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $total  +=  $this -> searchEntityTable ( $terms ,  $entityType ,  $page ,  $count ,  true ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $results  =  $results -> merge ( $search ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'total'  =>  $total , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'count'  =>  count ( $results ), 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-27 00:17:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            'results'  =>  $results -> sortByDesc ( 'score' ) -> values () 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        ]; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:16:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Search  a  book  for  entities 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  integer  $bookId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  string  $searchString 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  Collection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  searchBook ( $bookId ,  $searchString ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $terms  =  $this -> parseSearchString ( $searchString ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $entityTypes  =  [ 'page' ,  'chapter' ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $entityTypesToSearch  =  isset ( $terms [ 'filters' ][ 'type' ])  ?  explode ( '|' ,  $terms [ 'filters' ][ 'type' ])  :  $entityTypes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:16:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $results  =  collect (); 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:31:11 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        foreach  ( $entityTypesToSearch  as  $entityType )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ( ! in_array ( $entityType ,  $entityTypes ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:31:11 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $search  =  $this -> buildEntitySearchQuery ( $terms ,  $entityType ) -> where ( 'book_id' ,  '=' ,  $bookId ) -> take ( 20 ) -> get (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $results  =  $results -> merge ( $search ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $results -> sortByDesc ( 'score' ) -> take ( 20 ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:16:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Search  a  book  for  entities 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  integer  $chapterId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  string  $searchString 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  Collection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  searchChapter ( $chapterId ,  $searchString ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $terms  =  $this -> parseSearchString ( $searchString ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $pages  =  $this -> buildEntitySearchQuery ( $terms ,  'page' ) -> where ( 'chapter_id' ,  '=' ,  $chapterId ) -> take ( 20 ) -> get (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $pages -> sortByDesc ( 'score' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Search  across  a  particular  entity  type . 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     *  @ param  array  $terms 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     *  @ param  string  $entityType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  int  $page 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  int  $count 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     *  @ param  bool  $getCount  Return  the  total  count  of  the  search 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  \Illuminate\Database\Eloquent\Collection | int | static [] 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-15 22:04:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    public  function  searchEntityTable ( $terms ,  $entityType  =  'page' ,  $page  =  1 ,  $count  =  20 ,  $getCount  =  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:16:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $query  =  $this -> buildEntitySearchQuery ( $terms ,  $entityType ); 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( $getCount )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  $query -> count (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:16:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $query  =  $query -> skip (( $page - 1 )  *  $count ) -> take ( $count ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $query -> get (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Create  a  search  query  for  an  entity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  array  $terms 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  string  $entityType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  \Illuminate\Database\Eloquent\Builder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  buildEntitySearchQuery ( $terms ,  $entityType  =  'page' ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $entity  =  $this -> getEntity ( $entityType ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $entitySelect  =  $entity -> newQuery (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Handle normal search terms
 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( count ( $terms [ 'search' ])  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $subQuery  =  $this -> db -> table ( 'search_terms' ) -> select ( 'entity_id' ,  'entity_type' ,  \DB :: raw ( 'SUM(score) as score' )); 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-24 03:27:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            $subQuery -> where ( 'entity_type' ,  '=' ,  'BookStack\\'  .  ucfirst ( $entityType )); 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $subQuery -> where ( function  ( Builder  $query )  use  ( $terms )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                foreach  ( $terms [ 'search' ]  as  $inputTerm )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                    $query -> orWhere ( 'term' ,  'like' ,  $inputTerm  . '%' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }) -> groupBy ( 'entity_type' ,  'entity_id' ); 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $entitySelect -> join ( \DB :: raw ( '('  .  $subQuery -> toSql ()  .  ') as s' ),  function  ( JoinClause  $join )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                $join -> on ( 'id' ,  '=' ,  'entity_id' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }) -> selectRaw ( $entity -> getTable () . '.*, s.score' ) -> orderBy ( 'score' ,  'desc' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $entitySelect -> mergeBindings ( $subQuery ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Handle exact term matching
 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( count ( $terms [ 'exact' ])  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $entitySelect -> where ( function  ( \Illuminate\Database\Eloquent\Builder  $query )  use  ( $terms ,  $entity )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                foreach  ( $terms [ 'exact' ]  as  $inputTerm )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                    $query -> where ( function  ( \Illuminate\Database\Eloquent\Builder  $query )  use  ( $inputTerm ,  $entity )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        $query -> where ( 'name' ,  'like' ,  '%' . $inputTerm  . '%' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            -> orWhere ( $entity -> textField ,  'like' ,  '%' . $inputTerm  . '%' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // Handle tag searches
 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        foreach  ( $terms [ 'tags' ]  as  $inputTerm )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $this -> applyTagSearch ( $entitySelect ,  $inputTerm ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Handle filters
 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        foreach  ( $terms [ 'filters' ]  as  $filterTerm  =>  $filterValue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $functionName  =  camel_case ( 'filter_'  .  $filterTerm ); 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ( method_exists ( $this ,  $functionName ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $this -> $functionName ( $entitySelect ,  $entity ,  $filterValue ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-16 02:16:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  $this -> permissionService -> enforceEntityRestrictions ( $entityType ,  $entitySelect ,  'view' ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Parse  a  search  string  into  components . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  $searchString 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  array 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    protected  function  parseSearchString ( $searchString ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $terms  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'search'  =>  [], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'exact'  =>  [], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'tags'  =>  [], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'filters'  =>  [] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $patterns  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'exact'  =>  '/"(.*?)"/' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'tags'  =>  '/\[(.*?)\]/' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'filters'  =>  '/\{(.*?)\}/' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // Parse special terms
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        foreach  ( $patterns  as  $termType  =>  $pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $matches  =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            preg_match_all ( $pattern ,  $searchString ,  $matches ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( count ( $matches )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $terms [ $termType ]  =  $matches [ 1 ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $searchString  =  preg_replace ( $pattern ,  '' ,  $searchString ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // Parse standard terms
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        foreach  ( explode ( ' ' ,  trim ( $searchString ))  as  $searchTerm )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ( $searchTerm  !==  '' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $terms [ 'search' ][]  =  $searchTerm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // Split filter values out
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $splitFilters  =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foreach  ( $terms [ 'filters' ]  as  $filter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 04:12:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            $explodedFilter  =  explode ( ':' ,  $filter ,  2 ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 03:59:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $splitFilters [ $explodedFilter [ 0 ]]  =  ( count ( $explodedFilter )  >  1 )  ?  $explodedFilter [ 1 ]  :  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $terms [ 'filters' ]  =  $splitFilters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 18:57:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  $terms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Get  the  available  query  operators  as  a  regex  escaped  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  mixed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  getRegexEscapedOperators () 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $escapedOperators  =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foreach  ( $this -> queryOperators  as  $operator )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $escapedOperators []  =  preg_quote ( $operator ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  join ( '|' ,  $escapedOperators ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Apply  a  tag  search  term  onto  a  entity  query . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  \Illuminate\Database\Eloquent\Builder  $query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  string  $tagTerm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  mixed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    protected  function  applyTagSearch ( \Illuminate\Database\Eloquent\Builder  $query ,  $tagTerm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        preg_match ( " /^(.*?)(( " . $this -> getRegexEscapedOperators () . " )(.*?))? $ / " ,  $tagTerm ,  $tagSplit ); 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> whereHas ( 'tags' ,  function  ( \Illuminate\Database\Eloquent\Builder  $query )  use  ( $tagSplit )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $tagName  =  $tagSplit [ 1 ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $tagOperator  =  count ( $tagSplit )  >  2  ?  $tagSplit [ 3 ]  :  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $tagValue  =  count ( $tagSplit )  >  3  ?  $tagSplit [ 4 ]  :  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $validOperator  =  in_array ( $tagOperator ,  $this -> queryOperators ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! empty ( $tagOperator )  &&  ! empty ( $tagValue )  &&  $validOperator )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                if  ( ! empty ( $tagName ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $query -> where ( 'name' ,  '=' ,  $tagName ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                if  ( is_numeric ( $tagValue )  &&  $tagOperator  !==  'like' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // We have to do a raw sql query for this since otherwise PDO will quote the value and MySQL will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // search the value as a string which prevents being able to do number-based operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // on the tag values. We ensure it has a numeric value and then cast it just to be sure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $tagValue  =  ( float )  trim ( $query -> getConnection () -> getPdo () -> quote ( $tagValue ),  " ' " ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $query -> whereRaw ( " value  ${ tagOperator }   ${ tagValue } " ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $query -> where ( 'value' ,  $tagOperator ,  $tagValue ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $query -> where ( 'name' ,  '=' ,  $tagName ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $query ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Get  an  entity  instance  via  type . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  $type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  Entity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  getEntity ( $type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $this -> entities [ strtolower ( $type )]; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Index  the  given  entity . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Entity  $entity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  indexEntity ( Entity  $entity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> deleteEntityTerms ( $entity ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $nameTerms  =  $this -> generateTermArrayFromText ( $entity -> name ,  5 ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $bodyTerms  =  $this -> generateTermArrayFromText ( $entity -> getText (),  1 ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $terms  =  array_merge ( $nameTerms ,  $bodyTerms ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:34:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        foreach  ( $terms  as  $index  =>  $term )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $terms [ $index ][ 'entity_type' ]  =  $entity -> getMorphClass (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $terms [ $index ][ 'entity_id' ]  =  $entity -> id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> searchTerm -> newQuery () -> insert ( $terms ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Index  multiple  Entities  at  once 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Entity []  $entities 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    protected  function  indexEntities ( $entities ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $terms  =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foreach  ( $entities  as  $entity )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $nameTerms  =  $this -> generateTermArrayFromText ( $entity -> name ,  5 ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $bodyTerms  =  $this -> generateTermArrayFromText ( $entity -> getText (),  1 ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            foreach  ( array_merge ( $nameTerms ,  $bodyTerms )  as  $term )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $term [ 'entity_id' ]  =  $entity -> id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $term [ 'entity_type' ]  =  $entity -> getMorphClass (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $terms []  =  $term ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $chunkedTerms  =  array_chunk ( $terms ,  500 ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foreach  ( $chunkedTerms  as  $termChunk )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:34:53 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $this -> searchTerm -> newQuery () -> insert ( $termChunk ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Delete  and  re - index  the  terms  for  all  entities  in  the  system . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  indexAllEntities () 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> searchTerm -> truncate (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Chunk through all books
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $this -> book -> chunk ( 1000 ,  function  ( $books )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $this -> indexEntities ( $books ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Chunk through all chapters
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $this -> chapter -> chunk ( 1000 ,  function  ( $chapters )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $this -> indexEntities ( $chapters ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Chunk through all pages
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:24:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $this -> page -> chunk ( 1000 ,  function  ( $pages )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $this -> indexEntities ( $pages ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Delete  related  Entity  search  terms . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  Entity  $entity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  deleteEntityTerms ( Entity  $entity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $entity -> searchTerms () -> delete (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Create  a  scored  term  array  from  the  given  text . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  $text 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  float | int  $scoreAdjustment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  array 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  generateTermArrayFromText ( $text ,  $scoreAdjustment  =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $tokenMap  =  [];  // {TextToken => OccurrenceCount}
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-16 01:51:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $splitChars  =  "   \n \t .,!?:;()[] { }<>`' \" " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-30 21:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $token  =  strtok ( $text ,  $splitChars ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( $token  !==  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ( ! isset ( $tokenMap [ $token ]))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $tokenMap [ $token ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $tokenMap [ $token ] ++ ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-30 21:14:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $token  =  strtok ( $splitChars ); 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 20:48:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $terms  =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foreach  ( $tokenMap  as  $token  =>  $count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $terms []  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                'term'  =>  $token , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                'score'  =>  $count  *  $scoreAdjustment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $terms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Custom  entity  search  filters 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterUpdatedAfter ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $date  =  date_create ( $input ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( \Exception  $e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'updated_at' ,  '>=' ,  $date ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterUpdatedBefore ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $date  =  date_create ( $input ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( \Exception  $e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'updated_at' ,  '<' ,  $date ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterCreatedAfter ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $date  =  date_create ( $input ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( \Exception  $e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'created_at' ,  '>=' ,  $date ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterCreatedBefore ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $date  =  date_create ( $input ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( \Exception  $e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'created_at' ,  '<' ,  $date ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterCreatedBy ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( ! is_numeric ( $input )  &&  $input  !==  'me' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( $input  ===  'me' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input  =  user () -> id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'created_by' ,  '=' ,  $input ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterUpdatedBy ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( ! is_numeric ( $input )  &&  $input  !==  'me' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( $input  ===  'me' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $input  =  user () -> id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'updated_by' ,  '=' ,  $input ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterInName ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'name' ,  'like' ,  '%'  . $input .  '%' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    protected  function  filterInTitle ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $this -> filterInName ( $query ,  $model ,  $input ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterInBody ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $query -> where ( $model -> textField ,  'like' ,  '%'  . $input .  '%' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterIsRestricted ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $query -> where ( 'restricted' ,  '=' ,  true ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterViewedByMe ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> whereHas ( 'views' ,  function  ( $query )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $query -> where ( 'user_id' ,  '=' ,  user () -> id ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  filterNotViewedByMe ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $query -> whereDoesntHave ( 'views' ,  function  ( $query )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 01:05:34 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $query -> where ( 'user_id' ,  '=' ,  user () -> id ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-01 18:24:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    protected  function  filterSortBy ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ,  $input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $functionName  =  camel_case ( 'sort_by_'  .  $input ); 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( method_exists ( $this ,  $functionName ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $this -> $functionName ( $query ,  $model ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-01 18:24:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Sorting  filter  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  function  sortByLastCommented ( \Illuminate\Database\Eloquent\Builder  $query ,  Entity  $model ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $commentsTable  =  $this -> db -> getTablePrefix ()  .  'comments' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $morphClass  =  str_replace ( '\\' ,  '\\\\' ,  $model -> getMorphClass ()); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $commentQuery  =  $this -> db -> raw ( '(SELECT c1.entity_id, c1.entity_type, c1.created_at as last_commented FROM ' . $commentsTable . ' c1 LEFT JOIN ' . $commentsTable . ' c2 ON (c1.entity_id = c2.entity_id AND c1.entity_type = c2.entity_type AND c1.created_at < c2.created_at) WHERE c1.entity_type = \'' .  $morphClass  . '\' AND c2.created_at IS NULL) as comments' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $query -> join ( $commentQuery ,  $model -> getTable ()  .  '.id' ,  '=' ,  'comments.entity_id' ) -> orderBy ( 'last_commented' ,  'desc' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-29 00:58:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}