public function execute(array $deferred, array $data, $targetRunTime, &$status) { $inputHandler = new XenForo_Input($data); $input = $inputHandler->filter(array('batch' => XenForo_Input::UINT, 'start' => XenForo_Input::UINT, 'extra_data' => XenForo_Input::ARRAY_SIMPLE, 'delay' => XenForo_Input::UNUM, 'content_type' => XenForo_Input::STRING, 'delete_index' => XenForo_Input::UINT)); if ($input['delay'] >= 0.01) { usleep($input['delay'] * 1000000); } /* @var $searchModel XenForo_Model_Search */ $searchModel = XenForo_Model::create('XenForo_Model_Search'); $searchContentTypes = $searchModel->getSearchContentTypes(); $extraData = $input['extra_data']; if (!isset($extraData['content_types']) || !is_array($extraData['content_types'])) { if ($input['content_type'] && isset($searchContentTypes[$input['content_type']])) { $extraData['content_types'] = array($input['content_type']); } else { $extraData['content_types'] = array_keys($searchContentTypes); } } if (empty($extraData['current_type'])) { $extraData['current_type'] = array_shift($extraData['content_types']); } if (empty($extraData['type_start'])) { $extraData['type_start'] = 0; } $originalExtraData = $extraData; while (!isset($searchContentTypes[$extraData['current_type']])) { if (!$extraData['content_types']) { return false; } $extraData['current_type'] = array_shift($extraData['content_types']); } if ($input['delete_index']) { $source = XenForo_Search_SourceHandler_Abstract::getDefaultSourceHandler(); $source->deleteIndex($input['content_type'] ? $input['content_type'] : null); } $dataHandler = false; $searchHandler = $searchContentTypes[$extraData['current_type']]; if (class_exists($searchHandler)) { $dataHandler = XenForo_Search_DataHandler_Abstract::create($searchHandler); $indexer = new XenForo_Search_Indexer(); $indexer->setIsRebuild(true); $nextStart = $dataHandler->rebuildIndex($indexer, $extraData['type_start'], $input['batch']); $indexer->finalizeRebuildSet(); } else { $nextStart = false; } if ($nextStart === false) { // move on to next type $extraData['current_type'] = ''; $extraData['type_start'] = 0; } else { $extraData['type_start'] = $nextStart; } $data = array('batch' => $input['batch'], 'start' => $input['start'] + 1, 'extra_data' => $extraData, 'delay' => $input['delay']); $actionPhrase = new XenForo_Phrase('rebuilding'); $typePhrase = new XenForo_Phrase('search_index'); $text = $dataHandler ? $dataHandler->getSearchContentTypePhrase() : new XenForo_Phrase($originalExtraData['current_type']); $status = sprintf('%s... %s (%s)', $actionPhrase, $typePhrase, "{$text} " . XenForo_Locale::numberFormat($originalExtraData['type_start'])); return $data; }
protected function _Tinhte_XenTag_unindexFromSearch() { $indexer = new XenForo_Search_Indexer(); $data = $this->getMergedData(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('Tinhte_XenTag_Search_DataHandler_Page'); $dataHandler->deleteFromIndex($indexer, $data); }
public function processConstraint(XenForo_Search_SourceHandler_Abstract $sourceHandler, $constraint, $constraintInfo, array $constraints) { $result = Tinhte_XenTag_Integration::processConstraint($sourceHandler, $constraint, $constraintInfo, $constraints); if ($result !== false) { return $result; } return parent::processConstraint($sourceHandler, $constraint, $constraintInfo, $constraints); }
protected function _postDelete() { $template = $this->getModelFromCache('XenForo_Model_Template')->getTemplateInStyleByTitle($this->getModelFromCache('XenForo_Model_Page')->getTemplateTitle($this->getMergedData())); if ($template) { $dw = XenForo_DataWriter::create('XenForo_DataWriter_Template', XenForo_DataWriter::ERROR_SILENT); $dw->setExistingData($template, true); $dw->delete(); } $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_Page'); $indexer = new XenForo_Search_Indexer(); $dataHandler->deleteFromIndex($indexer, $this->getMergedData()); parent::_postDelete(); }
/** * Rebuilds the data. * * @see XenForo_CacheRebuilder_Abstract::rebuild() */ public function rebuild($position = 0, array &$options = array(), &$detailedMessage = '') { $inputHandler = new XenForo_Input($options); $input = $inputHandler->filter(array('batch' => XenForo_Input::UINT, 'start' => XenForo_Input::UINT, 'extra_data' => XenForo_Input::ARRAY_SIMPLE, 'delay' => XenForo_Input::UNUM)); if ($input['delay'] >= 0.01) { usleep($input['delay'] * 1000000); } /* @var $searchModel XenForo_Model_Search */ $searchModel = XenForo_Model::create('XenForo_Model_Search'); $searchContentTypes = $searchModel->getSearchContentTypes(); // TODO: potentially look at truncating the table (user option?) $extraData = $input['extra_data']; if (!isset($extraData['content_types']) || !is_array($extraData['content_types'])) { $extraData['content_types'] = array_keys($searchContentTypes); } if (empty($extraData['current_type'])) { $extraData['current_type'] = array_shift($extraData['content_types']); } if (empty($extraData['type_start'])) { $extraData['type_start'] = 0; } $originalExtraData = $extraData; while (!isset($searchContentTypes[$extraData['current_type']])) { if (!$extraData['content_types']) { return true; } $extraData['current_type'] = array_shift($extraData['content_types']); } $searchHandler = $searchContentTypes[$extraData['current_type']]; $dataHandler = XenForo_Search_DataHandler_Abstract::create($searchHandler); $indexer = new XenForo_Search_Indexer(); $indexer->setIsRebuild(true); $nextStart = $dataHandler->rebuildIndex($indexer, $extraData['type_start'], $input['batch']); $indexer->finalizeRebuildSet(); if ($nextStart === false) { // move on to next type $extraData['current_type'] = ''; $extraData['type_start'] = 0; } else { $extraData['type_start'] = $nextStart; } $options = array('batch' => $input['batch'], 'start' => $input['start'] + 1, 'extra_data' => $extraData, 'delay' => $input['delay']); $detailedMessage = "({$originalExtraData['current_type']} " . XenForo_Locale::numberFormat($originalExtraData['type_start']) . ")"; return 1; }
protected function _rebuildContentIndex() { switch ($this->get('content_type')) { case sonnb_XenGallery_Model_Video::$contentType: $handleKey = 'sonnb_XenGallery_Search_DataHandler_Video'; break; case sonnb_XenGallery_Model_Photo::$contentType: $handleKey = 'sonnb_XenGallery_Search_DataHandler_Photo'; break; default: $handleKey = ''; break; } if (empty($handleKey)) { return; } $indexer = new XenForo_Search_Indexer(); $dataHandler = XenForo_Search_DataHandler_Abstract::create($handleKey); $dataHandler->insertIntoIndex($indexer, $this->getMergedData()); }
public function prioritizeResults(array &$results, XenForo_Search_Searcher $searcher, $searchQuery, array $constraints = array(), $order = 'relevance') { // prioritize contents by doing a second search for prioritized contents // this may cause performance issue but shouldn't make a big impact // admin can easily disable the feature in AdminCP // it's required to do another search because the original search has its own // max results and may not include all prioritized results $prioritizedContents = $this->getPrioritizedContents(); if (empty($prioritizedContents)) { // nothing to do return; } $typeHandler = XenForo_Search_DataHandler_Abstract::create('Tinhte_XenTag_Search_DataHandler_General'); $typeHandler->setSearchContentTypes(array_keys($prioritizedContents)); $prioritizedResults = $searcher->searchType($typeHandler, $searchQuery, $constraints, $order); if (empty($prioritizedResults)) { // no prioritized results could be found, do nothing return; } // drop all prioritized results from general results foreach (array_keys($results) as $resultKey) { if (isset($prioritizedContents[$results[$resultKey][0]])) { unset($results[$resultKey]); } } // append priorizied results asort($prioritizedContents); $prioritizedResultsKeys = array_reverse(array_keys($prioritizedResults)); foreach ($prioritizedContents as $contentType => $displayOrder) { foreach ($prioritizedResultsKeys as $prioritizedResultKey) { if ($prioritizedResults[$prioritizedResultKey][0] == $contentType) { array_unshift($results, $prioritizedResults[$prioritizedResultKey]); } } } // normalized array indeces $results = array_values($results); }
/** * Executes a search against the full text index. * * @param string $searchQuery Text to search for * @param boolean $titleOnly If true, only searches text in titles * @param array $processedConstraints Structured constraints * @param array $orderParts Structured ordered by parts * @param string $groupByDiscussionType If grouping, content type of grouped results * @param integer $maxResults * @param XenForo_Search_DataHandler_Abstract $typeHandler Type-specific handler, for joins * * @return array Search results ([] => array(content type, id)) */ public function executeSearch($searchQuery, $titleOnly, array $processedConstraints, array $orderParts, $groupByDiscussionType, $maxResults, XenForo_Search_DataHandler_Abstract $typeHandler = null) { $db = $this->_getDb(); $queryParts = $this->tokenizeQuery($searchQuery); $searchQuery = $this->parseTokenizedQuery($queryParts, $processedConstraints); if ($titleOnly) { $matchFields = 'search_index.title, search_index.metadata'; } else { $matchFields = 'search_index.title, search_index.message, search_index.metadata'; } $tables = array(); $whereClauses = array(); foreach ($processedConstraints as $constraint) { if (isset($constraint['query']) && !isset($constraint['metadata'])) { // pull queries without metadata alternatives list($queryTable, $queryField, $queryOperator, $queryValues) = $constraint['query']; if (is_array($queryValues) && count($queryValues) == 0) { continue; } if ($queryOperator == '=' && is_array($queryValues)) { $whereClauses[] = "{$queryTable}.{$queryField} IN (" . $db->quote($queryValues) . ")"; } else { if (!is_scalar($queryValues)) { $queryValues = strval($queryValues); } $whereClauses[] = "{$queryTable}.{$queryField} {$queryOperator} " . $db->quote($queryValues); } $tables[] = $queryTable; } } $orderFields = array(); foreach ($orderParts as $order) { list($orderTable, $orderField, $orderDirection) = $order; $orderFields[] = "{$orderTable}.{$orderField} {$orderDirection}"; $tables[] = $orderTable; } $orderClause = $orderFields ? 'ORDER BY ' . implode(', ', $orderFields) : 'ORDER BY NULL'; $tables = array_flip($tables); unset($tables['search_index']); if ($typeHandler) { $joinStructures = $typeHandler->getJoinStructures($tables); $joins = array(); foreach ($joinStructures as $tableAlias => $joinStructure) { list($relationshipTable, $relationshipField) = $joinStructure['relationship']; $joins[] = "INNER JOIN {$joinStructure['table']} AS {$tableAlias} ON\n\t\t\t\t\t({$tableAlias}.{$joinStructure['key']} = {$relationshipTable}.{$relationshipField})"; } } else { $joins = array(); } $extraWhere = $whereClauses ? 'AND (' . implode(') AND (', $whereClauses) . ')' : ''; if ($groupByDiscussionType) { $selectFields = $db->quote($groupByDiscussionType) . ' AS content_type, search_index.discussion_id AS content_id'; $groupByClause = 'GROUP BY search_index.discussion_id'; } else { $selectFields = 'search_index.content_type, search_index.content_id'; $groupByClause = ''; } if ($maxResults < 1) { $maxResults = 100; } $maxResults = intval($maxResults); if ($this->_searcher && $this->_searcher->hasErrors()) { return array(); } return $db->fetchAll("\n\t\t\tSELECT {$selectFields}\n\t\t\tFROM xf_search_index AS search_index\n\t\t\t" . implode("\n", $joins) . "\n\t\t\tWHERE MATCH({$matchFields}) AGAINST (? IN BOOLEAN MODE)\n\t\t\t\t{$extraWhere}\n\t\t\t{$groupByClause}\n\t\t\t{$orderClause}\n\t\t\tLIMIT {$maxResults}\n\t\t", $searchQuery, Zend_Db::FETCH_NUM); }
protected function _postSave() { $postSaveChanges = array(); $this->updateCustomFields(); if ($this->isUpdate() && $this->isChanged('title')) { $dw = $this->getDescriptionDw(); $dw->set('title', $this->get('title'), '', array('runVerificationCallback' => false, 'setAfterPreSave' => true)); $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread', XenForo_DataWriter::ERROR_SILENT); if ($threadDw->setExistingData($this->get('discussion_thread_id')) && $threadDw->get('discussion_type') == 'resource') { $threadTitle = $this->_stripTemplateComponents($threadDw->get('title'), $this->getOption(self::OPTION_DELETE_THREAD_TITLE_TEMPLATE)); $threadTitle = $this->_stripTemplateComponents($threadTitle, $this->getOption(self::OPTION_PAID_THREAD_TITLE_TEMPLATE)); if ($threadTitle == $this->getExisting('title')) { $threadDw->set('title', $this->_getThreadTitle()); $threadDw->save(); } } } if ($this->isUpdate() && $this->isChanged('resource_category_id') && $this->get('discussion_thread_id')) { $catDw = $this->_getCategoryDwForUpdate(); $nodeId = $this->getOption(self::OPTION_CREATE_THREAD_NODE_ID); if ($nodeId === null) { $nodeId = $catDw->get('thread_node_id'); } $prefixId = $this->getOption(self::OPTION_CREATE_THREAD_PREFIX_ID); if ($prefixId === null) { $prefixId = $catDw->get('thread_prefix_id'); } $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread', XenForo_DataWriter::ERROR_SILENT); if ($threadDw->setExistingData($this->get('discussion_thread_id')) && $threadDw->get('discussion_type') == 'resource') { if ($nodeId) { $threadDw->set('node_id', $nodeId); $threadDw->set('prefix_id', $prefixId); if ($threadDw->get('discussion_state') == 'deleted') { $threadDw->set('discussion_state', 'visible'); } } else { $threadDw->set('discussion_state', 'deleted'); } $threadDw->save(); } } if ($this->_isFirstVisible) { $this->getDescriptionDw(); if ($this->_descriptionDw && !$this->_descriptionDw->isChanged('post_date')) { $this->_descriptionDw->set('post_date', $this->get('resource_date'), '', array('setAfterPreSave' => true)); } $this->getVersionDw(); if ($this->_versionDw && !$this->_versionDw->isChanged('release_date')) { $this->_versionDw->set('release_date', $this->get('resource_date'), '', array('setAfterPreSave' => true)); } } if ($this->_descriptionDw) { if ($this->_descriptionDw->isInsert()) { $this->_descriptionDw->set('resource_id', $this->get('resource_id'), '', array('setAfterPreSave' => true)); $this->_descriptionDw->setResource($this->getMergedData()); $this->_descriptionDw->save(); $this->set('description_update_id', $this->_descriptionDw->get('resource_update_id'), '', array('setAfterPreSave' => true)); $postSaveChanges['description_update_id'] = $this->get('description_update_id'); } else { $this->_descriptionDw->save(); } } if ($this->_versionDw) { if ($this->_versionDw->isInsert()) { $this->_versionDw->set('resource_id', $this->get('resource_id'), '', array('setAfterPreSave' => true)); $this->_versionDw->set('resource_update_id', $this->get('description_update_id'), '', array('setAfterPreSave' => true)); $this->_versionDw->save(); $this->set('current_version_id', $this->_versionDw->get('resource_version_id'), '', array('setAfterPreSave' => true)); $postSaveChanges['current_version_id'] = $this->get('current_version_id'); } else { $this->_versionDw->save(); } } $removed = false; if ($this->isChanged('resource_state')) { if ($this->get('resource_state') == 'visible') { $this->_resourceMadeVisible($postSaveChanges); } else { if ($this->isUpdate() && $this->getExisting('resource_state') == 'visible') { $this->_resourceRemoved(); $removed = true; } } $this->_updateDeletionLog(); $this->_updateModerationQueue(); } if ($postSaveChanges) { $this->_db->update('xf_resource', $postSaveChanges, 'resource_id = ' . $this->_db->quote($this->get('resource_id'))); } $catDw = $this->_getCategoryDwForUpdate(); if ($catDw && !$removed) { // will already be called for removal $catDw->resourceUpdate($this); $catDw->save(); } if ($this->isUpdate() && ($this->isChanged('resource_category_id') || $this->isChanged('title') || $this->isChanged('tag_line') || $this->isChanged('prefix_id'))) { $updateIds = $this->_db->fetchCol(' SELECT resource_update_id FROM xf_resource_update WHERE resource_id = ? ', $this->get('resource_id')); $indexer = new XenForo_Search_Indexer(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenResource_Search_DataHandler_Update'); $dataHandler->quickIndex($indexer, $updateIds); } if ($this->isUpdate() && $this->isChanged('user_id')) { if ($this->get('user_id') && $this->get('resource_state') == 'visible' && !$this->isChanged('resource_state')) { $this->_db->query(' UPDATE xf_user SET resource_count = resource_count + 1 WHERE user_id = ? ', $this->get('user_id')); } if ($this->getExisting('user_id') && $this->getExisting('resource_state') == 'visible') { $this->_db->query(' UPDATE xf_user SET resource_count = resource_count - 1 WHERE user_id = ? ', $this->getExisting('user_id')); } } }
/** * Deletes this message from the search index. */ protected function _deleteFromSearchIndex() { $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_ProfilePostComment'); $indexer = new XenForo_Search_Indexer(); $dataHandler->deleteFromIndex($indexer, $this->getMergedData()); }
/** * Gets the search data handler for this type of message. * * @return XenForo_Search_DataHandler_Abstract|false */ public function getSearchDataHandler() { return XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_Post'); }
/** * Merge multiple threads into a single thread * * @param array $threads * @param integer $targetThreadId * @param array $options * * @return boolean|array False if failure, otherwise thread array of merged thread */ public function mergeThreads(array $threads, $targetThreadId, array $options = array()) { if (!isset($threads[$targetThreadId])) { return false; } $targetThread = $threads[$targetThreadId]; unset($threads[$targetThreadId]); $mergeFromThreadIds = array_keys($threads); if (!$mergeFromThreadIds) { return false; } $options = array_merge(array('redirect' => false, 'redirectExpiry' => 0, 'log' => true, 'starterAlert' => false, 'starterAlertReason' => ''), $options); $postModel = $this->_getPostModel(); $db = $this->_getDb(); $movePosts = $this->fetchAllKeyed(' SELECT post_id, thread_id, user_id, message_state FROM xf_post WHERE thread_id IN (' . $db->quote($mergeFromThreadIds) . ') ', 'post_id'); $movePostIds = array_keys($movePosts); XenForo_Db::beginTransaction($db); $idsQuoted = $db->quote($mergeFromThreadIds); $db->update('xf_post', array('thread_id' => $targetThreadId), 'post_id IN (' . $db->quote($movePostIds) . ')'); $db->query("\n\t\t\tUPDATE IGNORE xf_thread_watch SET\n\t\t\t\tthread_id = ?\n\t\t\tWHERE thread_id IN ({$idsQuoted})\n\t\t", array($targetThreadId)); $db->query("\n\t\t\tUPDATE IGNORE xf_tag_content SET\n\t\t\t\tcontent_id = ?\n\t\t\tWHERE content_type = 'thread' AND content_id IN ({$idsQuoted})\n\t\t", array($targetThreadId)); $db->query("\n\t\t\tUPDATE IGNORE xf_thread_reply_ban SET\n\t\t\t\tthread_id = ?\n\t\t\tWHERE thread_id IN ({$idsQuoted})\n\t\t", array($targetThreadId)); $newCounters = $postModel->recalculatePostPositionsInThread($targetThreadId); if (!$newCounters['firstPostId']) { XenForo_Db::rollback($db); return false; } // TODO: user message counts will go off if merging from a visible thread into a hidden one or vice versa // TODO: user message counts will also go off if merging from a thread in a counting forum into a non-counting forum, or vice versa $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread'); $threadDw->setExistingData($targetThreadId); $threadDw->rebuildDiscussionCounters($newCounters['visibleCount'] - 1, $newCounters['firstPostId'], $newCounters['lastPostId']); $viewCount = $threadDw->get('view_count'); foreach ($threads as $thread) { $viewCount += $thread['view_count']; } $threadDw->set('view_count', $viewCount); if ($threadDw->get('discussion_type') == '') { foreach ($threads as $thread) { if ($thread['discussion_type'] == 'poll') { $pollMoved = $db->update('xf_poll', array('content_id' => $targetThreadId), "content_type = 'thread' AND content_id = " . $db->quote($thread['thread_id'])); if ($pollMoved) { $threadDw->set('discussion_type', 'poll'); break; } } } } $threadDw->save(); $targetThread = $threadDw->getMergedData(); foreach ($threads as $thread) { if ($thread['discussion_state'] == 'visible' && $options['starterAlert']) { $this->sendModeratorActionAlert('merge', $thread, $options['starterAlertReason'], array('targetTitle' => $targetThread['title'], 'targetLink' => XenForo_Link::buildPublicLink('threads', $targetThread))); } } if ($options['redirect']) { $targetUrl = XenForo_Link::buildPublicLink('threads', $targetThread); $redirectKey = "thread-{$targetThread['thread_id']}-"; foreach ($threads as $thread) { $redirectDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread'); $redirectDw->setExistingData($thread, true); $redirectDw->set('discussion_type', 'redirect'); $redirectDw->save(); $this->getModelFromCache('XenForo_Model_ThreadRedirect')->insertThreadRedirect($thread['thread_id'], $targetUrl, $redirectKey, $options['redirectExpiry']); } $db->delete('xf_thread_watch', "thread_id IN ({$idsQuoted})"); $db->delete('xf_thread_reply_ban', "thread_id IN ({$idsQuoted})"); $db->delete('xf_thread_user_post', "thread_id IN ({$idsQuoted})"); $db->delete('xf_poll', "content_type = 'thread' AND content_id IN ({$idsQuoted})"); $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_Thread'); $indexer = new XenForo_Search_Indexer(); $dataHandler->deleteFromIndex($indexer, $threads); } else { foreach ($threads as $thread) { $deleteDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread'); $deleteDw->setExistingData($thread, true); $deleteDw->delete(); } } $forumIds = array(); foreach ($threads as $thread) { $forumIds[$thread['node_id']] = $thread['node_id']; } foreach ($forumIds as $forumId) { $forumDw = XenForo_DataWriter::create('XenForo_DataWriter_Forum', XenForo_DataWriter::ERROR_SILENT); $forumDw->setExistingData($forumId); $forumDw->rebuildCounters(); $forumDw->save(); } $this->replaceThreadUserPostCounters($targetThreadId, $newCounters['userPosts']); /** @var XenForo_Model_Tag $tagModel */ $tagModel = $this->getModelFromCache('XenForo_Model_Tag'); $tagModel->rebuildTagCache('thread', $targetThread['thread_id']); $tagModel->recalculateTagUsageByContentTagged('thread', $targetThread['thread_id']); XenForo_Application::defer('SearchIndexPartial', array('contentType' => 'post', 'contentIds' => $movePostIds)); if ($options['log']) { XenForo_Model_Log::logModeratorAction('thread', $targetThread, 'merge_target', array('ids' => implode(', ', array_keys($threads)))); } XenForo_Db::commit($db); return $targetThread; }
/** * Creates search data handler objects for the specified content types. * * @param array $handlerContentTypes List of content types * * @return array Format: [content type] => XenForo_Search_DataHandler_Abstract object */ public function getSearchDataHandlers(array $handlerContentTypes) { $contentTypes = $this->getSearchContentTypes(); $handlers = array(); foreach ($handlerContentTypes as $contentType) { if (isset($contentTypes[$contentType])) { $handlers[$contentType] = XenForo_Search_DataHandler_Abstract::create($contentTypes[$contentType]); } } return $handlers; }
/** * Saves a page, wrapping the whole operation up in a transaction * * @param array $page * @param string $template * @param integer $nodeId * @param integer $templateId * * @return integer $nodeId */ public function savePage(array $page, $template, $nodeId = 0, $templateId = 0) { $db = $this->_getDb(); XenForo_Db::beginTransaction($db); // save page $pageWriter = XenForo_DataWriter::create('XenForo_DataWriter_Page'); if ($nodeId) { $pageWriter->setExistingData($nodeId); } $pageWriter->bulkSet($page); $pageWriter->save(); $page = $pageWriter->getMergedData(); // save template $templateWriter = XenForo_DataWriter::create('XenForo_DataWriter_Template'); if ($templateId) { $templateWriter->setExistingData($templateId); } $templateWriter->set('title', $this->getTemplateTitle($page)); $templateWriter->set('template', $template); $templateWriter->set('style_id', 0); $templateWriter->set('addon_id', ''); $templateWriter->save(); XenForo_Db::commit($db); $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_Page'); $indexer = new XenForo_Search_Indexer(); $page['content'] = $template; $dataHandler->insertIntoIndex($indexer, $page); return $pageWriter->get('node_id'); }
/** * Post-delete handling. */ protected function _postDelete() { $db = $this->_db; $db->update('xengallery_category', array('parent_category_id' => $this->get('parent_category_id')), 'parent_category_id = ' . $this->_db->quote($this->get('category_id'))); $media = $db->fetchAll(' SELECT * FROM xengallery_media WHERE category_id = ? ', $this->get('category_id')); $mediaIds = array(); foreach ($media as $_media) { $mediaIds[] = $_media['media_id']; $mediaWriter = XenForo_DataWriter::create('XenGallery_DataWriter_Media'); $mediaWriter->setExistingData($_media); $mediaWriter->delete(); } $mediaIdsQuoted = $db->quote($mediaIds); if ($mediaIdsQuoted) { $indexer = new XenForo_Search_Indexer(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenGallery_Search_DataHandler_Media'); $dataHandler->deleteFromIndex($indexer, $media); $db->update('xf_attachment', array('unassociated' => 1), 'content_type = \'xengallery_media\' AND content_id IN (' . $mediaIdsQuoted . ')'); } $this->_getCategoryModel()->rebuildCategoryStructure(); }
/** * Post-save handling. */ protected function _postSave() { $attachmentHash = $this->getExtraData(self::DATA_ATTACHMENT_HASH); if ($attachmentHash) { $this->_associateAttachments($attachmentHash); } $resourceDw = XenForo_DataWriter::create('XenResource_DataWriter_Resource', XenForo_DataWriter::ERROR_SILENT); if ($resourceDw->setExistingData($this->get('resource_id'))) { if ($this->getOption(self::OPTION_UPDATE_LAST_UPDATE)) { $usernameUpdated = $resourceDw->checkUserName(); if ($this->isInsert() && $this->get('message_state') == 'visible') { $resourceDw->updateUpdateCount(1); $resourceDw->updateLastUpdate($this->get('post_date')); $resourceDw->save(); } else { if ($this->isUpdate() && $this->isChanged('message_state')) { $resourceDw->updateUpdateCount(); $resourceDw->updateLastUpdate(); $resourceDw->save(); } else { if ($usernameUpdated) { $resourceDw->save(); } } } } $this->_resource = $resourceDw->getMergedData(); $this->_updateThread($this->_resource); } if ($this->isChanged('title') || $this->isChanged('message')) { $indexer = new XenForo_Search_Indexer(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenResource_Search_DataHandler_Update'); $dataHandler->insertIntoIndex($indexer, $this->getMergedData(), $this->_resource); } if ($this->isChanged('message_state')) { $this->_updateDeletionLog(); $this->_updateModerationQueue(); } if ($this->_isFirstVisible && $this->_resource) { if (!$this->get('ip_id')) { $ipId = XenForo_Model_Ip::log($this->_resource['user_id'], 'resource_update', $this->get('resource_update_id'), 'insert'); $this->set('ip_id', $ipId, '', array('setAfterPreSave' => true)); $this->_db->update('xf_resource_update', array('ip_id' => $ipId), 'resource_update_id = ' . $this->_db->quote($this->getExisting('resource_update_id'))); } if ($this->get('message_state') == 'visible') { $this->_getNewsFeedModel()->publish($this->_resource['user_id'], $this->_resource['username'], 'resource_update', $this->get('resource_update_id'), 'insert'); } } }
protected function _postDelete() { $dataHandler = XenForo_Search_DataHandler_Abstract::create('ThemeHouse_Bible_Search_DataHandler_Verse'); $indexer = new XenForo_Search_Indexer(); $dataHandler->deleteFromIndex($indexer, $this->getMergedData()); }
/** * @return bdApi_Search_DataHandler_ClientContent */ protected function _getSearchDataHandler() { return XenForo_Search_DataHandler_Abstract::create('bdApi_Search_DataHandler_ClientContent'); }
/** * Creates search data handler objects for the specified content types. * * @param array|null $handlerContentTypes List of content types. If null, get all * * @return array Format: [content type] => XenForo_Search_DataHandler_Abstract object */ public function getSearchDataHandlers(array $handlerContentTypes = null) { $contentTypes = $this->getSearchContentTypes(); $handlers = array(); if ($handlerContentTypes === null) { $handlerContentTypes = array_keys($contentTypes); } foreach ($handlerContentTypes as $contentType) { if (isset($contentTypes[$contentType])) { if (!class_exists($contentTypes[$contentType])) { continue; } $handlers[$contentType] = XenForo_Search_DataHandler_Abstract::create($contentTypes[$contentType]); } } return $handlers; }
protected function _doSearch($tagText) { $visitorUserId = XenForo_Visitor::getUserId(); /* @var $searchModel XenForo_Model_Search */ $searchModel = $this->getModelFromCache('XenForo_Model_Search'); /* @var $tagSearchModel Tinhte_XenTag_Model_Search */ $tagSearchModel = $this->getModelFromCache('Tinhte_XenTag_Model_Search'); $input = array('type' => Tinhte_XenTag_Constants::SEARCH_TYPE_TAG, 'keywords' => '', Tinhte_XenTag_Constants::SEARCH_INPUT_TAGS => $tagText, 'order' => 'date', 'group_discussion' => 0); $constraints = $searchModel->getGeneralConstraintsFromInput($input, $errors); if ($errors) { return $this->responseError($errors); } $forceRefresh = $this->_input->filterSingle('force_refresh', XenForo_Input::UINT) > 0; if ($forceRefresh) { if (XenForo_Visitor::getInstance()->get('isTrusted')) { // good, this is a trusted user (admin or mod) } else { // do not accept force refresh request from not-trusted users $forceRefresh = false; } } if ($forceRefresh == false) { // force to use cache to have a nice and clean url $search = $searchModel->getExistingSearch($input['type'], $input['keywords'], $constraints, $input['order'], $input['group_discussion'], $visitorUserId, Tinhte_XenTag_Option::get('searchForceUseCache')); } else { // skip getting existing results, this will cause a real search to be made $search = false; } if (empty($search)) { $searcher = new XenForo_Search_Searcher($searchModel); $typeHandler = XenForo_Search_DataHandler_Abstract::create('Tinhte_XenTag_Search_DataHandler_General'); $results = $searcher->searchType($typeHandler, $input['keywords'], $constraints, $input['order']); if (empty($results)) { return $this->_getNoResultsResponse($tagText); } else { $tagSearchModel->prioritizeResults($results, $searcher, $input['keywords'], $constraints, $input['order']); } $warnings = $searcher->getErrors() + $searcher->getWarnings(); $search = $searchModel->insertSearch($results, $input['type'], $input['keywords'], $constraints, $input['order'], $input['group_discussion'], array(), $warnings, $visitorUserId); } return $search; }
/** * Deletes this discussion from the search index. */ protected function _deleteFromSearchIndex() { $indexer = new XenForo_Search_Indexer(); $mergedData = $this->getMergedData(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('Nobita_Teams_Search_DataHandler_Team'); if ($dataHandler) { $dataHandler->deleteFromIndex($indexer, $mergedData); } }
protected function _postSave() { if ($this->_streams && $this->isInsert()) { $this->_processStreams(); } $this->_processCategoryChanges(); $this->_processCollectionChanges(); if ($this->isInsert()) { $this->_logIpExtend('insert'); if ($this->get('album_type') == sonnb_XenGallery_Model_Album::ALBUM_TYPE_NORMAL) { $this->_publishToNewsFeed(); } } if ($this->isChanged('album_state')) { $this->_updateDeletionLog(); $this->_updateModerationQueue(); $this->rebuildUserAlbumCount(); } if ($this->isInsert() && ($this->get('description') || $this->get('title'))) { $indexer = new XenForo_Search_Indexer(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('sonnb_XenGallery_Search_DataHandler_Album'); $dataHandler->insertIntoIndex($indexer, $this->getMergedData()); } elseif ($this->isUpdate() && ($this->isChanged('description') || $this->isChanged('title'))) { $indexer = new XenForo_Search_Indexer(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('sonnb_XenGallery_Search_DataHandler_Album'); $dataHandler->insertIntoIndex($indexer, $this->getMergedData()); } if ($this->isChanged('album_state') && $this->get('album_state') === 'deleted') { $this->_logIpExtend('soft-delete'); } if ($this->isUpdate() && $this->isChanged('user_id')) { $oldUserId = $this->getExisting('user_id'); $newUserId = $this->get('user_id'); $this->rebuildUserAlbumCount($oldUserId); $this->rebuildUserAlbumCount($newUserId); } if ($this->isChanged('collection_id') && $this->get('collection_id')) { $this->_db->update('sonnb_xengallery_collection', array('last_content_date' => XenForo_Application::$time), array('collection_id = ?' => $this->get('collection_id'))); } $this->updateCustomFields(); if ($this->get('album_state') === 'visible' && ($this->isInsert() || $this->getExisting('album_state') === 'moderated')) { $maxTagged = 20; if ($this->_taggedUsers) { if ($maxTagged > 0) { $alertTagged = array_slice($this->_taggedUsers, 0, $maxTagged, true); } else { $alertTagged = $this->_taggedUsers; } $content = $this->getMergedData(); $this->_getUserTaggingModel()->alertTaggedMembers($content, $content['album_id'], sonnb_XenGallery_Model_Album::$xfContentType, $alertTagged); } } //TODO: Write to history }
protected function _updateModerationQueue(array $media) { if (!$this->isChanged('media_state')) { return; } if ($this->get('media_state') == 'moderated') { $this->getModelFromCache('XenForo_Model_ModerationQueue')->insertIntoModerationQueue('xengallery_media', $this->get('media_id'), $this->get('media_date')); $indexer = new XenForo_Search_Indexer(); $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenGallery_Search_DataHandler_Media'); $dataHandler->deleteFromIndex($indexer, $media); $this->_updateAlbumCache($this->get('album_id')); } else { if ($this->getExisting('media_state') == 'moderated') { $this->getModelFromCache('XenForo_Model_ModerationQueue')->deleteFromModerationQueue('xengallery_media', $this->get('media_id')); $this->_updateAlbumCache($this->get('album_id')); } } }
public function updateDataHandler(XenForo_Search_DataHandler_Abstract $handler, array $search) { if (!empty($search['searchConstraints'])) { $handler->setExportSearchContstraints($search['searchConstraints']); } }
/** * Process search constraints. * * @param array $constraints List of constraints: [constraint name] => limit (may be scalar or array) * @param XenForo_Search_DataHandler_Abstract|null $typeHandler * * @return array Processed constraints. Names as keys, value is array with possible keys: * * metadata - metadata value; keys: 0 = name of metadata, 1 = scalar/array allowed value(s) for metadata * * query - constraint to limit via query; keys: 0 = table alias, 1 = field, 2 = operator, 3 = scalar/array allowed value(s). Multiple for "=" operator only. * Note that the metadata and query keys are assumed to be equivalent. Engines need only use one (depending on engine details). */ public function processConstraints(array $constraints, XenForo_Search_DataHandler_Abstract $typeHandler = null) { $processed = array(); foreach ($constraints as $constraint => $constraintInfo) { if (is_array($constraintInfo) && count($constraintInfo) == 0 || is_string($constraintInfo) && $constraintInfo === '') { continue; } switch ($constraint) { case 'user': $processed[$constraint] = array('metadata' => array('user', $constraintInfo), 'query' => array('search_index', 'user_id', '=', $constraintInfo)); break; case 'user_content': if (!empty($constraints['user'])) { $processed[$constraint] = array('metadata' => array('content', $constraintInfo), 'query' => array('search_index', 'content_type', '=', $constraintInfo)); } break; case 'content': $processed[$constraint] = array('metadata' => array('content', $constraintInfo), 'query' => array('search_index', 'content_type', '=', $constraintInfo)); break; case 'node': $nodes = preg_split('/\\D/', strval($constraintInfo)); $processed[$constraint] = array('metadata' => array('node', array_map('intval', $nodes))); break; case 'date': $processed[$constraint] = array('query' => array('search_index', 'item_date', '>', intval($constraintInfo))); break; case 'date_max': $processed[$constraint] = array('query' => array('search_index', 'item_date', '<', intval($constraintInfo))); break; default: if ($typeHandler) { $newConstraint = $typeHandler->processConstraint($this, $constraint, $constraintInfo, $constraints); if ($newConstraint) { $processed[$constraint] = $newConstraint; } } } } return $processed; }
if ($input['content_type']) { $searchContentList = array($input['content_type']); } else { $searchContentList = array_keys($searchContentTypes); } // ****************** $start = 0; $batch = 100; $currentContentType = array_shift($searchContentList); // ****************** $position = $start; $lastStart = 0; while (true) { $searchHandler = $searchContentTypes[$currentContentType]; if (class_exists($searchHandler)) { $dataHandler = XenForo_Search_DataHandler_Abstract::create($searchHandler); $indexer = new XenForo_Search_Indexer(); if ($start and $start > $specialBuildRange[0] and $start < $specialBuildRange[1]) { $start = $dataHandler->rebuildIndex($indexer, $start, $batch); } else { $indexer->setIsRebuild(true); $start = $dataHandler->rebuildIndex($indexer, $start, $batch); $indexer->finalizeRebuildSet(); } } else { $start = false; } if ($start === false) { if (empty($searchContentList)) { break; }