コード例 #1
0
ファイル: AddURLTest.php プロジェクト: jkyto/agolf
  /**
   * Creates a new processor object for use in the tests.
   */
  protected function setUp() {
    parent::setUp();

    // Create a mock for the URL to be returned.
    $url = $this->getMockBuilder('Drupal\Core\Url')
      ->disableOriginalConstructor()
      ->getMock();
    $url->expects($this->any())
      ->method('toString')
      ->will($this->returnValue('http://www.example.com/node/example'));

    // Mock the data source of the indexer to return the mocked url object.
    $datasource = $this->getMock('Drupal\search_api\Datasource\DatasourceInterface');
    $datasource->expects($this->any())
      ->method('getItemUrl')
      ->withAnyParameters()
      ->will($this->returnValue($url));

    // Create a mock for the index to return the datasource mock.
    /** @var \Drupal\search_api\IndexInterface $index */
    $index = $this->index = $this->getMock('Drupal\search_api\IndexInterface');
    $this->index->expects($this->any())
      ->method('getDatasource')
      ->with('entity:node')
      ->will($this->returnValue($datasource));

    // Create the tested processor and set the mocked indexer.
    $this->processor = new AddURL(array(), 'add_url', array());
    $this->processor->setIndex($index);
    /** @var \Drupal\Core\StringTranslation\TranslationInterface $translation */
    $translation = $this->getStringTranslationStub();
    $this->processor->setStringTranslation($translation);
  }
コード例 #2
0
 /**
  * {@inheritdoc}
  */
 public static function supportsIndex(IndexInterface $index)
 {
     foreach ($index->getDatasources() as $datasource) {
         if (in_array($datasource->getEntityTypeId(), array('node', 'comment'))) {
             return TRUE;
         }
     }
     return FALSE;
 }
コード例 #3
0
 /**
  * Overrides \Drupal\search_api\Processor\ProcessorPluginBase::supportsIndex().
  *
  * This plugin only supports indexes containing users.
  */
 public static function supportsIndex(IndexInterface $index)
 {
     foreach ($index->getDatasources() as $datasource) {
         if ($datasource->getEntityTypeId() == 'user') {
             return TRUE;
         }
     }
     return FALSE;
 }
コード例 #4
0
 /**
  * Creates a new processor object for use in the tests.
  */
 public function setUp()
 {
     parent::setUp();
     $this->setUpDataTypePlugin();
     $this->index = $this->getMock('Drupal\\search_api\\IndexInterface');
     $this->index->expects($this->any())->method('status')->will($this->returnValue(TRUE));
     $fields = $this->getTestItem()[$this->itemIds[0]]->getFields();
     $this->index->expects($this->any())->method('getFields')->will($this->returnValue($fields));
     $this->processor = new TestFieldsProcessorPlugin(array('index' => $this->index), '', array());
 }
コード例 #5
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state, IndexInterface $index = NULL)
 {
     if (!isset($index)) {
         return array();
     }
     $form['#index'] = $index;
     $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';
     if ($index->hasValidTracker()) {
         if (!\Drupal::getContainer()->get('search_api.index_task_manager')->isTrackingComplete($index)) {
             $form['tracking'] = array('#type' => 'details', '#title' => $this->t('Track items for index'), '#description' => $this->t('Not all items have been tracked for this index. This means the displayed index status is incomplete and not all items will currently be indexed.'), '#open' => TRUE, '#attributes' => array('class' => array('container-inline')));
             $form['tracking']['index_now'] = array('#type' => 'submit', '#value' => $this->t('Track now'), '#name' => 'track_now');
         }
         // 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->getTrackerInstance()->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;
 }
コード例 #6
0
  /**
   * Tests custom data types integration.
   */
  public function testCustomDataTypes() {
    $original_value = $this->entities[1]->get('name')->value;
    $original_type = $this->index->getFields()['entity:entity_test/name']->getType();

    $item = $this->index->loadItem('entity:entity_test/1:en');
    $item = Utility::createItemFromObject($this->index, $item, 'entity:entity_test/1:en');
    $name_field = $item->getField('entity:entity_test/name');

    $processed_value = $name_field->getValues()[0];
    $processed_type = $name_field->getType();

    $this->assertEqual($processed_value, $original_value, 'The processed value matches the original value');
    $this->assertEqual($processed_type, $original_type, 'The processed type matches the original type.');

    // Reset the fields on the item and change to the supported data type.
    $item->setFieldsExtracted(FALSE);
    $item->setFields(array());
    $this->index->getFields()['entity:entity_test/name']->setType('search_api_test_data_type');
    $name_field = $item->getField('entity:entity_test/name');

    $processed_value = $name_field->getValues()[0];
    $processed_type = $name_field->getType();

    $this->assertEqual($processed_value, $original_value, 'The processed value matches the original value');
    $this->assertEqual($processed_type, 'search_api_test_data_type', 'The processed type matches the new type.');

    // Reset the fields on the item and change to the non-supported data type.
    $item->setFieldsExtracted(FALSE);
    $item->setFields(array());
    $this->index->getFields()['entity:entity_test/name']->setType('search_api_unsupported_test_data_type');
    $name_field = $item->getField('entity:entity_test/name');

    $processed_value = $name_field->getValues()[0];
    $processed_type = $name_field->getType();

    $this->assertEqual($processed_value, $original_value, 'The processed value matches the original value');
    $this->assertEqual($processed_type, 'integer', 'The processed type matches the fallback type.');

    // Reset the fields on the item and change to the data altering data type.
    $item->setFieldsExtracted(FALSE);
    $item->setFields(array());
    $this->index->getFields()['entity:entity_test/name']->setType('search_api_altering_test_data_type');
    $name_field = $item->getField('entity:entity_test/name');

    $processed_value = $name_field->getValues()[0];
    $processed_type = $name_field->getType();

    $this->assertEqual($processed_value, strlen($original_value), 'The processed value matches the altered original value');
    $this->assertEqual($processed_type, 'search_api_altering_test_data_type', 'The processed type matches the defined type.');
  }
コード例 #7
0
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     $values = $form_state->getValues();
     $new_settings = array();
     // Store processor settings.
     // @todo Go through all available processors, enable/disable with method on
     //   processor plugin to allow reaction.
     /** @var \Drupal\search_api\Processor\ProcessorInterface $processor */
     $processors = $this->entity->getProcessors(FALSE);
     foreach ($processors as $processor_id => $processor) {
         if (empty($values['status'][$processor_id])) {
             continue;
         }
         $new_settings[$processor_id] = array('processor_id' => $processor_id, 'weights' => array(), 'settings' => array());
         $processor_values = $values['processors'][$processor_id];
         if (!empty($processor_values['weights'])) {
             $new_settings[$processor_id]['weights'] = $processor_values['weights'];
         }
         if (isset($form['settings'][$processor_id])) {
             $processor_form_state = new SubFormState($form_state, array('processors', $processor_id, 'settings'));
             $processor->submitConfigurationForm($form['settings'][$processor_id], $processor_form_state);
             $new_settings[$processor_id]['settings'] = $processor->getConfiguration();
         }
     }
     // Sort the processors so we won't have unnecessary changes.
     ksort($new_settings);
     if (!$this->entity->getOption('processors', array()) !== $new_settings) {
         $this->entity->setOption('processors', $new_settings);
         $this->entity->save();
         $this->entity->reindex();
         drupal_set_message($this->t('The indexing workflow was successfully edited. All content was scheduled for reindexing so the new settings can take effect.'));
     } else {
         drupal_set_message($this->t('No values were changed.'));
     }
 }
コード例 #8
0
ファイル: Item.php プロジェクト: curveagency/intranet
 /**
  * {@inheritdoc}
  */
 public function getFields($extract = TRUE)
 {
     if ($extract && !$this->fieldsExtracted) {
         $data_type_fallback_mapping = Utility::getDataTypeFallbackMapping($this->index);
         foreach (array(NULL, $this->getDatasourceId()) as $datasource_id) {
             $fields_by_property_path = array();
             foreach ($this->index->getFieldsByDatasource($datasource_id) as $field_id => $field) {
                 // Don't overwrite fields that were previously set.
                 if (empty($this->fields[$field_id])) {
                     $this->fields[$field_id] = clone $field;
                     $field_data_type = $this->fields[$field_id]->getType();
                     // If the field data type is in the fallback mapping list, then use
                     // the fallback type as field type.
                     if (isset($data_type_fallback_mapping[$field_data_type])) {
                         $this->fields[$field_id]->setType($data_type_fallback_mapping[$field_data_type]);
                     }
                     $fields_by_property_path[$field->getPropertyPath()] = $this->fields[$field_id];
                 }
             }
             if ($datasource_id && $fields_by_property_path) {
                 try {
                     Utility::extractFields($this->getOriginalObject(), $fields_by_property_path);
                 } catch (SearchApiException $e) {
                     // If we couldn't load the object, just log an error and fail
                     // silently to set the values.
                     watchdog_exception('search_api', $e);
                 }
             }
         }
         $this->fieldsExtracted = TRUE;
     }
     return $this->fields;
 }
コード例 #9
0
ファイル: IndexForm.php プロジェクト: nB-MDSO/mdso-d8blog
 /**
  * {@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_settings = 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_settings[$datasource_id] = $datasource;
     }
     $index->setDatasources($datasource_settings);
     // 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->getTrackerInstance();
     } 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->setTracker($tracker);
 }
コード例 #10
0
 /**
  * {@inheritdoc}
  */
 public function render($row)
 {
     $datasource_id = $row->search_api_datasource;
     if (!$row->_item instanceof ComplexDataInterface) {
         $context = array('%item_id' => $row->search_api_id, '%view' => $this->view->storage->label());
         $this->getLogger()->warning('Failed to load item %item_id in view %view.', $context);
         return '';
     }
     // @todo Use isValidDatasource() instead.
     try {
         $datasource = $this->index->getDatasource($datasource_id);
     } catch (SearchApiException $e) {
         $context = array('%datasource' => $datasource_id, '%view' => $this->view->storage->label());
         $this->getLogger()->warning('Item of unknown datasource %datasource returned in view %view.', $context);
         return '';
     }
     // Always use the default view mode if it was not set explicitly in the
     // options.
     $view_mode = 'default';
     $bundle = $this->index->getDatasource($datasource_id)->getItemBundle($row->_item);
     if (isset($this->options['view_modes'][$datasource_id][$bundle])) {
         $view_mode = $this->options['view_modes'][$datasource_id][$bundle];
     }
     try {
         return $this->index->getDatasource($datasource_id)->viewItem($row->_item, $view_mode);
     } catch (SearchApiException $e) {
         watchdog_exception('search_api', $e);
         return '';
     }
 }
コード例 #11
0
 /**
  * Cancels the editing of the index's fields.
  *
  * @param array $form
  *   An associative array containing the structure of the form.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The current state of the form.
  */
 public function cancel(array &$form, FormStateInterface $form_state)
 {
     if ($this->entity instanceof UnsavedConfigurationInterface && $this->entity->hasChanges()) {
         $this->entity->discardChanges();
     }
     $form_state->setRedirectUrl($this->entity->toUrl('canonical'));
 }
コード例 #12
0
 /**
  * Tests task system integration for the deleteAllIndexItems() method.
  */
 public function testDeleteAllIndexItems()
 {
     // Set exception for deleteAllIndexItems() and reset the list of successful
     // backend method calls.
     $this->state->set('search_api_test_backend.exception.deleteAllIndexItems', TRUE);
     $this->getCalledServerMethods();
     // Try to update the index.
     $this->server->deleteAllIndexItems($this->index);
     $this->assertEqual($this->getCalledServerMethods(), array(), 'deleteAllIndexItems correctly threw an exception.');
     $tasks = $this->getServerTasks();
     if (count($tasks) == 1) {
         $task_created = $tasks[0]->type === 'deleteAllIndexItems';
     }
     $this->assertTrue(!empty($task_created), 'The deleteAllIndexItems task was successfully added.');
     if ($tasks) {
         $this->assertEqual($tasks[0]->index_id, $this->index->id(), 'The right index ID was used for the deleteAllIndexItems task.');
     }
     // Check whether other task-system-integrated methods now fail, too.
     $this->server->updateIndex($this->index);
     $this->assertEqual($this->getCalledServerMethods(), array(), 'updateIndex was not executed.');
     $tasks = $this->getServerTasks();
     if (count($tasks) == 2) {
         $this->pass("Second task ('updateIndex') was added.");
         $this->assertEqual($tasks[0]->type, 'deleteAllIndexItems', 'First task stayed the same.');
         $this->assertEqual($tasks[1]->type, 'updateIndex', 'New task was queued as last.');
     } else {
         $this->fail("Second task (updateIndex) was not added.");
     }
     // Let deleteAllIndexItems() succeed again, then trigger the task execution
     // with a call to indexItems().
     $this->state->set('search_api_test_backend.exception.deleteAllIndexItems', FALSE);
     $this->server->indexItems($this->index, array());
     $this->assertEqual($this->getServerTasks(), array(), 'Server tasks were correctly executed.');
     $this->assertEqual($this->getCalledServerMethods(), array('deleteAllIndexItems', 'updateIndex', 'indexItems'), 'Right methods were called during task execution.');
 }
コード例 #13
0
ファイル: FieldTrait.php プロジェクト: jkyto/agolf
 /**
  * Retrieves the properties that should be serialized.
  *
  * Used in __sleep(), but extracted to be more easily usable for subclasses.
  *
  * @return array
  *   An array mapping property names of this object to their values.
  */
 protected function getSerializationProperties() {
   $this->indexId = $this->index->id();
   $properties = get_object_vars($this);
   // Don't serialize objects in properties.
   unset($properties['index'], $properties['datasource'], $properties['dataDefinition']);
   return $properties;
 }
コード例 #14
0
ファイル: Field.php プロジェクト: curveagency/intranet
 /**
  * {@inheritdoc}
  */
 public function __sleep()
 {
     $this->indexId = $this->index->id();
     $properties = get_object_vars($this);
     // Don't serialize objects in properties or the field values.
     unset($properties['index'], $properties['datasource'], $properties['dataDefinition'], $properties['values']);
     return array_keys($properties);
 }
コード例 #15
0
 /**
  * {@inheritdoc}
  */
 public function getQueryTypesForFacet(FacetInterface $facet)
 {
     // Get our Facets Field Identifier, which is equal to the Search API Field
     // identifier.
     $field_id = $facet->getFieldIdentifier();
     // Get the Search API Server.
     $server = $this->index->getServerInstance();
     // Get the Search API Backend.
     $backend = $server->getBackend();
     $fields = $this->index->getFields();
     foreach ($fields as $field) {
         if ($field->getFieldIdentifier() == $field_id) {
             return $this->getQueryTypesForDataType($backend, $field->getType());
         }
     }
     throw new InvalidQueryTypeException($this->t("No available query types were found for facet @facet", ['@facet' => $facet->getName()]));
 }
コード例 #16
0
 /**
  * Tests whether the properties are correctly altered.
  *
  * @see \Drupal\search_api\Plugin\search_api\processor\AggregatedField::alterPropertyDefinitions()
  */
 public function testAlterPropertyDefinitions()
 {
     $fields = array('entity:test1/foo', 'entity:test1/foo:bar', 'entity:test2/foobaz:bla');
     $index_fields = array();
     foreach ($fields as $field_id) {
         $field_object = Utility::createField($this->index, $field_id);
         list($prefix, $label) = str_replace(':', ' » ', Utility::splitCombinedId($field_id));
         $field_object->setLabelPrefix($prefix . ' » ');
         $field_object->setLabel($label);
         $index_fields[$field_id] = $field_object;
     }
     $this->index->expects($this->any())->method('getFields')->willReturn($index_fields);
     $this->index->method('getPropertyDefinitions')->willReturn(array());
     $dummy_datasource = $this->getMock('Drupal\\search_api\\Datasource\\DatasourceInterface');
     $dummy_datasource->method('label')->willReturn('datasource');
     $this->index->method('getDatasources')->willReturn(array('entity:test1' => $dummy_datasource, 'entity:test2' => $dummy_datasource));
     $configuration['fields'] = array('search_api_aggregation_1' => array('label' => 'Field 1', 'type' => 'union', 'fields' => array('entity:test1/foo', 'entity:test1/foo:bar', 'entity:test2/foobaz:bla')), 'search_api_aggregation_2' => array('label' => 'Field 2', 'type' => 'max', 'fields' => array('entity:test1/foo:bar')));
     $this->processor->setConfiguration($configuration);
     /** @var \Drupal\Core\StringTranslation\TranslationInterface $translation */
     $translation = $this->getStringTranslationStub();
     $this->processor->setStringTranslation($translation);
     // Check for modified properties when no datasource is given.
     $properties = array();
     $this->processor->alterPropertyDefinitions($properties, NULL);
     $property_added = array_key_exists('search_api_aggregation_1', $properties);
     $this->assertTrue($property_added, 'The "search_api_aggregation_1" property was added to the properties.');
     if ($property_added) {
         $this->assertInstanceOf('Drupal\\Core\\TypedData\\DataDefinitionInterface', $properties['search_api_aggregation_1'], 'The "search_api_aggregation_1" property contains a valid data definition.');
         if ($properties['search_api_aggregation_1'] instanceof DataDefinitionInterface) {
             $this->assertEquals('string', $properties['search_api_aggregation_1']->getDataType(), 'Correct data type set in the data definition.');
             $this->assertEquals('Field 1', $properties['search_api_aggregation_1']->getLabel(), 'Correct label set in the data definition.');
             $fields_string = 'datasource » foo, datasource » foo:bar, datasource » foobaz:bla';
             $description = $translation->translate('A @type aggregation of the following fields: @fields.', array('@type' => $translation->translate('Union'), '@fields' => $fields_string));
             $this->assertEquals($description, $properties['search_api_aggregation_1']->getDescription(), 'Correct description set in the data definition.');
         }
     }
     $property_added = array_key_exists('search_api_aggregation_2', $properties);
     $this->assertTrue($property_added, 'The "search_api_aggregation_2" property was added to the properties.');
     if ($property_added) {
         $this->assertInstanceOf('Drupal\\Core\\TypedData\\DataDefinitionInterface', $properties['search_api_aggregation_2'], 'The "search_api_aggregation_2" property contains a valid data definition.');
         if ($properties['search_api_aggregation_2'] instanceof DataDefinitionInterface) {
             $this->assertEquals('integer', $properties['search_api_aggregation_2']->getDataType(), 'Correct data type set in the data definition.');
             $this->assertEquals('Field 2', $properties['search_api_aggregation_2']->getLabel(), 'Correct label set in the data definition.');
             $description = $translation->translate('A @type aggregation of the following fields: @fields.', array('@type' => $translation->translate('Maximum'), '@fields' => 'datasource » foo:bar'));
             $this->assertEquals($description, $properties['search_api_aggregation_2']->getDescription(), 'Correct description set in the data definition.');
         }
     }
     // Test whether the properties of specific datasources stay untouched.
     $properties = array();
     /** @var \Drupal\search_api\Datasource\DatasourceInterface $datasource */
     $datasource = $this->getMock('Drupal\\search_api\\Datasource\\DatasourceInterface');
     $this->processor->alterPropertyDefinitions($properties, $datasource);
     $this->assertEmpty($properties, 'Datasource-specific properties did not get changed.');
 }
コード例 #17
0
 /**
  * Form submission handler for adding a new field to the index.
  *
  * @param array $form
  *   An associative array containing the structure of the form.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The current state of the form.
  */
 public function addField(array $form, FormStateInterface $form_state)
 {
     $button = $form_state->getTriggeringElement();
     if (!$button) {
         return;
     }
     /** @var \Drupal\Core\TypedData\DataDefinitionInterface $property */
     $property = $button['#property'];
     list($datasource_id, $property_path) = Utility::splitCombinedId($button['#name']);
     $field = Utility::createFieldFromProperty($this->entity, $property, $datasource_id, $property_path, NULL, $button['#data_type']);
     $field->setLabel($button['#prefixed_label']);
     $this->entity->addField($field);
     $args['%label'] = $field->getLabel();
     drupal_set_message($this->t('Field %label was added to the index.', $args));
 }
コード例 #18
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'));
  }
コード例 #19
0
ファイル: ProcessorTestBase.php プロジェクト: jkyto/agolf
  /**
   * Generates some test items.
   *
   * @param array[] $items
   *   Array of items to be transformed into proper search item objects. Each
   *   item in this array is an associative array with the following keys:
   *   - datasource: The datasource plugin ID.
   *   - item: The item object to be indexed.
   *   - item_id: The datasource-specific raw item ID.
   *   - *: Any other keys will be treated as property paths, and their values
   *     as a single value for a field with that property path.
   *
   * @return \Drupal\search_api\Item\ItemInterface[]
   *   The generated test items.
   */
  public function generateItems(array $items) {
    /** @var \Drupal\search_api\Item\ItemInterface[] $extracted_items */
    $extracted_items = array();
    foreach ($items as $item) {
      $id = Utility::createCombinedId($item['datasource'], $item['item_id']);
      $extracted_items[$id] = Utility::createItemFromObject($this->index, $item['item'], $id);
      foreach (array(NULL, $item['datasource']) as $datasource_id) {
        foreach ($this->index->getFieldsByDatasource($datasource_id) as $key => $field) {
          /** @var \Drupal\search_api\Item\FieldInterface $field */
          $field = clone $field;
          if (isset($item[$field->getPropertyPath()])) {
            $field->addValue($item[$field->getPropertyPath()]);
          }
          $extracted_items[$id]->setField($key, $field);
        }
      }
    }

    return $extracted_items;
  }
コード例 #20
0
 /**
  * Enables a search index without a confirmation form.
  *
  * @param \Drupal\search_api\IndexInterface $search_api_index
  *   The index to be enabled.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   The response to send to the browser.
  */
 public function indexBypassEnable(IndexInterface $search_api_index)
 {
     // Enable the index.
     $search_api_index->setStatus(TRUE)->save();
     // \Drupal\search_api\Entity\Index::preSave() doesn't allow an index to be
     // enabled if its server is not set or disabled.
     if ($search_api_index->status()) {
         // Notify the user about the status change.
         drupal_set_message($this->t('The search index %name has been enabled.', array('%name' => $search_api_index->label())));
     } else {
         // Notify the user that the status change did not succeed.
         drupal_set_message($this->t('The search index %name could not be enabled. Check if its server is set and enabled.', array('%name' => $search_api_index->label())));
     }
     // Redirect to the index's "View" page.
     $url = $search_api_index->urlInfo('canonical');
     return $this->redirect($url->getRouteName(), $url->getRouteParameters());
 }
コード例 #21
0
ファイル: Query.php プロジェクト: jkyto/agolf
 /**
  * Implements the magic __toString() method to simplify debugging.
  */
 public function __toString() {
   $ret = 'Index: ' . $this->index->id() . "\n";
   $ret .= 'Keys: ' . str_replace("\n", "\n  ", var_export($this->origKeys, TRUE)) . "\n";
   if (isset($this->keys)) {
     $ret .= 'Parsed keys: ' . str_replace("\n", "\n  ", var_export($this->keys, TRUE)) . "\n";
     $ret .= 'Searched fields: ' . (isset($this->fields) ? implode(', ', $this->fields) : '[ALL]') . "\n";
   }
   if ($filter = (string) $this->filter) {
     $filter = str_replace("\n", "\n  ", $filter);
     $ret .= "Filters:\n  $filter\n";
   }
   if ($this->sorts) {
     $sorts = array();
     foreach ($this->sorts as $field => $order) {
       $sorts[] = "$field $order";
     }
     $ret .= 'Sorting: ' . implode(', ', $sorts) . "\n";
   }
   // @todo Fix for entities contained in options (which might kill
   //    var_export() due to circular references).
   $ret .= 'Options: ' . str_replace("\n", "\n  ", var_export($this->options, TRUE)) . "\n";
   return $ret;
 }
コード例 #22
0
 /**
  * Tests whether deleting an index works correctly.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The index used for the test.
  */
 public function indexDelete(IndexInterface $index)
 {
     $this->storage->delete(array($index));
     $loaded_index = $this->storage->load($index->id());
     $this->assertNull($loaded_index);
 }
コード例 #23
0
ファイル: Utility.php プロジェクト: curveagency/intranet
 /**
  * Finds a new unique field identifier on the given index.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The search index.
  * @param string $property_path
  *   The property path on which the field identifier should be based. Only the
  *   last component of the property path will be considered.
  *
  * @return string
  *   A new unique field identifier on the given index.
  */
 public static function getNewFieldId(IndexInterface $index, $property_path)
 {
     list(, $suggested_id) = static::splitPropertyPath($property_path);
     $field_id = $suggested_id;
     $i = 0;
     while ($index->getField($field_id)) {
         $field_id = $suggested_id . '_' . ++$i;
     }
     return $field_id;
 }
コード例 #24
0
ファイル: TestBackend.php プロジェクト: curveagency/intranet
 /**
  * {@inheritdoc}
  */
 public function updateIndex(IndexInterface $index)
 {
     $this->checkError(__FUNCTION__);
     $index->reindex();
 }
コード例 #25
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.');
 }
コード例 #26
0
 /**
  * Removes a field from a search index.
  *
  * @param \Drupal\search_api\IndexInterface $search_api_index
  *   The search index.
  * @param string $field_id
  *   The ID of the field to remove.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   The response to send to the browser.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  *   Thrown when the field was not found.
  */
 public function removeField(IndexInterface $search_api_index, $field_id)
 {
     $fields = $search_api_index->getFields();
     if (isset($fields[$field_id])) {
         try {
             $search_api_index->removeField($field_id);
             $search_api_index->save();
         } catch (SearchApiException $e) {
             $args['%field'] = $fields[$field_id]->getLabel();
             drupal_set_message($this->t('The field %field is locked and cannot be removed.', $args), 'error');
         }
     } else {
         throw new NotFoundHttpException();
     }
     // Redirect to the index's "View" page.
     $url = $search_api_index->toUrl('fields');
     return $this->redirect($url->getRouteName(), $url->getRouteParameters());
 }
コード例 #27
0
 /**
  * {@inheritdoc}
  */
 public function calculateDependencies()
 {
     $dependencies = parent::calculateDependencies();
     $dependencies[$this->index->getConfigDependencyKey()][] = $this->index->getConfigDependencyName();
     return $dependencies;
 }
コード例 #28
0
 /**
  * Asserts enable/disable operations for a search server or index.
  *
  * @param \Drupal\search_api\ServerInterface|\Drupal\search_api\IndexInterface $entity
  *   A search server or index.
  */
 protected function assertEntityStatusChange($entity)
 {
     $this->drupalGet($this->overviewPageUrl);
     $row_class = Html::cleanCssIdentifier($entity->getEntityTypeId() . '-' . $entity->id());
     $this->assertFieldByXPath('//tr[contains(@class,"' . $row_class . '") and contains(@class, "search-api-list-enabled")]', NULL, 'The newly created entity is enabled by default.');
     // The first "Disable" link on the page belongs to our server, the second
     // one to our index.
     $this->clickLink('Disable', $entity instanceof ServerInterface ? 0 : 1);
     // Submit the confirmation form and test that the entity has been disabled.
     $this->drupalPostForm(NULL, array(), 'Disable');
     $this->assertFieldByXPath('//tr[contains(@class,"' . $row_class . '") and contains(@class, "search-api-list-disabled")]', NULL, 'The entity has been disabled.');
     // Now enable the entity and verify that the operation succeeded.
     $this->clickLink('Enable');
     $this->drupalGet($this->overviewPageUrl);
     $this->assertFieldByXPath('//tr[contains(@class,"' . $row_class . '") and contains(@class, "search-api-list-enabled")]', NULL, 'The entity has benn enabled.');
 }
コード例 #29
0
ファイル: Index.php プロジェクト: curveagency/intranet
 /**
  * Reacts to changes in processor configuration.
  *
  * @param \Drupal\search_api\IndexInterface $original
  *   The previous version of the index.
  */
 protected function reactToProcessorChanges(IndexInterface $original)
 {
     $old_processors = $original->getProcessors();
     $new_processors = $this->getProcessors();
     // Only actually do something when the processor settings are changed.
     if ($old_processors != $new_processors) {
         $requires_reindex = FALSE;
         // Loop over all new settings and check if the processors were already set
         // in the original entity.
         foreach ($new_processors as $key => $processor) {
             // The processor is new, because it wasn't configured in the original
             // entity.
             if (!isset($old_processors[$key])) {
                 if ($processor->requiresReindexing(NULL, $processor->getConfiguration())) {
                     $requires_reindex = TRUE;
                     break;
                 }
             }
         }
         if (!$requires_reindex) {
             // Loop over all original settings and check if one of them has been
             // removed or changed.
             foreach ($old_processors as $key => $old_processor) {
                 $new_processor = isset($new_processors[$key]) ? $new_processors[$key] : NULL;
                 $old_config = $old_processor->getConfiguration();
                 $new_config = $new_processor ? $new_processor->getConfiguration() : NULL;
                 if (!$new_processor || $old_config != $new_config) {
                     if ($old_processor->requiresReindexing($old_config, $new_config)) {
                         $requires_reindex = TRUE;
                         break;
                     }
                 }
             }
         }
         if ($requires_reindex) {
             $this->reindex();
         }
     }
 }
コード例 #30
0
 /**
  * Retrieves the necessary type fallbacks for an index.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The index for which to return the type fallbacks.
  *
  * @return string[]
  *   An array containing the IDs of all custom data types that are not
  *   supported by the index's current server, mapped to their fallback types.
  */
 public static function getDataTypeFallbackMapping(IndexInterface $index)
 {
     // Check the static cache first.
     $index_id = $index->id();
     if (empty(static::$dataTypeFallbackMapping[$index_id])) {
         $server = NULL;
         try {
             $server = $index->getServer();
         } catch (SearchApiException $e) {
             // If the server isn't available, just ignore it here and return all
             // types.
         }
         static::$dataTypeFallbackMapping[$index_id] = array();
         /** @var \Drupal\search_api\DataType\DataTypeInterface $data_type */
         foreach (\Drupal::service('plugin.manager.search_api.data_type')->getCustomDataTypes() as $type_id => $data_type) {
             if (!$server || !$server->supportsDataType($type_id)) {
                 static::$dataTypeFallbackMapping[$index_id][$type_id] = $data_type->getFallbackType();
             }
         }
     }
     return static::$dataTypeFallbackMapping[$index_id];
 }