コード例 #1
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state, IndexInterface $index = NULL)
 {
     $form['#index'] = $index;
     $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';
     if ($index->hasValidTracker()) {
         // Add the "Index now" form.
         $form['index'] = array('#type' => 'details', '#title' => $this->t('Index now'), '#open' => TRUE, '#attributes' => array('class' => array('container-inline')));
         $has_remaining_items = $index->getTracker()->getRemainingItemsCount() > 0;
         $all_value = $this->t('all', array(), array('context' => 'items to index'));
         $limit = array('#type' => 'textfield', '#default_value' => $all_value, '#size' => 4, '#attributes' => array('class' => array('search-api-limit')), '#disabled' => !$has_remaining_items);
         $batch_size = array('#type' => 'textfield', '#default_value' => $index->getOption('cron_limit', $this->config('search_api.settings')->get('default_cron_limit')), '#size' => 4, '#attributes' => array('class' => array('search-api-batch-size')), '#disabled' => !$has_remaining_items);
         // Here it gets complicated. We want to build a sentence from the form
         // input elements, but to translate that we have to make the two form
         // elements (for limit and batch size) pseudo-variables in the $this->t()
         // call.
         // Since we can't pass them directly, we split the translated sentence
         // (which still has the two tokens), figure out their order and then put
         // the pieces together again using the form elements' #prefix and #suffix
         // properties.
         $sentence = preg_split('/@(limit|batch_size)/', $this->t('Index @limit items in batches of @batch_size items'), -1, PREG_SPLIT_DELIM_CAPTURE);
         // Check if the sentence contains the expected amount of parts.
         if (count($sentence) === 5) {
             $first = $sentence[1];
             $form['index'][$first] = ${$first};
             $form['index'][$first]['#prefix'] = $sentence[0];
             $form['index'][$first]['#suffix'] = $sentence[2];
             $second = $sentence[3];
             $form['index'][$second] = ${$second};
             $form['index'][$second]['#suffix'] = "{$sentence[4]} ";
         } else {
             // Sentence is broken. Use fallback method instead.
             $limit['#title'] = $this->t('Number of items to index');
             $form['index']['limit'] = $limit;
             $batch_size['#title'] = $this->t('Number of items per batch run');
             $form['index']['batch_size'] = $batch_size;
         }
         // Add the value "all" so it can be used by the validation.
         $form['index']['all'] = array('#type' => 'value', '#value' => $all_value);
         $form['index']['index_now'] = array('#type' => 'submit', '#value' => $this->t('Index now'), '#disabled' => !$has_remaining_items, '#name' => 'index_now');
         // Add actions for reindexing and for clearing the index.
         $form['actions']['#type'] = 'actions';
         $form['actions']['reindex'] = array('#type' => 'submit', '#value' => $this->t('Queue all items for reindexing'), '#name' => 'reindex', '#button_type' => 'danger');
         $form['actions']['clear'] = array('#type' => 'submit', '#value' => $this->t('Clear all indexed data'), '#name' => 'clear', '#button_type' => 'danger');
     }
     return $form;
 }
コード例 #2
0
ファイル: IndexForm.php プロジェクト: jkyto/agolf
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    /** @var $index \Drupal\search_api\IndexInterface */
    $index = $this->getEntity();
    $index->setOptions($form_state->getValue('options', array()) + $this->originalEntity->getOptions());

    $datasources = $form_state->getValue('datasources', array());
    /** @var \Drupal\search_api\Datasource\DatasourceInterface[] $datasource_plugins */
    $datasource_plugins = $this->originalEntity->getDatasources(FALSE);
    $datasource_configuration = array();
    foreach ($datasources as $datasource_id) {
      $datasource = $datasource_plugins[$datasource_id];
      $datasource_form = (!empty($form['datasource_configs'][$datasource_id])) ? $form['datasource_configs'][$datasource_id] : array();
      $datasource_form_state = new SubFormState($form_state, array('datasource_configs', $datasource_id));
      $datasource->submitConfigurationForm($datasource_form, $datasource_form_state);
      $datasource_configuration[$datasource_id] = $datasource->getConfiguration();
    }
    $index->set('datasource_configs', $datasource_configuration);

    // Call submitConfigurationForm() for the (possibly new) tracker.
    // @todo It seems if we change the tracker, we would validate/submit the old
    //   tracker's form using the new tracker. Shouldn't be done, of course.
    //   Similar above for datasources, though there of course the values will
    //   just always be empty (because datasources have their plugin ID in the
    //   form structure).
    $tracker_id = $form_state->getValue('tracker', NULL);
    if ($this->originalEntity->getTrackerId() == $tracker_id) {
      $tracker = $this->originalEntity->getTracker();
    }
    else {
      $tracker = $this->trackerPluginManager->createInstance($tracker_id, array('index' => $this->originalEntity));
    }

    $tracker_form_state = new SubFormState($form_state, array('tracker_config'));
    $tracker->submitConfigurationForm($form['tracker_config'], $tracker_form_state);
    $index->set('tracker_config', $tracker->getConfiguration());

    // Invalidate caches, so this gets picked up by the views wizard.
    Cache::invalidateTags(array('views_data'));
    // Remove this line when https://www.drupal.org/node/2370365 gets fixed.
    Cache::invalidateTags(array('extension:views'));
  }
コード例 #3
0
 /**
  * Tests translation handling of the content entity datasource.
  */
 public function testItemTranslations()
 {
     // Test retrieving language and translations when no translations are
     // available.
     $entity_1 = EntityTestMul::create(array('id' => 1, 'name' => 'test 1', 'user_id' => $this->container->get('current_user')->id()));
     $entity_1->save();
     $this->assertEqual($entity_1->language()->getId(), 'en', SafeMarkup::format('%entity_type: Entity language set to site default.', array('%entity_type' => $this->testEntityTypeId)));
     $this->assertFalse($entity_1->getTranslationLanguages(FALSE), SafeMarkup::format('%entity_type: No translations are available', array('%entity_type' => $this->testEntityTypeId)));
     $entity_2 = EntityTestMul::create(array('id' => 2, 'name' => 'test 2', 'user_id' => $this->container->get('current_user')->id()));
     $entity_2->save();
     $this->assertEqual($entity_2->language()->getId(), 'en', SafeMarkup::format('%entity_type: Entity language set to site default.', array('%entity_type' => $this->testEntityTypeId)));
     $this->assertFalse($entity_2->getTranslationLanguages(FALSE), SafeMarkup::format('%entity_type: No translations are available', array('%entity_type' => $this->testEntityTypeId)));
     // Test that the datasource returns the correct item IDs.
     $datasource = $this->index->getDatasource('entity:' . $this->testEntityTypeId);
     $datasource_item_ids = $datasource->getItemIds();
     sort($datasource_item_ids);
     $expected = array('1:en', '2:en');
     $this->assertEqual($datasource_item_ids, $expected, 'Datasource returns correct item ids.');
     // Test indexing the new entity.
     $this->assertEqual($this->index->getTracker()->getIndexedItemsCount(), 0, 'The index is empty.');
     $this->assertEqual($this->index->getTracker()->getTotalItemsCount(), 2, 'There are two items to be indexed.');
     $this->index->index();
     $this->assertEqual($this->index->getTracker()->getIndexedItemsCount(), 2, 'Two items have been indexed.');
     // Now, make the first entity language-specific by assigning a language.
     $default_langcode = $this->langcodes[0];
     $entity_1->get('langcode')->setValue($default_langcode);
     $entity_1->save();
     $this->assertEqual($entity_1->language(), \Drupal::languageManager()->getLanguage($this->langcodes[0]), SafeMarkup::format('%entity_type: Entity language retrieved.', array('%entity_type' => $this->testEntityTypeId)));
     $this->assertFalse($entity_1->getTranslationLanguages(FALSE), SafeMarkup::format('%entity_type: No translations are available', array('%entity_type' => $this->testEntityTypeId)));
     // Test that the datasource returns the correct item IDs.
     $datasource_item_ids = $datasource->getItemIds();
     sort($datasource_item_ids);
     $expected = array('1:' . $this->langcodes[0], '2:en');
     $this->assertEqual($datasource_item_ids, $expected, 'Datasource returns correct item ids.');
     // Test that the index needs to be updated.
     $this->assertEqual($this->index->getTracker()->getIndexedItemsCount(), 1, 'The updated item needs to be reindexed.');
     $this->assertEqual($this->index->getTracker()->getTotalItemsCount(), 2, 'There are two items in total.');
     // Set two translations for the first entity and test that the datasource
     // returns three separate item IDs, one for each translation.
     $translation = $entity_1->getTranslation($this->langcodes[1]);
     $translation->save();
     $translation = $entity_1->getTranslation($this->langcodes[2]);
     $translation->save();
     $this->assertTrue($entity_1->getTranslationLanguages(FALSE), SafeMarkup::format('%entity_type: Translations are available', array('%entity_type' => $this->testEntityTypeId)));
     $datasource_item_ids = $datasource->getItemIds();
     sort($datasource_item_ids);
     $expected = array('1:' . $this->langcodes[0], '1:' . $this->langcodes[1], '1:' . $this->langcodes[2], '2:en');
     $this->assertEqual($datasource_item_ids, $expected, 'Datasource returns correct item ids for a translated entity.');
     // Test that the index needs to be updated.
     $this->assertEqual($this->index->getTracker()->getIndexedItemsCount(), 1, 'The updated items needs to be reindexed.');
     $this->assertEqual($this->index->getTracker()->getTotalItemsCount(), 4, 'There are four items in total.');
     // Delete one translation and test that the datasource returns only three
     // items.
     $entity_1->removeTranslation($this->langcodes[2]);
     $entity_1->save();
     $datasource_item_ids = $datasource->getItemIds();
     sort($datasource_item_ids);
     $expected = array('1:' . $this->langcodes[0], '1:' . $this->langcodes[1], '2:en');
     $this->assertEqual($datasource_item_ids, $expected, 'Datasource returns correct item ids for a translated entity.');
     // Test reindexing.
     $this->assertEqual($this->index->getTracker()->getTotalItemsCount(), 3, 'There are three items in total.');
     $this->assertEqual($this->index->getTracker()->getIndexedItemsCount(), 1, 'The updated items needs to be reindexed.');
     $this->index->index();
     $this->assertEqual($this->index->getTracker()->getIndexedItemsCount(), 3, 'Three items are indexed.');
 }
コード例 #4
0
ファイル: IndexBatchHelper.php プロジェクト: jkyto/agolf
  /**
   * Processes an index batch operation.
   *
   * @param \Drupal\search_api\IndexInterface $index
   *   The index on which items should be indexed.
   * @param int $batch_size
   *   The maximum number of items to index per batch pass.
   * @param int $limit
   *   The maximum number of items to index in total, or -1 to index all items.
   * @param array $context
   *   The current batch context, as defined in the
   *   @link batch Batch operations @endlink documentation.
   */
  public static function process(IndexInterface $index, $batch_size, $limit, array &$context) {
    // Check if the sandbox should be initialized.
    if (!isset($context['sandbox']['limit'])) {
      // Initialize the sandbox with data which is shared among the batch runs.
      $context['sandbox']['limit'] = $limit;
      $context['sandbox']['batch_size'] = $batch_size;
      $context['sandbox']['progress'] = 0;
    }
    // Check if the results should be initialized.
    if (!isset($context['results']['indexed'])) {
      // Initialize the results with data which is shared among the batch runs.
      $context['results']['indexed'] = 0;
      $context['results']['not indexed'] = 0;
    }
    // Get the remaining item count. When no valid tracker is available then
    // the value will be set to zero which will cause the batch process to
    // stop.
    $remaining_item_count = ($index->hasValidTracker() ? $index->getTracker()->getRemainingItemsCount() : 0);

    // Check if an explicit limit needs to be used.
    if ($context['sandbox']['limit'] > -1) {
      // Calculate the remaining amount of items that can be indexed. Note that
      // a minimum is taking between the allowed number of items and the
      // remaining item count to prevent incorrect reporting of not indexed
      // items.
      $actual_limit = min($context['sandbox']['limit'] - $context['sandbox']['progress'], $remaining_item_count);
    }
    else {
      // Use the remaining item count as actual limit.
      $actual_limit = $remaining_item_count;
    }

    // Store original count of items to be indexed to show progress properly.
    if (empty($context['sandbox']['original_item_count'])) {
      $context['sandbox']['original_item_count'] = min($remaining_item_count, $actual_limit);
    }

    // Determine the number of items to index for this run.
    $to_index = min($actual_limit, $context['sandbox']['batch_size']);
    // Catch any exception that may occur during indexing.
    try {
      // Index items limited by the given count.
      $indexed = $index->index($to_index);
      // Increment the indexed result and progress.
      $context['results']['indexed'] += $indexed;
      $context['results']['not indexed'] += ($to_index - $indexed);
      $context['sandbox']['progress'] += $to_index;
      // Display progress message.
      if ($indexed > 0) {
        $context['message'] = static::formatPlural($context['results']['indexed'], 'Successfully indexed 1 item.', 'Successfully indexed @count items.');
      }
      // Everything has been indexed?
      if ($indexed === 0 || $context['sandbox']['progress'] >= $context['sandbox']['original_item_count']) {
        $context['finished'] = 1;
      }
      else {
        $context['finished'] = ($context['sandbox']['progress'] / $context['sandbox']['original_item_count']);
      }
    }
    catch (\Exception $ex) {
      // Log exception to watchdog and abort the batch job.
      watchdog_exception('search_api', $ex);
      $context['message'] = static::t('An error occurred during indexing: @message', array('@message' => $ex->getMessage()));
      $context['finished'] = 1;
      $context['results']['not indexed'] += ($context['sandbox']['limit'] - $context['sandbox']['progress']);
    }
  }