/** * Load a collection of xPDOObject instances. * * @static * @param xPDO &$xpdo A valid xPDO instance. * @param string $className Name of the class. * @param mixed $criteria A valid primary key, criteria array, or xPDOCriteria instance. * @param boolean|integer $cacheFlag Indicates if the objects should be * cached and optionally, by specifying an integer value, for how many * seconds. * @return array An array of xPDOObject instances or an empty array if no instances are loaded. */ public static function loadCollection(xPDO &$xpdo, $className, $criteria = null, $cacheFlag = true) { $objCollection = array(); $fromCache = false; if (!($className = $xpdo->loadClass($className))) { return $objCollection; } $rows = false; $fromCache = false; $collectionCaching = (int) $xpdo->getOption(xPDO::OPT_CACHE_DB_COLLECTIONS, array(), 1); if (!is_object($criteria)) { $criteria = $xpdo->getCriteria($className, $criteria, $cacheFlag); } if (is_object($criteria)) { $criteria = $xpdo->addDerivativeCriteria($className, $criteria); } if ($collectionCaching > 0 && $xpdo->_cacheEnabled && $cacheFlag) { $rows = $xpdo->fromCache($criteria); $fromCache = is_array($rows) && !empty($rows); } if (!$fromCache && is_object($criteria)) { $rows = xPDOObject::_loadRows($xpdo, $className, $criteria); } if (is_array($rows)) { foreach ($rows as $row) { xPDOObject::_loadCollectionInstance($xpdo, $objCollection, $className, $criteria, $row, $fromCache, $cacheFlag); } } elseif (is_object($rows)) { $cacheRows = array(); while ($row = $rows->fetch(PDO::FETCH_ASSOC)) { xPDOObject::_loadCollectionInstance($xpdo, $objCollection, $className, $criteria, $row, $fromCache, $cacheFlag); if ($collectionCaching > 0 && $xpdo->_cacheEnabled && $cacheFlag && !$fromCache) { $cacheRows[] = $row; } } if ($collectionCaching > 0 && $xpdo->_cacheEnabled && $cacheFlag && !$fromCache) { $rows =& $cacheRows; } } if (!$fromCache && $xpdo->_cacheEnabled && $collectionCaching > 0 && $cacheFlag && !empty($rows)) { $xpdo->toCache($criteria, $rows, $cacheFlag); } return $objCollection; }
/** * Run the search based on the specified search string. * * @param string $string The string to run the search on. * @param int $limit The number of results to limit to. * @param int $start The starting result index to search from. * @param array $conditions An array of conditions to add to the search filter. * @return array An array of search results. */ public function run($string, $limit = 10, $start = 0, array $conditions = array()) { $response = array('results' => array(), 'total' => 0); $grouped = $this->modx->getOption('discuss.group_by_thread', '', 1); $c = $this->modx->newQuery('disPost'); $c->innerJoin('disThread', 'Thread'); $c->innerJoin('disBoard', 'Board'); $c->innerJoin('disUser', 'Author'); $c->where(array("MATCH (disPost.title,disPost.message) AGAINST ({$this->modx->quote($string, PDO::PARAM_STR)} IN BOOLEAN MODE)", 'Thread.private' => 0)); if ($this->discuss->user->isLoggedIn) { $ignoreBoards = $this->discuss->user->get('ignore_boards'); if (!empty($ignoreBoards)) { $c->where(array('Board.id:NOT IN' => explode(',', $ignoreBoards))); } } if (!empty($conditions['board'])) { $c->where(array('Board.id:IN' => $conditions['board'])); } if (!empty($conditions['author'])) { if (is_string($conditions['author'])) { $c->where(array('Author.username' => $conditions['author'])); } else { $c->where(array('author' => $conditions['author'])); } } if (!empty($conditions['class_key'])) { $c->where(array('Thread.class_key' => $conditions['class_key'])); if (!empty($conditions['answered']) && !is_null($conditions['answered'])) { $c->where(array('Thread.answered' => $conditions['answered'])); } } if (!empty($conditions['createdon'])) { $c->where(array("{$this->modx->escape('disPost')}.{$this->modx->escape('createdon')} {$conditions['createdon']}")); } $c->select(array($this->modx->getSelectColumns('disPost', 'disPost', 'group_', array('thread')), 'replies' => 'Thread.replies', 'username' => 'Author.username', 'board_name' => 'Board.name', "MATCH (disPost.title,disPost.message) AGAINST ({$this->modx->quote($string, PDO::PARAM_STR)} IN BOOLEAN MODE) AS score")); $c->select($this->modx->getSelectColumns('disPost', 'disPost')); $c->sortby('score', 'DESC'); $rowsFetched = (int) $this->modx->getOption('discuss.max_search_results', '', 500); if ($grouped) { $rowsFetched += (int) $this->modx->getOption('discuss.search_results_buffer', '', 200); } $c->limit($rowsFetched); $c->prepare(); if (!$c->stmt->execute()) { $errorInfo = $c->stmt->errorInfo(); $this->modx->log(xPDO::LOG_LEVEL_ERROR, "Error " . $c->stmt->errorCode() . " executing statement:\n" . $c->toSQL() . "\n" . print_r($errorInfo, true)); return $response; } $threads = array(); $i = 0; // used for thread grouping $skip = 0; // skip to start, if necessary $posts = array(); if ($grouped) { $rows = $c->stmt->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_GROUP); } else { $rows = $c->stmt->fetchAll(PDO::FETCH_ASSOC); } foreach ($rows as $row) { if ($skip < $start) { // Scroll to start or skip thread if found already $skip++; continue; } if ($grouped) { $row = $row[0]; } xPDOObject::_loadCollectionInstance($this->modx, $posts, 'disPost', $c, $row, false, false); $i++; if ($i == $limit || $i == count($rows)) { // $limit results found; get total row count, closeCursor (just in case) and exit while loop $response['total'] = count($rows) > (int) $this->modx->getOption('discuss.max_search_results', '', 500) ? (int) $this->modx->getOption('discuss.max_search_results', '', 500) : count($rows); $c->stmt->closeCursor(); break; } } foreach ($posts as $post) { $postArray = $post->toArray('', true, true); $postArray['message'] = $post->getContent(); $response['results'][] = $postArray; } return $response; }