コード例 #1
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;
 }
コード例 #2
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.');
 }
コード例 #3
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);
 }
コード例 #4
0
 /**
  * Builds the form fields for a set of fields.
  *
  * @param \Drupal\search_api\Item\FieldInterface[] $fields
  *   List of fields to display.
  *
  * @return array
  *   The build structure.
  */
 protected function buildFieldsTable(array $fields)
 {
     $data_type_plugin_manager = $this->getDataTypePluginManager();
     $types = $data_type_plugin_manager->getInstancesOptions();
     $fulltext_types = array('text');
     // Add all data types with fallback "text" to fulltext types as well.
     foreach ($data_type_plugin_manager->getInstances() as $id => $type) {
         if ($type->getFallbackType() == 'text') {
             $fulltext_types[] = $id;
         }
     }
     $boost_values = array('0.1', '0.2', '0.3', '0.5', '0.8', '1.0', '2.0', '3.0', '5.0', '8.0', '13.0', '21.0');
     $boosts = array_combine($boost_values, $boost_values);
     $build = array('#type' => 'details', '#open' => TRUE, '#theme' => 'search_api_admin_fields_table', '#parents' => array());
     foreach ($fields as $key => $field) {
         $build['fields'][$key]['#access'] = !$field->isHidden();
         $build['fields'][$key]['title']['#plain_text'] = $field->getLabel();
         $build['fields'][$key]['id']['#plain_text'] = $key;
         if ($field->getDescription()) {
             $build['fields'][$key]['description'] = array('#type' => 'value', '#value' => $field->getDescription());
         }
         $css_key = '#edit-fields-' . Html::getId($key);
         $build['fields'][$key]['type'] = array('#type' => 'select', '#options' => $types, '#default_value' => $field->getType());
         if ($field->isTypeLocked()) {
             $build['fields'][$key]['type']['#disabled'] = TRUE;
         }
         $build['fields'][$key]['boost'] = array('#type' => 'select', '#options' => $boosts, '#default_value' => sprintf('%.1f', $field->getBoost()));
         foreach ($fulltext_types as $type) {
             $build['fields'][$key]['boost']['#states']['visible'][$css_key . '-type'][] = array('value' => $type);
         }
         $build['fields'][$key]['remove']['#markup'] = '';
         if (!$field->isIndexedLocked()) {
             $route_parameters = array('search_api_index' => $this->entity->id(), 'field_id' => $key);
             $build['fields'][$key]['remove'] = array('#type' => 'link', '#title' => $this->t('Remove'), '#url' => Url::fromRoute('entity.search_api_index.remove_field', $route_parameters));
         }
     }
     return $build;
 }
コード例 #5
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;
 }
コード例 #6
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.');
 }
コード例 #7
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];
 }
コード例 #8
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);
 }
コード例 #9
0
ファイル: Database.php プロジェクト: jkyto/agolf
 /**
  * Retrieve the database info for the given index, or some data from it.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The search index.
  *
  * @return array|string
  *   The requested data from the key-value store.
  */
 protected function getIndexDbInfo(IndexInterface $index) {
   return $this->getKeyValueStore()->get($index->id(), array());
 }
コード例 #10
0
 /**
  * Reloads the index with the latest copy from storage.
  */
 protected function reloadIndex()
 {
     $storage = \Drupal::entityTypeManager()->getStorage('search_api_index');
     $storage->resetCache();
     $this->index = $storage->load($this->index->id());
 }
コード例 #11
0
 /**
  * Retrieves the key of the index's state.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The index.
  *
  * @return string
  *   The key which identifies the index's state in the site state.
  */
 protected function getIndexStateKey(IndexInterface $index)
 {
     return 'search_api.index.' . $index->id() . '.tasks';
 }
コード例 #12
0
 /**
  * {@inheritdoc}
  */
 public function save()
 {
     return $this->tempStore->setIfOwner($this->entity->id(), $this->entity);
 }
コード例 #13
0
ファイル: Database.php プロジェクト: nB-MDSO/mdso-d8blog
 /**
  * Retrieves the database info for the given index.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The search index.
  *
  * @return array
  *   The index data from the key-value store.
  */
 protected function getIndexDbInfo(IndexInterface $index)
 {
     $db_info = $this->getKeyValueStore()->get($index->id(), array());
     if ($db_info['server'] != $this->server->id()) {
         return array();
     }
     return $db_info;
 }
コード例 #14
0
ファイル: search_api.api.php プロジェクト: jkyto/agolf
/**
 * React when a search index was scheduled for reindexing
 *
 * @param \Drupal\search_api\IndexInterface $index
 *   The index scheduled for reindexing.
 * @param $clear
 *   Boolean indicating whether the index was also cleared.
 */
function hook_search_api_index_reindex(\Drupal\search_api\IndexInterface $index, $clear = FALSE) {
  \Drupal\Core\Database\Database::getConnection()->insert('example_search_index_reindexed')
    ->fields(array(
      'index' => $index->id(),
      'clear' => $clear,
      'update_time' => REQUEST_TIME,
    ))
    ->execute();
}
コード例 #15
0
 /**
  * Creates a list of all indexed field names mapped to their Solr field names.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The Search Api index.
  * @param bool $single_value_name
  *   (optional) Whether to return names for fields which store only the first
  *   value of the field. Defaults to FALSE.
  * @param bool $reset
  *   (optional) Whether to reset the static cache.
  *
  * The special fields "search_api_id" and "search_api_relevance" are also
  * included. Any Solr fields that exist on search results are mapped back to
  * to their local field names in the final result set.
  *
  * @see SearchApiSolrBackend::search()
  */
 public function getFieldNames(IndexInterface $index, $single_value_name = FALSE, $reset = FALSE)
 {
     // @todo The field name mapping should be cached per index because custom
     // queries needs to access it on every query.
     $subkey = (int) $single_value_name;
     if (!isset($this->fieldNames[$index->id()][$subkey]) || $reset) {
         // This array maps "local property name" => "solr doc property name".
         $ret = array('search_api_id' => 'item_id', 'search_api_relevance' => 'score');
         // Add the names of any fields configured on the index.
         $fields = $index->getFields();
         foreach ($fields as $key => $field) {
             // Generate a field name; this corresponds with naming conventions in
             // our schema.xml
             $type = $field->getType();
             $type_info = SearchApiSolrUtility::getDataTypeInfo($type);
             $pref = isset($type_info['prefix']) ? $type_info['prefix'] : '';
             $pref .= $single_value_name ? 's' : 'm';
             $name = $pref . '_' . $key;
             $ret[$key] = SearchApiSolrUtility::encodeSolrDynamicFieldName($name);
         }
         // Let modules adjust the field mappings.
         $hook_name = $single_value_name ? 'search_api_solr_single_value_field_mapping' : 'search_api_solr_field_mapping';
         $this->moduleHandler->alter($hook_name, $index, $ret);
         $this->fieldNames[$index->id()][$subkey] = $ret;
     }
     return $this->fieldNames[$index->id()][$subkey];
 }
コード例 #16
0
ファイル: Utility.php プロジェクト: curveagency/intranet
 /**
  * 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->getServerInstance();
         } catch (SearchApiException $e) {
             // If the server isn't available, just ignore it here and return all
             // custom types.
         }
         static::$dataTypeFallbackMapping[$index_id] = array();
         /** @var \Drupal\search_api\DataType\DataTypeInterface $data_type */
         foreach (\Drupal::service('plugin.manager.search_api.data_type')->getInstances() as $type_id => $data_type) {
             // We know for sure that we do not need to fall back for the default
             // data types as they are always present and are required to be
             // supported by all backends.
             if (!$data_type->isDefault() && (!$server || !$server->supportsDataType($type_id))) {
                 static::$dataTypeFallbackMapping[$index_id][$type_id] = $data_type->getFallbackType();
             }
         }
     }
     return static::$dataTypeFallbackMapping[$index_id];
 }
コード例 #17
0
 /**
  * Builds the form for the basic index properties.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The index that is being created or edited.
  */
 public function buildEntityForm(array &$form, FormStateInterface $form_state, IndexInterface $index)
 {
     $form['#tree'] = TRUE;
     $form['name'] = array('#type' => 'textfield', '#title' => $this->t('Index name'), '#description' => $this->t('Enter the displayed name for the index.'), '#default_value' => $index->label(), '#required' => TRUE);
     $form['id'] = array('#type' => 'machine_name', '#default_value' => $index->id(), '#maxlength' => 50, '#required' => TRUE, '#machine_name' => array('exists' => array($this->getIndexStorage(), 'load'), 'source' => array('name')));
     // If the user changed the datasources or the tracker, notify them that they
     // need to be configured.
     // @todo Only do that if the datasources/tracker have configuration forms.
     //   (Same in \Drupal\search_api\Form\ServerForm.)
     $values = $form_state->getValues();
     if (!empty($values['datasources'])) {
         drupal_set_message($this->t('Please configure the used datasources.'), 'warning');
     }
     if (!empty($values['tracker'])) {
         drupal_set_message($this->t('Please configure the used tracker.'), 'warning');
     }
     $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';
     $datasource_options = array();
     foreach ($this->getDatasourcePluginManager()->getDefinitions() as $datasource_id => $definition) {
         $datasource_options[$datasource_id] = !empty($definition['label']) ? $definition['label'] : $datasource_id;
     }
     $form['datasources'] = array('#type' => 'select', '#title' => $this->t('Data sources'), '#description' => $this->t('Select one or more data sources of items that will be stored in this index.'), '#options' => $datasource_options, '#default_value' => $index->getDatasourceIds(), '#multiple' => TRUE, '#required' => TRUE, '#ajax' => array('trigger_as' => array('name' => 'datasourcepluginids_configure'), 'callback' => '::buildAjaxDatasourceConfigForm', 'wrapper' => 'search-api-datasources-config-form', 'method' => 'replace', 'effect' => 'fade'));
     $form['datasource_configs'] = array('#type' => 'container', '#attributes' => array('id' => 'search-api-datasources-config-form'), '#tree' => TRUE);
     $form['datasource_configure_button'] = array('#type' => 'submit', '#name' => 'datasourcepluginids_configure', '#value' => $this->t('Configure'), '#limit_validation_errors' => array(array('datasources')), '#submit' => array('::submitAjaxDatasourceConfigForm'), '#ajax' => array('callback' => '::buildAjaxDatasourceConfigForm', 'wrapper' => 'search-api-datasources-config-form'), '#attributes' => array('class' => array('js-hide')));
     $this->buildDatasourcesConfigForm($form, $form_state, $index);
     $tracker_options = $this->getTrackerPluginManager()->getOptionsList();
     $form['tracker'] = array('#type' => 'radios', '#title' => $this->t('Tracker'), '#description' => $this->t('Select the type of tracker which should be used for keeping track of item changes.'), '#options' => $this->getTrackerPluginManager()->getOptionsList(), '#default_value' => $index->hasValidTracker() ? $index->getTracker()->getPluginId() : key($tracker_options), '#required' => TRUE, '#disabled' => !$index->isNew(), '#ajax' => array('trigger_as' => array('name' => 'trackerpluginid_configure'), 'callback' => '::buildAjaxTrackerConfigForm', 'wrapper' => 'search-api-tracker-config-form', 'method' => 'replace', 'effect' => 'fade'), '#access' => count($tracker_options) > 1);
     $form['tracker_config'] = array('#type' => 'container', '#attributes' => array('id' => 'search-api-tracker-config-form'), '#tree' => TRUE);
     $form['tracker_configure_button'] = array('#type' => 'submit', '#name' => 'trackerpluginid_configure', '#value' => $this->t('Configure'), '#limit_validation_errors' => array(array('tracker')), '#submit' => array('::submitAjaxTrackerConfigForm'), '#ajax' => array('callback' => '::buildAjaxTrackerConfigForm', 'wrapper' => 'search-api-tracker-config-form'), '#attributes' => array('class' => array('js-hide')), '#access' => count($tracker_options) > 1);
     $this->buildTrackerConfigForm($form, $form_state, $index);
     $form['server'] = array('#type' => 'radios', '#title' => $this->t('Server'), '#description' => $this->t('Select the server this index should use. Indexes cannot be enabled without a connection to a valid, enabled server.'), '#options' => array(NULL => '<em>' . $this->t('- No server -') . '</em>') + $this->getServerOptions(), '#default_value' => $index->hasValidServer() ? $index->getServerId() : NULL);
     $form['status'] = array('#type' => 'checkbox', '#title' => $this->t('Enabled'), '#description' => $this->t('Only enabled indexes can be used for indexing and searching. This setting will only take effect if the selected server is also enabled.'), '#default_value' => $index->status(), '#disabled' => !$index->status() && (!$index->hasValidServer() || !$index->getServer()->status()), '#states' => array('invisible' => array(':input[name="server"]' => array('value' => ''))));
     $form['description'] = array('#type' => 'textarea', '#title' => $this->t('Description'), '#description' => $this->t('Enter a description for the index.'), '#default_value' => $index->getDescription());
     $form['options'] = array('#tree' => TRUE, '#type' => 'details', '#title' => $this->t('Index options'), '#collapsed' => TRUE);
     // We display the "read-only" flag along with the other options, even though
     // it is a property directly on the index object. We use "#parents" to move
     // it to the correct place in the form values.
     $form['options']['read_only'] = array('#type' => 'checkbox', '#title' => $this->t('Read only'), '#description' => $this->t('Do not write to this index or track the status of items in this index.'), '#default_value' => $index->isReadOnly(), '#parents' => array('read_only'));
     $form['options']['index_directly'] = array('#type' => 'checkbox', '#title' => $this->t('Index items immediately'), '#description' => $this->t('Immediately index new or updated items instead of waiting for the next cron run. This might have serious performance drawbacks and is generally not advised for larger sites.'), '#default_value' => $index->getOption('index_directly'));
     $form['options']['cron_limit'] = array('#type' => 'textfield', '#title' => $this->t('Cron batch size'), '#description' => $this->t('Set how many items will be indexed at once when indexing items during a cron run. "0" means that no items will be indexed by cron for this index, "-1" means that cron should index all items at once.'), '#default_value' => $index->getOption('cron_limit'), '#size' => 4);
 }
コード例 #18
0
 /**
  * Retrieves the internal field information.
  *
  * @param \Drupal\search_api\IndexInterface $index
  *   The index whose fields should be retrieved.
  *
  * @return array[]
  *   An array of arrays. The outer array is keyed by field name. Each value
  *   is an associative array with information on the field.
  */
 protected function getFieldInfo(IndexInterface $index)
 {
     return $this->configuration['field_tables'][$index->id()];
 }