public function tearDown()
 {
     if ($this->oldProcessor) {
         SearchUpdater::$processor = $this->oldProcessor;
     }
     Config::unnest();
     Injector::inst()->unregisterNamedObject('QueuedJobService');
     FullTextSearch::force_index_list();
     parent::tearDown();
 }
 function setUp()
 {
     parent::setUp();
     if (self::$index === null) {
         self::$index = singleton(get_class($this) . '_Index');
     } else {
         self::$index->reset();
     }
     SearchUpdater::bind_manipulation_capture();
     Config::nest();
     Config::inst()->update('Injector', 'SearchUpdateProcessor', array('class' => 'SearchUpdateImmediateProcessor'));
     FullTextSearch::force_index_list(self::$index);
     SearchUpdater::clear_dirty_indexes();
 }
 function testExcludeVariantState()
 {
     $index = singleton('SearchVariantVersionedTest_IndexNoStage');
     FullTextSearch::force_index_list($index);
     // Check that write doesn't update stage
     $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Foo'));
     $item->write();
     SearchUpdater::flush_dirty_indexes();
     $this->assertEquals($index->getAdded(array('ID', '_versionedstage')), array());
     // Check that publish updates Live
     $index->reset();
     $item->publish("Stage", "Live");
     SearchUpdater::flush_dirty_indexes();
     $this->assertEquals($index->getAdded(array('ID', '_versionedstage')), array(array('ID' => $item->ID, '_versionedstage' => 'Live')));
 }
 function setUp()
 {
     parent::setUp();
     // Check subsites installed
     if (!class_exists('Subsite') || !class_exists('SubsitePolyhome')) {
         return $this->markTestSkipped('The subsites polyhome module is not installed');
     }
     if (self::$index === null) {
         self::$index = singleton('SearchVariantSiteTreeSubsitesPolyhomeTest_Index');
     }
     if (self::$subsite_a === null) {
         self::$subsite_a = new Subsite();
         self::$subsite_a->write();
         self::$subsite_b = new Subsite();
         self::$subsite_b->write();
     }
     FullTextSearch::force_index_list(self::$index);
     SearchUpdater::clear_dirty_indexes();
 }
 /**
  * Generates the list of indexes to process for the dirty items
  * 
  * @return array
  */
 protected function prepareIndexes()
 {
     $originalState = SearchVariant::current_state();
     $dirtyIndexes = array();
     $dirty = $this->getSource();
     $indexes = FullTextSearch::get_indexes();
     foreach ($dirty as $base => $statefulids) {
         if (!$statefulids) {
             continue;
         }
         foreach ($statefulids as $statefulid) {
             $state = $statefulid['state'];
             $ids = $statefulid['ids'];
             SearchVariant::activate_state($state);
             // Ensure that indexes for all new / updated objects are included
             $objs = DataObject::get($base)->byIDs(array_keys($ids));
             foreach ($objs as $obj) {
                 foreach ($ids[$obj->ID] as $index) {
                     if (!$indexes[$index]->variantStateExcluded($state)) {
                         $indexes[$index]->add($obj);
                         $dirtyIndexes[$index] = $indexes[$index];
                     }
                 }
                 unset($ids[$obj->ID]);
             }
             // Generate list of records that do not exist and should be removed
             foreach ($ids as $id => $fromindexes) {
                 foreach ($fromindexes as $index) {
                     if (!$indexes[$index]->variantStateExcluded($state)) {
                         $indexes[$index]->delete($base, $id, $state);
                         $dirtyIndexes[$index] = $indexes[$index];
                     }
                 }
             }
         }
     }
     SearchVariant::activate_state($originalState);
     return $dirtyIndexes;
 }
 public function setUp()
 {
     parent::setUp();
     if (!class_exists('Phockito')) {
         $this->skipTest = true;
         return $this->markTestSkipped("These tests need the Phockito module installed to run");
     }
     // Check versioned available
     if (!class_exists('Versioned')) {
         $this->skipTest = true;
         return $this->markTestSkipped('The versioned decorator is not installed');
     }
     if (self::$index === null) {
         self::$index = singleton('SolrVersionedTest_Index');
     }
     SearchUpdater::bind_manipulation_capture();
     Config::nest();
     Config::inst()->update('Injector', 'SearchUpdateProcessor', array('class' => 'SearchUpdateImmediateProcessor'));
     FullTextSearch::force_index_list(self::$index);
     SearchUpdater::clear_dirty_indexes();
     $this->oldMode = Versioned::get_reading_mode();
     Versioned::reading_stage('Stage');
 }
 public function searchFetchByIds($object_ids, $loader_class_name, &$counter, $params = array(), $fetch_method = 'fetch_by_ids')
 {
     if (!$this->_query_object) {
         return array();
     }
     $search = new FullTextSearch();
     $search_result = $search->findByIds($object_ids, $this->_query_object);
     if (!count($search_result)) {
         return array();
     }
     $counter = 0;
     $count_method = $fetch_method . '_count';
     $site_object = Limb::toolkit()->createSiteObject($loader_class_name);
     $counter = $site_object->{$count_method}(array_keys($search_result), $params);
     $fetched_objects = $site_object->{$fetch_method}(array_keys($search_result), $params);
     if (!count($fetched_objects)) {
         return array();
     }
     foreach ($search_result as $key => $score) {
         if (isset($fetched_objects[$key])) {
             $result[$key] = $fetched_objects[$key];
             $result[$key]['score'] = $score;
         }
     }
     Limb::toolkit()->getAuthorizer()->assignActionsToObjects($result);
     $this->_assignPaths($result);
     $this->_assignSearchPaths($result, isset($params['offset']) ? $params['offset'] : 0);
     return $result;
 }
 /**
  * Sometimes, like when in tests, you want to restrain the actual indexes to a subset
  *
  * Call with one argument - an array of class names, index instances or classname => indexinstance pairs (can be mixed).
  * Alternatively call with multiple arguments, each of which is a class name or index instance
  *
  * From then on, fulltext search system will only see those indexes passed in this most recent call.
  *
  * Passing in no arguments resets back to automatic index list
  *
  * Alternatively you can use `FullTextSearch.indexes` to configure a list of indexes via config.
  */
 static function force_index_list()
 {
     $indexes = func_get_args();
     // No arguments = back to automatic
     if (!$indexes) {
         self::get_indexes(null, true);
         return;
     }
     // Arguments can be a single array
     if (is_array($indexes[0])) {
         $indexes = $indexes[0];
     }
     // Reset to empty first
     self::$all_indexes = array();
     self::$indexes_by_subclass = array();
     // And parse out alternative type combos for arguments and add to allIndexes
     foreach ($indexes as $class => $index) {
         if (is_string($index)) {
             $class = $index;
             $index = singleton($class);
         }
         if (is_numeric($class)) {
             $class = get_class($index);
         }
         self::$all_indexes[$class] = $index;
     }
 }
 public function tearDown()
 {
     FullTextSearch::force_index_list();
     SolrReindexTest_Variant::disable();
     parent::tearDown();
 }
 /**
  * Send updates to the current search processor for execution
  * 
  * @param array $writes
  */
 public static function process_writes($writes)
 {
     foreach ($writes as $write) {
         // For every index
         foreach (FullTextSearch::get_indexes() as $index => $instance) {
             // If that index as a field from this class
             if (SearchIntrospection::is_subclass_of($write['class'], $instance->dependancyList)) {
                 // Get the dirty IDs
                 $dirtyids = $instance->getDirtyIDs($write['class'], $write['id'], $write['statefulids'], $write['fields']);
                 // Then add then then to the global list to deal with later
                 foreach ($dirtyids as $dirtyclass => $ids) {
                     if ($ids) {
                         if (!self::$processor) {
                             self::$processor = Injector::inst()->create('SearchUpdateProcessor');
                         }
                         self::$processor->addDirtyIDs($dirtyclass, $ids, $index);
                     }
                 }
             }
         }
     }
     // If we do have some work to do register the shutdown function to actually do the work
     // Don't do it if we're testing - there's no database connection outside the test methods, so we'd
     // just get errors
     $runningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
     if (self::$processor && !self::$registered && !$runningTests) {
         register_shutdown_function(array("SearchUpdater", "flush_dirty_indexes"));
         self::$registered = true;
     }
 }
 /**
  * Get the list of index names we should process
  *
  * @return array
  */
 public function getAllIndexes()
 {
     if (empty($this->indexes)) {
         $indexes = FullTextSearch::get_indexes();
         $this->indexes = array_keys($indexes);
     }
     return $this->indexes;
 }
 static function get_indexes()
 {
     return FullTextSearch::get_indexes('SolrIndex');
 }