/** * Returns the singleton instance for the search core * * @return vB_Search_Core */ public static function get_instance() { if (is_null(self::$instance)) { self::$instance = new vB_Search_Core(); //initialize the search implementation global $vbulletin; if (!empty($vbulletin->options['searchimplementation'])) { call_user_func(array($vbulletin->options['searchimplementation'], 'init')); } // self::$instance->register_search_controller('vb', 'Tag', new vb_Search_SearchController_Tag()); } return self::$instance; }
/** * Operations to be done after adding a node. Putting actions here allow child classes to minimize time keeping transaction open. * * @param int $nodeid * @param mixed $data Array of data being added * @param mixed $options Array of options for the content being created- passed from add() * Understands skipNotification(s), skipUpdateLastContent. * @param mixed $cacheEvents Array of strings- cache events to be called * @param mixed $nodevals Array of field => value pairs representing the node table field values passed to create the record. * Currently most are not used but all are passed. */ protected function afterAdd($nodeid, $data, $options, $cacheEvents, $nodevals) { $userid = vB::getCurrentSession()->get('userid'); // We have singular & plural scattered throughout the code. Going to make the actual check use plural (look for // empty($options['skipNotifications']) below) and catch/convert any singular to plural so that both work. // VBV-13609 if (isset($options['skipNotification'])) { $options['skipNotifications'] = $options['skipNotification']; unset($options['skipNotification']); } $this->updateNodeOptions($nodeid, $data); vB_Cache::instance()->allCacheEvent($cacheEvents); //If published and if this is a text class we should update the text counts. if ($textCountChange = $this->textCountChange) { // apparently showapproved isn't always set. I guess since the default value for approved & showapproved is 1, we only set it to 0 if // necessary. As such, if it's not set, let's assume it's been approved $approved = (isset($nodevals['showapproved']) ? $nodevals['showapproved'] : true and isset($nodevals['approved']) ? $nodevals['approved'] : true); // parentheses, parentheses everywhere if ($nodevals['showpublished'] and $approved) { vB_Library::instance('node')->updateParentCounts($nodeid, $textCountChange, 0, $textCountChange, 0, 1, !isset($options['skipUpdateLastContent']) or !$options['skipUpdateLastContent']); } else { $published = $nodevals['showpublished']; // if it's not showpublished & showapproved, we shouldn't update the parents' last content data $updatelastcontent = false; vB_Library::instance('node')->updateParentCounts($nodeid, 0, $textCountChange, 0, $textCountChange, $published, $updatelastcontent); } } foreach ($this->qryAfterAdd as $qry) { $this->assertor->assertQuery($qry['definition'], $qry['data']); } //handle the 'index' setting; $index = empty($data['noIndex']); if ($index) { vB_Api::instanceInternal('Search')->index($nodeid); } vB_Api::instanceInternal('Search')->purgeCacheForCurrentUser(); $this->nodeLibrary->clearCacheEvents($nodeid); $node = vB_Library::instance('node')->getNode($nodeid); if ($this->isVisitorMessage($nodeid)) { if (!empty($node['setfor'])) { vB_Search_Core::instance()->purgeCacheForUser($node['setfor']); } } vB_Cache::instance()->allCacheEvent('fContentChg_' . $data['parentid']); // update tags if (!empty($data['tags'])) { $tagRet = vB_Api::instanceInternal('tags')->addTags($nodeid, $data['tags']); } //Let's see if we need to send notifications //Private messages are different. Let the subclass handle them. // (Do PMs even have notifications? Why?) if ($this->contenttype != 'vBForum_PrivateMessage' and empty($options['skipNotifications'])) { $node = vB_Library::instance('node')->getNode($nodeid, false, true); // we need to get the full content, to ensure 'channelid' is there. $notificationLib = vB_Library::instance('notification'); //If this is a visitor message we always send a message // we have the $node from above if ($this->isVisitorMessage($nodeid) and !empty($node['setfor'])) { $recipients = array($node['setfor']); $notificationLib->triggerNotificationEvent('new-visitormessage', array('sentbynodeid' => $nodeid), $recipients); } else { if ($node['starter'] > 0) { /* * Warning: Currently the content library doesn't have a defined set of rules on whether * this particular node should generate notifications or not. For example, if this node is * a grand-child of a thread starter, it could be a comment or a photo in a gallery reply * but only comments should send out notifications. * At the moment, each photo added to a gallery doesn't generate individual notifications * because the front-end createcontent controller sets the skipNotifications option when * calling content_photo API's add(). * * Note, each subclass of vB_Notification's validateAndCleanNotificationData() needs to check * the context data and prevent attachments etc from sending notifications. */ $notificationLib->triggerNotificationEvent('new-content', array('sentbynodeid' => $nodeid)); } } // Don't forget about calling insert! $notificationLib->insertNotificationsToDB(); } // @TODO VBV-2303 we can't send notifications as guest... private message library do checkFolders() which won't be valid for guests. if (empty($options['skipNotifications']) and intval(vB::getCurrentSession()->get('userid'))) { // is VBV-2303 still an issue? } // Subscribe this user to this topic if appropriate $userinfo = vB::getCurrentSession()->fetch_userinfo(); if ($userinfo['autosubscribe']) { $starterid = 0; if (!empty($nodevals['starter'])) { $starterid = $nodevals['starter']; } if (empty($starterid)) { $node = vB_Library::instance('node')->getNode($nodeid); $starterid = $node['starter']; } // subscribe to topic vB_Api::instance('follow')->add($starterid, vB_Api_Follow::FOLLOWTYPE_CONTENT); } // Update the post count for this user (content add) $this->incrementUserPostCount($node); //send moderator notification emails. if ($this->textCountChange > 0 and empty($this->skipModNotification)) { $this->sendModeratorNotification($nodeid); } }
public function clean() { vB_Search_Core::instance()->clean(); }
function delete($nodeid) { if (empty($nodeid)) { return false; } // prevent deleting of top level channels if (in_array($nodeid, vB_Api::instanceInternal('content_channel')->fetchTopLevelChannelIds())) { throw new vB_Exception_Api('cant_delete_top_level'); } // get the direct children. $children_nodes = vB::getDbAssertor()->assertQuery('vBForum:getChildrenOnly', array('nodeid' => $nodeid)); $nodeids = array(); $children_by_type = array(); foreach ($children_nodes as $node) { $children_by_type[$node['contenttypeid']][$node['nodeid']] = $node['nodeid']; $nodeids[] = $node['nodeid']; } foreach ($children_by_type as $contenttypeid => $nodes) { $contentLib = vB_Library_Content::getContentLib($contenttypeid); $contentLib->deleteChildren($nodes); } if (!empty($nodeids)) { vB_Search_Core::instance()->deleteBulk($nodeids); } // deleting the node $success = parent::delete($nodeid); // delete pages and routes $this->deleteChannelPages($nodeid); vB_Cache::instance()->event('vB_ChannelStructure_chg'); vB::getUserContext()->rebuildGroupAccess(); vB_Channel::rebuildChannelTypes(); return $success; }