/** * @see \wcf\system\worker\IWorker::execute() */ public function execute() { $this->objectList->getConditionBuilder()->add('conversation_message.messageID BETWEEN ? AND ?', array($this->limit * $this->loopCount + 1, $this->limit * $this->loopCount + $this->limit)); parent::execute(); if (!$this->loopCount) { // reset search index SearchIndexManager::getInstance()->reset('com.woltlab.wcf.conversation.message'); } // prepare statements $attachmentObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', 'com.woltlab.wcf.conversation.message'); $sql = "SELECT\t\tCOUNT(*) AS attachments\n\t\t\tFROM\t\twcf" . WCF_N . "_attachment\n\t\t\tWHERE\t\tobjectTypeID = ?\n\t\t\t\t\tAND objectID = ?"; $attachmentStatement = WCF::getDB()->prepareStatement($sql); foreach ($this->objectList as $message) { SearchIndexManager::getInstance()->add('com.woltlab.wcf.conversation.message', $message->messageID, $message->message, $message->subject ?: '', $message->time, $message->userID, $message->username); $editor = new ConversationMessageEditor($message); $data = array(); // count attachments $attachmentStatement->execute(array($attachmentObjectType->objectTypeID, $message->messageID)); $row = $attachmentStatement->fetchSingleRow(); $data['attachments'] = $row['attachments']; // update embedded objects $data['hasEmbeddedObjects'] = MessageEmbeddedObjectManager::getInstance()->registerObjects('com.woltlab.wcf.conversation.message', $message->messageID, $message->message) ? 1 : 0; $editor->update($data); } }
/** * @see \wcf\system\search\AbstractSearchIndexManager::createSearchIndex() */ protected function createSearchIndex(ObjectType $objectType) { $tableName = SearchIndexManager::getTableName($objectType); // check if table already exists $sql = "SELECT\tCOUNT(*) AS count\n\t\t\tFROM\twcf" . WCF_N . "_package_installation_sql_log\n\t\t\tWHERE\tsqlTable = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($tableName)); $row = $statement->fetchArray(); if ($row['count']) { // table already exists return false; } $columns = array(array('name' => 'objectID', 'data' => array('length' => 10, 'notNull' => true, 'type' => 'int')), array('name' => 'subject', 'data' => array('default' => '', 'length' => 255, 'notNull' => true, 'type' => 'varchar')), array('name' => 'message', 'data' => array('type' => 'mediumtext')), array('name' => 'metaData', 'data' => array('type' => 'mediumtext')), array('name' => 'time', 'data' => array('default' => 0, 'length' => 10, 'notNull' => true, 'type' => 'int')), array('name' => 'userID', 'data' => array('default' => '', 'length' => 10, 'type' => 'int')), array('name' => 'username', 'data' => array('default' => '', 'length' => 255, 'notNull' => true, 'type' => 'varchar')), array('name' => 'languageID', 'data' => array('default' => 0, 'length' => 10, 'notNull' => true, 'type' => 'int'))); $indices = array(array('name' => 'objectAndLanguage', 'data' => array('columns' => 'objectID, languageID', 'type' => 'UNIQUE')), array('name' => 'fulltextIndex', 'data' => array('columns' => 'subject, message, metaData', 'type' => 'FULLTEXT')), array('name' => 'fulltextIndexSubjectOnly', 'data' => array('columns' => 'subject', 'type' => 'FULLTEXT')), array('name' => 'language', 'data' => array('columns' => 'languageID', 'type' => 'KEY')), array('name' => 'user', 'data' => array('columns' => 'userID, time', 'type' => 'KEY'))); WCF::getDB()->getEditor()->createTable($tableName, $columns, $indices); // add comment $sql = "ALTER TABLE\t" . $tableName . "\n\t\t\tCOMMENT\t\t= 'Search index for " . $objectType->objectType . "'"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); // log table $sql = "INSERT INTO\twcf" . WCF_N . "_package_installation_sql_log\n\t\t\t\t\t(packageID, sqlTable)\n\t\t\tVALUES\t\t(?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($objectType->packageID, $tableName)); return true; }
/** * @see \wcf\system\worker\IWorker::execute() */ public function execute() { parent::execute(); // reset search index on first cycle if (!$this->loopCount) { SearchIndexManager::getInstance()->reset('de.codequake.cms.page'); } // re-create search index $pageAction = new PageAction($this->objectList->getObjects(), 'refreshSearchIndex', array('isBulkProcessing' => true)); $pageAction->executeAction(); }
/** * @see \wcf\system\worker\IWorker::execute() */ public function execute() { parent::execute(); if (!count($this->objectList)) { return; } if (!$this->loopCount) { // remove the activity points UserActivityPointHandler::getInstance()->reset('de.voolia.news.activityPointEvent.news'); // remove the entry from search index SearchIndexManager::getInstance()->reset('de.voolia.news.entry'); } // get news attachments $attachmentObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', 'de.voolia.news.entry'); $sql = "SELECT\t\tCOUNT(*) AS attachments\n\t\t\tFROM\t\twcf" . WCF_N . "_attachment\n\t\t\tWHERE\t\tobjectTypeID = ?\n\t\t\tAND\t\tobjectID = ?"; $attachments = WCF::getDB()->prepareStatement($sql); // calculate the cumulative likes $conditions = new PreparedStatementConditionBuilder(); $conditions->add("objectID IN (?)", array($this->objectList->getObjectIDs())); $conditions->add("objectTypeID = ?", array(ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.like.likeableObject', 'de.voolia.news.likeableNews'))); $sql = "SELECT\tobjectID,\n\t\t\t\tcumulativeLikes\n\t\t\tFROM\twcf" . WCF_N . "_like_object\n\t\t\t" . $conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); $likes = array(); while ($row = $statement->fetchArray()) { $likes[$row['objectID']] = $row['cumulativeLikes']; } // update the news entries $userItems = array(); foreach ($this->objectList as $news) { // new EntryEditor $editor = new NewsEditor($news); // update search index SearchIndexManager::getInstance()->add('de.voolia.news.entry', $news->newsID, $news->message, $news->subject, $news->time, $news->userID, $news->username, $news->languageID); // news data $newsData = array(); // likes $newsData['cumulativeLikes'] = isset($likes[$news->newsID]) ? $likes[$news->newsID] : 0; // attachments $attachments->execute(array($attachmentObjectType->objectTypeID, $news->newsID)); $row = $attachments->fetchArray(); $newsData['attachments'] = $row['attachments']; if ($news->userID) { if (!isset($userItems[$news->userID])) { $userItems[$news->userID] = 0; } $userItems[$news->userID]++; } $editor->update($newsData); } // update activity points UserActivityPointHandler::getInstance()->fireEvents('de.voolia.news.activityPointEvent.news', $userItems, false); }
/** * Refreshes the search index */ public function refreshSearchIndex() { if (empty($this->objects)) { $this->readObjects(); } $pageIDs = array(); foreach ($this->objects as $pageEditor) { $pageIDs[] = $pageEditor->pageID; } if (!isset($this->parameters['isBulkProcessing']) || !$this->parameters['isBulkProcessing']) { SearchIndexManager::getInstance()->delete('de.codequake.cms.page', $pageIDs); } foreach ($this->objects as $pageEditor) { $contents = $pageEditor->getDecoratedObject()->getContents(); $metaData = array(); foreach (LanguageFactory::getInstance()->getLanguages() as $language) { $metaData[$language->languageID] = ''; } foreach (array('body', 'sidebar') as $position) { foreach ($contents[$position] as $content) { if ($content->getObjectType()->getProcessor() instanceof ISearchableContentType) { $searchIndexData = $content->getObjectType()->getProcessor()->getSearchableData($content->getDecoratedObject()); foreach ($searchIndexData as $languageID => $data) { if (!empty($metaData[$languageID])) { $metaData[$languageID] .= "\n"; } $metaData[$languageID] .= $data; } } } } foreach (LanguageFactory::getInstance()->getLanguages() as $language) { SearchIndexManager::getInstance()->add('de.codequake.cms.page', $pageEditor->pageID, $language->get($pageEditor->description), $language->get($pageEditor->title), $pageEditor->creationTime, $pageEditor->authorID, $pageEditor->authorName, $language->languageID, isset($metaData[$language->languageID]) ? $metaData[$language->languageID] : ''); } } }
/** * @see \wcf\system\worker\IWorker::execute() */ public function execute() { parent::execute(); if (!$this->loopCount) { // reset activity points UserActivityPointHandler::getInstance()->reset('de.incendium.linklist.activityPointEvent.entry'); // reset search index SearchIndexManager::getInstance()->reset('de.incendium.linklist.entry'); } if (!count($this->objectList)) { return; } // fetch cumulative likes $conditions = new PreparedStatementConditionBuilder(); $conditions->add("objectTypeID = ?", array(ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.like.likeableObject', 'de.incendium.linklist.likeableEntry'))); $conditions->add("objectID IN (?)", array($this->objectList->getObjectIDs())); $sql = "SELECT\tobjectID, cumulativeLikes\n\t\t\tFROM\twcf" . WCF_N . "_like_object\n\t\t\t" . $conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); $cumulativeLikes = array(); while ($row = $statement->fetchArray()) { $cumulativeLikes[$row['objectID']] = $row['cumulativeLikes']; } // prepare statements $attachmentObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', 'de.incendium.linklist.entry'); $sql = "SELECT\t\tCOUNT(*) AS attachments\n\t\t\tFROM\t\twcf" . WCF_N . "_attachment\n\t\t\tWHERE\t\tobjectTypeID = ?\n\t\t\t\t\tAND objectID = ?"; $attachmentStatement = WCF::getDB()->prepareStatement($sql); $itemsToUser = array(); foreach ($this->objectList as $entry) { $editor = new EntryEditor($entry); $data = array(); // count attachments $attachmentStatement->execute(array($attachmentObjectType->objectTypeID, $entry->entryID)); $row = $attachmentStatement->fetchArray(); $data['attachments'] = $row['attachments']; // update cumulative likes $data['cumulativeLikes'] = isset($cumulativeLikes[$entry->entryID]) ? $cumulativeLikes[$entry->entryID] : 0; $editor->update($data); if ($entry->userID) { if (!isset($itemsToUser[$entry->userID])) { $itemsToUser[$entry->userID] = 0; } $itemsToUser[$entry->userID]++; } // update search index SearchIndexManager::getInstance()->add('de.incendium.linklist.entry', $entry->entryID, $entry->message, $entry->subject, $entry->time, $entry->userID, $entry->username, $entry->languageID); } // update activity points UserActivityPointHandler::getInstance()->fireEvents('de.incendium.linklist.activityPointEvent.entry', $itemsToUser, false); }
/** * Deletes given entries. * * @return array<array> */ public function delete() { if (empty($this->objects)) { $this->readObjects(); } $entryIDs = $entyData = $attachmentEntryIDs = $userCounters = array(); foreach ($this->objects as $entry) { $entryData[$entry->entryID] = $entry->userID; $entryIDs[] = $entry->entryID; if ($entry->attachments) { $attachmentEntryIDs[] = $entry->entryID; } if (!$entry->isDisabled) { if (!isset($userToItems[$entry->userID])) { $userToItems[$entry->userID] = 0; } $userToItems[$entry->userID]++; } } // remove user activity events $this->removeActivityEvents($entryData); // remove files $fileList = new EntryFileList(); $fileList->getConditionBuilder()->add("file.entryID IN (?)", array(array_keys($entryData))); $fileList->readObjects(); $fileAction = new EntryFileAction($fileList->getObjects(), 'delete', array('ignoreEntries' => true)); $fileAction->executeAction(); // remove entries foreach ($this->objects as $entry) { $entry->delete(); $this->addEntryData($entry->getDecoratedObject(), 'deleted', LinkHandler::getInstance()->getLink('FilebaseOverview', array('application' => 'filebase'))); EntryModificationLogHandler::getInstance()->delete($entry->getDecoratedObject()); } if (!empty($entryIDs)) { // delete like data LikeHandler::getInstance()->removeLikes('de.incendium.filebase.likeableEntry', $entryIDs); // delete comments CommentHandler::getInstance()->deleteObjects('de.incendium.filebase.entryComment', $entryIDs); // delete tag to object entries TagEngine::getInstance()->deleteObjects('de.incendium.filebase.entry', $entryIDs); // delete entry from search index SearchIndexManager::getInstance()->delete('de.incendium.filebase.entry', $entryIDs); } // decrease user entry counter if (!empty($userCounters)) { EntryEditor::updateEntryCounter($userCounters); } // delete attachments if (!empty($attachmentEntryIDs)) { AttachmentHandler::removeAttachments('de.incendium.filebase.entry', $attachmentEntryIDs); } // delete subscriptions UserObjectWatchHandler::getInstance()->deleteObjects('de.incendium.filebase.entry', $entryIDs); $this->unmarkItems(); return $this->getEntryData(); }
/** * @see \wcf\data\IDeleteAction::delete() */ public function delete() { if (empty($this->objects)) { $this->readObjects(); } $entryIDs = $entyData = $attachmentEntryIDs = $userCounters = array(); foreach ($this->objects as $entry) { $entryData[$entry->entryID] = $entry->userID; $entryIDs[] = $entry->entryID; if ($entry->attachments) { $attachmentEntryIDs[] = $entry->entryID; } if (!$entry->isDisabled) { if (!isset($userToItems[$entry->userID])) { $userToItems[$entry->userID] = 0; } $userToItems[$entry->userID]++; } } // remove user activity events $this->removeActivityEvents($entryData); // remove entries foreach ($this->objects as $entry) { $entry->delete(); $this->addEntryData($entry->getDecoratedObject(), 'deleted', LinkHandler::getInstance()->getLink('LinklistOverview', array('application' => 'linklist'))); EntryModificationLogHandler::getInstance()->delete($entry->getDecoratedObject()); } if (!empty($entryIDs)) { // delete like data LikeHandler::getInstance()->removeLikes('de.incendium.linklist.likeableEntry', $entryIDs); // delete comments CommentHandler::getInstance()->deleteObjects('de.incendium.linklist.entryComment', $entryIDs); // delete tag to object entries TagEngine::getInstance()->deleteObjects('de.incendium.linklist.entry', $entryIDs); // delete entry from search index SearchIndexManager::getInstance()->delete('de.incendium.linklist.entry', $entryIDs); } // decrease user entry counter if (!empty($userCounters)) { EntryEditor::updateEntryCounter($userCounters); } // delete attachments if (!empty($attachmentEntryIDs)) { AttachmentHandler::removeAttachments('de.incendium.linklist.entry', $attachmentEntryIDs); } $this->unmarkItems(); return $this->getEntryData(); }
/** * @see \wcf\system\worker\IWorker::finalize() */ public function finalize() { SearchIndexManager::getInstance()->commitBulkOperation(); }
/** * @see \wcf\data\AbstractDatabaseObjectAction::delete() */ public function delete() { $count = parent::delete(); $attachmentMessageIDs = $conversationIDs = array(); foreach ($this->objects as $message) { if (!in_array($message->conversationID, $conversationIDs)) { $conversationIDs[] = $message->conversationID; } if ($message->attachments) { $attachmentMessageIDs[] = $message->messageID; } } // rebuild conversations if (!empty($conversationIDs)) { $conversationAction = new ConversationAction($conversationIDs, 'rebuild'); $conversationAction->executeAction(); } if (!empty($this->objectIDs)) { // delete notifications UserNotificationHandler::getInstance()->deleteNotifications('conversationMessage', 'com.woltlab.wcf.conversation.message.notification', array(), $this->objectIDs); // update search index SearchIndexManager::getInstance()->delete('com.woltlab.wcf.conversation.message', $this->objectIDs); // update embedded objects MessageEmbeddedObjectManager::getInstance()->removeObjects('com.woltlab.wcf.conversation.message', $this->objectIDs); // remove moderation queues ModerationQueueManager::getInstance()->removeQueues('com.woltlab.wcf.conversation.message', $this->objectIDs); } // remove attachments if (!empty($attachmentMessageIDs)) { AttachmentHandler::removeAttachments('com.woltlab.wcf.conversation.message', $attachmentMessageIDs); } return $count; }
/** * Clears resources after successful installation. */ protected function finalize() { // create search index tables SearchIndexManager::getInstance()->createSearchIndices(); CacheHandler::getInstance()->flushAll(); }
/** * @see \wcf\system\search\ISearchEngine::getInnerJoin() */ public function getInnerJoin($objectTypeName, $q, $subjectOnly = false, PreparedStatementConditionBuilder $searchIndexCondition = null, $orderBy = 'time DESC', $limit = 1000) { $fulltextCondition = null; $relevanceCalc = ''; if (!empty($q)) { $q = $this->parseSearchQuery($q); $fulltextCondition = new PreparedStatementConditionBuilder(false); $fulltextCondition->add("MATCH (subject" . (!$subjectOnly ? ', message, metaData' : '') . ") AGAINST (? IN BOOLEAN MODE)", array($q)); if ($orderBy == 'relevance ASC' || $orderBy == 'relevance DESC') { $relevanceCalc = "MATCH (subject" . (!$subjectOnly ? ', message, metaData' : '') . ") AGAINST ('" . escapeString($q) . "') + (5 / (1 + POW(LN(1 + (" . TIME_NOW . " - time) / 2592000), 2))) AS relevance"; } } $sql = "SELECT\t\tobjectID\n\t\t\t\t\t" . ($relevanceCalc ? ',' . $relevanceCalc : '') . "\n\t\t\tFROM\t\t" . SearchIndexManager::getTableName($objectTypeName) . "\n\t\t\tWHERE\t\t" . ($fulltextCondition !== null ? $fulltextCondition : '') . "\n\t\t\t\t\t" . ($searchIndexCondition !== null && $searchIndexCondition->__toString() ? ($fulltextCondition !== null ? "AND " : '') . $searchIndexCondition : '') . "\n\t\t\t" . (!empty($orderBy) && $fulltextCondition === null ? 'ORDER BY ' . $orderBy : '') . "\n\t\t\tLIMIT\t\t" . ($limit == 1000 ? SearchEngine::INNER_SEARCH_LIMIT : $limit); return array('fulltextCondition' => $fulltextCondition, 'searchIndexCondition' => $searchIndexCondition, 'sql' => $sql); }
/** * @see \wcf\data\IDeleteAction::delete() */ public function delete() { // delete news entries parent::delete(); // collect data $newsIDs = $perUserCount = $pollIDs = array(); foreach ($this->objects as $news) { $newsIDs[] = $news->newsID; if ($news->pollID) { $pollIDs[] = $news->pollID; } if (!$news->isDisabled) { if (!isset($perUserCount[$news->userID])) { $perUserCount[$news->userID] = 0; } $perUserCount[$news->userID]++; } } if (!empty($newsIDs)) { // delete like data LikeHandler::getInstance()->removeLikes('de.voolia.news.likeableNews', $newsIDs); // delete comments CommentHandler::getInstance()->deleteObjects('de.voolia.news.comment', $newsIDs); // delete tag to object entries TagEngine::getInstance()->deleteObjects('de.voolia.news.entry', $newsIDs); // delete entry activity events UserActivityEventHandler::getInstance()->removeEvents('de.voolia.news.recentActivityEvent.news', $newsIDs); UserActivityPointHandler::getInstance()->removeEvents('de.voolia.news.activityPointEvent.news', $perUserCount); // delete entry from search index SearchIndexManager::getInstance()->delete('de.voolia.news.entry', $newsIDs); // remove object from moderation queue ModerationQueueActivationManager::getInstance()->removeModeratedContent('de.voolia.news.entry', $newsIDs); } // delete a poll if (!empty($pollIDs)) { PollManager::getInstance()->removePolls($pollIDs); } // reset the user storage data UserStorageHandler::getInstance()->resetAll('newsUnreadEntries'); UserStorageHandler::getInstance()->resetAll('newsUnreadWatchedEntries'); // reset the news cache NewsEditor::resetNewsStatsCache(); }
public function delete() { $newsIDs = array(); $attachedNewsIDs = array(); foreach ($this->objects as $news) { $newsIDs[] = $news->newsID; if ($news->attachments != 0) { $attachedNewsIDs[] = $news->newsID; } } // remove activity points UserActivityPointHandler::getInstance()->removeEvents('de.codequake.cms.activityPointEvent.news', $newsIDs); // remove attaches if (!empty($attachedNewsIDs)) { AttachmentHandler::removeAttachments('de.codequake.cms.news', $attachedNewsIDs); } // delete old search index entries if (!empty($objectIDs)) { SearchIndexManager::getInstance()->delete('de.codequake.cms.news', $newsIDs); } if (isset($this->parameters['unmarkItems'])) { $this->unmarkItems($newsIDs); } return parent::delete(); }
/** * @see \wcf\data\IDeleteAction::delete() */ public function delete() { if (empty($this->objects)) { $this->readObjects(); } // collect data $entryIDs = $entyData = $attachmentEntryIDs = $perUserCount = $pollIDs = array(); foreach ($this->objects as $entry) { $entryIDs[] = $entry->entryID; $entryData[$entry->entryID] = $entry->userID; if ($entry->pollID) { $pollIDs[] = $entry->pollID; } if ($entry->attachments) { $attachmentEntryIDs[] = $entry->entryID; } if (!$entry->isDisabled) { if (!isset($perUserCount[$entry->userID])) { $perUserCount[$entry->userID] = 0; } $perUserCount[$entry->userID]++; } } // remove user activity events $this->removeActivityEvents($entryData); // remove entries foreach ($this->objects as $entry) { $entry->delete(); $this->addEntryData($entry->getDecoratedObject(), 'deleted', LinkHandler::getInstance()->getLink('NewsOverview', array('application' => 'cms'))); NewsEntryModificationLogHandler::getInstance()->delete($entry->getDecoratedObject()); } if (!empty($entryIDs)) { // delete like data LikeHandler::getInstance()->removeLikes('de.incendium.cms.like.likeableNews', $entryIDs); // delete comments CommentHandler::getInstance()->deleteObjects('de.incendium.cms.news.comment', $entryIDs); // delete tag to object entries TagEngine::getInstance()->deleteObjects('de.incendium.cms.news.entry', $entryIDs); // delete entry activity events UserActivityEventHandler::getInstance()->removeEvents('de.incendium.cms.news.recentActivityEvent.entry', $entryIDs); UserActivityPointHandler::getInstance()->removeEvents('de.incendium.cms.news.activityPointEvent.entry', $perUserCount); // delete entry from search index SearchIndexManager::getInstance()->delete('de.incendium.cms.news.entry', $entryIDs); // remove object from moderation queue ModerationQueueActivationManager::getInstance()->removeModeratedContent('de.incendium.cms.news.entry', $entryIDs); } // delete a poll if (!empty($pollIDs)) { PollManager::getInstance()->removePolls($pollIDs); } // delete attachments if (!empty($attachmentEntryIDs)) { AttachmentHandler::removeAttachments('de.incendium.cms.news.entry', $attachmentEntryIDs); } // reset the user storage data UserStorageHandler::getInstance()->resetAll('cmsUnreadNewsEntries'); $this->unmarkItems(); return $this->getEntryData(); }