Example #1
0
 public function count()
 {
     $meta = Helper::create($this->library->getConnection())->showMeta()->execute();
     foreach ($meta as $m) {
         if ($m['Variable_name'] == 'total_found') {
             return $m['Value'];
         }
     }
 }
Example #2
0
 public function testSetVariable()
 {
     Helper::create($this->conn)->setVariable('AUTOCOMMIT', 0)->execute();
     $vars = Helper::pairsToAssoc(Helper::create($this->conn)->showVariables()->execute());
     $this->assertEquals(0, $vars['autocommit']);
     Helper::create($this->conn)->setVariable('AUTOCOMMIT', 1)->execute();
     $vars = Helper::pairsToAssoc(Helper::create($this->conn)->showVariables()->execute());
     $this->assertEquals(1, $vars['autocommit']);
     Helper::create($this->conn)->setVariable('@foo', 1, true);
     Helper::create($this->conn)->setVariable('@foo', array(0), true);
 }
 public function testMiscellaneous()
 {
     $query = Helper::create($this->conn)->showMeta();
     $this->assertEquals('SHOW META', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->showWarnings();
     $this->assertEquals('SHOW WARNINGS', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->showStatus();
     $this->assertEquals('SHOW STATUS', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->attachIndex('disk', 'rt');
     $this->assertEquals('ATTACH INDEX `disk` TO RTINDEX `rt`', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->flushRtIndex('rt');
     $this->assertEquals('FLUSH RTINDEX `rt`', $query->compile()->getCompiled());
 }
Example #4
0
 public static function searchPaths($keyword, &$count)
 {
     $conn = self::getSphinxConnection();
     $query = SphinxQL::create($conn)->select('*')->from('mangaindex_paths')->where('directory', '=', 1)->limit(0, 100);
     $escaped = $query->halfEscapeMatch($keyword);
     $escaped = str_replace('?', '\\?', $escaped);
     // "?" behaves strangely and doesn't get escaped by the above
     $query->match('*', $escaped);
     $result = $query->execute();
     $ids = self::getIds($result);
     $metaResult = Helper::create($conn)->showMeta()->execute();
     $meta = self::sortMeta($metaResult);
     $count = $meta['total_found'];
     if (count($ids) > 0) {
         $records = PathRecord::whereIn('id', $ids)->get();
         return $records;
     } else {
         return array();
     }
 }
Example #5
0
 /**
  * Gets the search results
  *
  * @return  \Foolz\Foolfuuka\Model\Search  The current object
  * @throws  SearchEmptyResultException     If there's no results to display
  * @throws  SearchRequiresSphinxException  If the search submitted requires Sphinx to run
  * @throws  SearchSphinxOfflineException   If the Sphinx server is unreachable
  * @throws  SearchInvalidException         If the values of the search weren't compatible with the domain
  */
 protected function p_getSearchComments()
 {
     $this->profiler->log('Board::getSearchComments Start');
     extract($this->options);
     // set all empty fields to null
     $search_fields = ['boards', 'subject', 'text', 'username', 'tripcode', 'email', 'capcode', 'uid', 'poster_ip', 'filename', 'image', 'deleted', 'ghost', 'filter', 'type', 'start', 'end', 'results', 'order'];
     foreach ($search_fields as $field) {
         if (!isset($args[$field])) {
             $args[$field] = null;
         }
     }
     // populate an array containing all boards that would be searched
     $boards = [];
     if ($args['boards'] !== null) {
         foreach ($args['boards'] as $board) {
             $b = $this->radix_coll->getByShortname($board);
             if ($b) {
                 $boards[] = $b;
             }
         }
     }
     // search all boards if none selected
     if (count($boards) == 0) {
         $boards = $this->radix_coll->getAll();
     }
     // if image is set, get either the media_hash or media_id
     if ($args['image'] !== null) {
         if (substr($args['image'], -2) !== '==') {
             $args['image'] .= '==';
         }
         // if board is set, retrieve media_id
         if ($this->radix !== null) {
             try {
                 $media = $this->media_factory->getByMediaHash($this->radix, $args['image']);
             } catch (MediaNotFoundException $e) {
                 $this->comments_unsorted = [];
                 $this->comments = [];
                 $this->profiler->log('Board::getSearchComments Ended Prematurely');
                 throw new SearchEmptyResultException(_i('No results found.'));
             }
             $args['image'] = $media->media_id;
         }
     }
     if ($this->radix === null && !$this->preferences->get('foolfuuka.sphinx.global')) {
         // global search requires sphinx
         throw new SearchRequiresSphinxException(_i('Sorry, this action requires the Sphinx to be installed and running.'));
     } elseif ($this->radix === null && $this->preferences->get('foolfuuka.sphinx.global') || $this->radix !== null && $this->radix->sphinx) {
         // configure sphinx connection params
         $sphinx = explode(':', $this->preferences->get('foolfuuka.sphinx.listen'));
         $conn = new SphinxConnnection();
         $conn->setParams(['host' => $sphinx[0], 'port' => $sphinx[1], 'options' => [MYSQLI_OPT_CONNECT_TIMEOUT => 5]]);
         $conn->silenceConnectionWarning(true);
         // establish connection
         try {
             SphinxQL::forge($conn);
         } catch (\Foolz\SphinxQL\ConnectionException $e) {
             throw new SearchSphinxOfflineException(_i('The search backend is currently unavailable.'));
         }
         // determine if all boards will be used for search or not
         if ($this->radix == null) {
             $indexes = [];
             foreach ($boards as $radix) {
                 if (!$radix->sphinx) {
                     continue;
                 }
                 $indexes[] = $radix->shortname . '_ancient';
                 $indexes[] = $radix->shortname . '_main';
                 $indexes[] = $radix->shortname . '_delta';
             }
         } else {
             $indexes = [$this->radix->shortname . '_ancient', $this->radix->shortname . '_main', $this->radix->shortname . '_delta'];
         }
         // start search query
         $query = SphinxQL::forge()->select('id', 'board')->from($indexes);
         // parse search params
         if ($args['subject'] !== null) {
             $query->match('title', $args['subject']);
         }
         if ($args['text'] !== null) {
             if (mb_strlen($args['text'], 'utf-8') < 1) {
                 return [];
             }
             $query->match('comment', $args['text'], true);
         }
         if ($args['username'] !== null) {
             $query->match('name', $args['username']);
         }
         if ($args['tripcode'] !== null) {
             $query->match('trip', '"' . $args['tripcode'] . '"');
         }
         if ($args['email'] !== null) {
             $query->match('email', $args['email']);
         }
         if ($args['capcode'] !== null) {
             if ($args['capcode'] === 'user') {
                 $query->where('cap', ord('N'));
             } elseif ($args['capcode'] === 'mod') {
                 $query->where('cap', ord('M'));
             } elseif ($args['capcode'] === 'admin') {
                 $query->where('cap', ord('A'));
             } elseif ($args['capcode'] === 'dev') {
                 $query->where('cap', ord('D'));
             }
         }
         if ($args['uid'] !== null) {
             $query->match('pid', $args['uid']);
         }
         if ($this->getAuth()->hasAccess('comment.see_ip') && $args['poster_ip'] !== null) {
             $query->where('pip', (int) Inet::ptod($args['poster_ip']));
         }
         if ($args['filename'] !== null) {
             $query->match('media_filename', $args['filename']);
         }
         if ($args['image'] !== null) {
             if ($this->radix !== null) {
                 $query->where('mid', (int) $args['image']);
             } else {
                 $query->match('media_hash', '"' . $args['image'] . '"');
             }
         }
         if ($args['deleted'] !== null) {
             if ($args['deleted'] == 'deleted') {
                 $query->where('is_deleted', 1);
             }
             if ($args['deleted'] == 'not-deleted') {
                 $query->where('is_deleted', 0);
             }
         }
         if ($args['ghost'] !== null) {
             if ($args['ghost'] == 'only') {
                 $query->where('is_internal', 1);
             }
             if ($args['ghost'] == 'none') {
                 $query->where('is_internal', 0);
             }
         }
         if ($args['filter'] !== null) {
             if ($args['filter'] == 'image') {
                 $query->where('has_image', 0);
             }
             if ($args['filter'] == 'text') {
                 $query->where('has_image', 1);
             }
         }
         if ($args['type'] !== null) {
             if ($args['type'] == 'sticky') {
                 $query->where('is_sticky', 1);
             }
             if ($args['type'] == 'op') {
                 $query->where('is_op', 1);
             }
             if ($args['type'] == 'posts') {
                 $query->where('is_op', 0);
             }
         }
         if ($args['start'] !== null) {
             $query->where('timestamp', '>=', intval(strtotime($args['start'])));
         }
         if ($args['end'] !== null) {
             $query->where('timestamp', '<=', intval(strtotime($args['end'])));
         }
         if ($args['results'] !== null) {
             if ($args['results'] == 'op') {
                 $query->groupBy('thread_num');
                 $query->withinGroupOrderBy('is_op', 'desc');
             }
             if ($args['results'] == 'posts') {
                 $query->where('is_op', 0);
             }
         }
         if ($args['order'] !== null && $args['order'] == 'asc') {
             $query->orderBy('timestamp', 'ASC');
         } else {
             $query->orderBy('timestamp', 'DESC');
         }
         $max_matches = $this->preferences->get('foolfuuka.sphinx.max_matches', 5000);
         // set sphinx options
         $query->limit($limit)->offset($page * $limit - $limit >= $max_matches ? $max_matches - 1 : $page * $limit - $limit)->option('max_matches', (int) $max_matches)->option('reverse_scan', $args['order'] === 'asc' ? 0 : 1);
         // submit query
         try {
             $search = $query->execute();
         } catch (\Foolz\SphinxQL\DatabaseException $e) {
             $this->logger->error('Search Error: ' . $e->getMessage());
             throw new SearchInvalidException(_i('The search backend returned an error.'));
         }
         // no results found
         if (!count($search)) {
             $this->comments_unsorted = [];
             $this->comments = [];
             throw new SearchEmptyResultException(_i('No results found.'));
         }
         $sphinx_meta = Helper::pairsToAssoc(Helper::create($conn)->showMeta()->execute());
         $this->total_count = $sphinx_meta['total'];
         $this->total_found = $sphinx_meta['total_found'];
         // populate sql array for full records
         $sql = [];
         foreach ($search as $doc => $result) {
             $board = $this->radix_coll->getById($result['board']);
             $sql[] = $this->dc->qb()->select('*, ' . $result['board'] . ' AS board_id')->from($board->getTable(), 'r')->leftJoin('r', $board->getTable('_images'), 'mg', 'mg.media_id = r.media_id')->where('doc_id = ' . $this->dc->getConnection()->quote($result['id']))->getSQL();
         }
         $result = $this->dc->getConnection()->executeQuery(implode(' UNION ', $sql))->fetchAll();
     } else {
         // this is not implemented yet, would require some sort of MySQL search
         throw new SearchRequiresSphinxException(_i('Sorry, this board does not have search enabled.'));
     }
     // no results found IN DATABASE, but we might still get a search count from Sphinx
     if (!count($result)) {
         $this->comments_unsorted = [];
         $this->comments = [];
     } else {
         // process results
         foreach ($result as $key => $row) {
             $board = $this->radix !== null ? $this->radix : $this->radix_coll->getById($row['board_id']);
             $bulk = new CommentBulk();
             $bulk->import($row, $board);
             $this->comments_unsorted[] = $bulk;
             unset($result[$key]);
         }
     }
     $this->comments[0]['posts'] = $this->comments_unsorted;
     return $this;
 }
 /**
  * @covers \Foolz\SphinxQL\SphinxQL::executeBatch
  * @covers \Foolz\SphinxQL\SphinxQL::enqueue
  * @covers \Foolz\SphinxQL\SphinxQL::getQueue
  * @covers \Foolz\SphinxQL\SphinxQL::getQueuePrev
  * @covers \Foolz\SphinxQL\SphinxQL::setQueuePrev
  */
 public function testQueue()
 {
     $this->refill();
     $result = SphinxQL::create(self::$conn)->select()->from('rt')->where('gid', 9003)->enqueue(Helper::create(self::$conn)->showMeta())->enqueue()->select()->from('rt')->where('gid', 201)->executeBatch()->getStored();
     $this->assertEquals('10', $result[0][0]['id']);
     $this->assertEquals('1', $result[1][0]['Value']);
     $this->assertEquals('11', $result[2][0]['id']);
 }
 public function testMiscellaneous()
 {
     $query = Helper::create($this->conn)->showMeta();
     $this->assertEquals('SHOW META', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->showWarnings();
     $this->assertEquals('SHOW WARNINGS', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->showStatus();
     $this->assertEquals('SHOW STATUS', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->attachIndex('disk', 'rt');
     $this->assertEquals('ATTACH INDEX disk TO RTINDEX rt', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->flushRtIndex('rt');
     $this->assertEquals('FLUSH RTINDEX rt', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->optimizeIndex('rt');
     $this->assertEquals('OPTIMIZE INDEX rt', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->showIndexStatus('rt');
     $this->assertEquals('SHOW INDEX rt STATUS', $query->compile()->getCompiled());
     $query = Helper::create($this->conn)->flushRamchunk('rt');
     $this->assertEquals('FLUSH RAMCHUNK rt', $query->compile()->getCompiled());
 }
Example #8
0
 /**
  * Gets the search results
  *
  * @return  \Foolz\FoolFuuka\Model\Search  The current object
  * @throws  SearchEmptyResultException     If there's no results to display
  * @throws  SearchRequiresSphinxException  If the search submitted requires Sphinx to run
  * @throws  SearchSphinxOfflineException   If the Sphinx server is unreachable
  * @throws  SearchInvalidException         If the values of the search weren't compatible with the domain
  */
 protected function p_getResults()
 {
     $this->profiler->log('Search::getResults Start');
     extract($this->options);
     $boards = [];
     $input = $this->getUserInput();
     if ($this->radix !== null) {
         $boards[] = $this->radix;
     } elseif ($input['boards'] !== null) {
         foreach ($input['boards'] as $board) {
             $b = $this->radix_coll->getByShortname($board);
             if ($b) {
                 $boards[] = $b;
             }
         }
     }
     // search all boards if none selected
     if (count($boards) == 0) {
         $boards = $this->radix_coll->getAll();
     }
     // if image is set, get either the media_hash or media_id
     if ($input['image'] !== null && substr($input['image'], -2) !== '==') {
         $input['image'] .= '==';
     }
     if ($this->radix === null && !$this->preferences->get('foolfuuka.sphinx.global')) {
         throw new SearchRequiresSphinxException(_i('Sorry, the global search function has not been enabled.'));
     }
     if ($this->radix !== null && !$this->radix->sphinx) {
         throw new SearchRequiresSphinxException(_i('Sorry, this board does not have search enabled.'));
     }
     $sphinx = explode(':', $this->preferences->get('foolfuuka.sphinx.listen'));
     $conn = new SphinxConnnection();
     $conn->setParams(['host' => $sphinx[0], 'port' => $sphinx[1], 'options' => [MYSQLI_OPT_CONNECT_TIMEOUT => 5]]);
     $indices = [];
     foreach ($boards as $radix) {
         if (!$radix->sphinx) {
             continue;
         }
         $indices[] = $radix->shortname . '_ancient';
         $indices[] = $radix->shortname . '_main';
         $indices[] = $radix->shortname . '_delta';
     }
     // establish connection
     try {
         $query = SphinxQL::create($conn)->select('id', 'board', 'tnum')->from($indices)->setFullEscapeChars(['\\', '(', ')', '|', '-', '!', '@', '%', '~', '"', '&', '/', '^', '$', '='])->setHalfEscapeChars(['\\', '(', ')', '!', '@', '%', '~', '&', '/', '^', '$', '=']);
     } catch (\Foolz\SphinxQL\Exception\ConnectionException $e) {
         throw new SearchSphinxOfflineException($this->preferences->get('foolfuuka.sphinx.custom_message', _i('The search backend is currently unavailable.')));
     }
     // process user input
     if ($input['subject'] !== null) {
         $query->match('title', $input['subject']);
     }
     if ($input['text'] !== null) {
         if (mb_strlen($input['text'], 'utf-8') < 1) {
             return [];
         }
         $query->match('comment', $input['text'], true);
     }
     if ($input['username'] !== null) {
         $query->match('name', $input['username']);
     }
     if ($input['tripcode'] !== null) {
         $query->match('trip', '"' . $input['tripcode'] . '"');
     }
     if ($input['email'] !== null) {
         $query->match('email', $input['email']);
     }
     if ($input['capcode'] !== null) {
         switch ($input['capcode']) {
             case 'user':
                 $query->where('cap', ord('N'));
                 break;
             case 'mod':
                 $query->where('cap', ord('M'));
                 break;
             case 'dev':
                 $query->where('cap', ord('D'));
                 break;
             case 'admin':
                 $query->where('cap', ord('A'));
                 break;
         }
     }
     if ($input['uid'] !== null) {
         $query->match('pid', $input['uid']);
     }
     if ($input['country'] !== null) {
         $query->match('country', $input['country'], true);
     }
     if ($this->getAuth()->hasAccess('comment.see_ip') && $input['poster_ip'] !== null) {
         $query->where('pip', (int) Inet::ptod($input['poster_ip']));
     }
     if ($input['filename'] !== null) {
         $query->match('media_filename', $input['filename']);
     }
     if ($input['image'] !== null) {
         $query->match('media_hash', '"' . $input['image'] . '"');
     }
     if ($input['deleted'] !== null) {
         switch ($input['deleted']) {
             case 'deleted':
                 $query->where('is_deleted', 1);
                 break;
             case 'not-deleted':
                 $query->where('is_deleted', 0);
                 break;
         }
     }
     if ($input['ghost'] !== null) {
         switch ($input['ghost']) {
             case 'only':
                 $query->where('is_internal', 1);
                 break;
             case 'none':
                 $query->where('is_internal', 0);
                 break;
         }
     }
     if ($input['filter'] !== null) {
         switch ($input['filter']) {
             case 'image':
                 $query->where('has_image', 0);
                 break;
             case 'text':
                 $query->where('has_image', 1);
                 break;
         }
     }
     if ($input['type'] !== null) {
         switch ($input['type']) {
             case 'sticky':
                 $query->where('is_sticky', 1);
                 break;
             case 'op':
                 $query->where('is_op', 1);
                 break;
             case 'posts':
                 $query->where('is_op', 0);
                 break;
         }
     }
     if ($input['start'] !== null) {
         $query->where('timestamp', '>=', intval(strtotime($input['start'])));
     }
     if ($input['end'] !== null) {
         $query->where('timestamp', '<=', intval(strtotime($input['end'])));
     }
     if ($input['results'] !== null && $input['results'] == 'thread') {
         $query->groupBy('tnum');
         $query->withinGroupOrderBy('is_op', 'desc');
     }
     if ($input['order'] !== null && $input['order'] == 'asc') {
         $query->orderBy('timestamp', 'ASC');
     } else {
         $query->orderBy('timestamp', 'DESC');
     }
     $max_matches = $this->preferences->get('foolfuuka.sphinx.max_matches', 5000);
     // set sphinx options
     $query->limit($limit)->offset($page * $limit - $limit >= $max_matches ? $max_matches - 1 : $page * $limit - $limit)->option('max_matches', (int) $max_matches)->option('reverse_scan', $input['order'] === 'asc' ? 0 : 1);
     // submit query
     try {
         $this->profiler->log('Start: SphinxQL: ' . $query->compile()->getCompiled());
         $search = $query->execute();
         $this->profiler->log('Stop: SphinxQL');
     } catch (\Foolz\SphinxQL\Exception\DatabaseException $e) {
         $this->logger->error('Search Error: ' . $e->getMessage());
         throw new SearchInvalidException(_i('The search backend returned an error.'));
     }
     // no results found
     if (!count($search)) {
         $this->comments_unsorted = [];
         $this->comments = [];
         throw new SearchEmptyResultException(_i('No results found.'));
     }
     $sphinx_meta = Helper::pairsToAssoc(Helper::create($conn)->showMeta()->execute());
     $this->total_count = $sphinx_meta['total'];
     $this->total_found = $sphinx_meta['total_found'];
     // populate sql array for full records
     $sql = [];
     foreach ($search as $doc => $result) {
         $board = $this->radix_coll->getById($result['board']);
         if ($input['results'] !== null && $input['results'] == 'thread') {
             $post = 'num = ' . $this->dc->getConnection()->quote($result['tnum']) . ' AND subnum = 0';
         } else {
             $post = 'doc_id = ' . $this->dc->getConnection()->quote($result['id']);
         }
         $sql[] = $this->dc->qb()->select('*, ' . $result['board'] . ' AS board_id')->from($board->getTable(), 'r')->leftJoin('r', $board->getTable('_images'), 'mg', 'mg.media_id = r.media_id')->where($post)->getSQL();
     }
     $result = $this->dc->getConnection()->executeQuery(implode(' UNION ', $sql))->fetchAll();
     // no results found IN DATABASE, but we might still get a search count from Sphinx
     if (!count($result)) {
         $this->comments_unsorted = [];
         $this->comments = [];
     } else {
         // process results
         foreach ($result as $key => $row) {
             $board = $this->radix !== null ? $this->radix : $this->radix_coll->getById($row['board_id']);
             $bulk = new CommentBulk();
             $bulk->import($row, $board);
             $this->comments_unsorted[] = $bulk;
             unset($result[$key]);
         }
     }
     $this->comments[0]['posts'] = $this->comments_unsorted;
     return $this;
 }
Example #9
0
 /**
  * sphinx搜索实现
  *
  * @Author   tianyunzi
  * @DateTime 2015-09-23T14:26:57+0800
  * @param    [type]                   $keyword [description]
  * @return   [type]                            [description]
  */
 public function sphinxHelp($keyword, $page = 1, $limit = 20)
 {
     $stringObj = new StringHelper();
     $keyword = $stringObj->formatKeyword($keyword);
     $splitKeyword = $this->splitKeyword($keyword);
     $sphinxConfig = $this->di['config']['helpsphinx'];
     $conn = new Connection();
     $conn->setParams(array('host' => $sphinxConfig->host, 'port' => $sphinxConfig->port));
     if (count($splitKeyword) > 1) {
     } else {
         $sql = "select id from m_article where match('(@articletitle " . $splitKeyword[0] . "),(@content " . $splitKeyword[0] . ")') order by id desc limit " . $limit;
     }
     $query = SphinxQL::create($conn)->query($sql)->enqueue(Helper::create($conn)->showMeta());
     $result = array('data' => array(), 'total_found' => 0, 'time' => 0);
     try {
         $sphinxRs = $query->executeBatch();
         if (is_array($sphinxRs) && count($sphinxRs) > 0) {
             $sphinxData = $sphinxRs[0];
             $variableData = $sphinxRs[1];
         }
         if (isset($sphinxData) && is_array($sphinxData)) {
             foreach ($sphinxData as $value) {
                 $result['data'][] = $value['id'];
             }
         }
         if (isset($variableData) && is_array($variableData)) {
             foreach ($variableData as $value) {
                 if ($value['Variable_name'] == 'total_found') {
                     $result['total_found'] = $value['Value'];
                 }
                 if ($value['Variable_name'] == 'time') {
                     $result['time'] = $value['Value'];
                 }
             }
         }
     } catch (Exception $e) {
     }
     $result['data'] = implode(",", array_filter($result['data']));
     return $result;
 }