'List all search indexes.', 'examples' => array( 'drush searchapi-list' => dt('List all search indexes.'), 'drush sapi-l' => dt('Alias to list all search indexes.'), ), 'aliases' => array('sapi-l'), ); $items['search-api-enable'] = array( 'description' => 'Enable one or all disabled search_api indexes.', 'examples' => array( 'drush searchapi-enable' => dt('Enable all disabled indexes.'), 'drush sapi-en' => dt('Alias to enable all disabled indexes.'), 'drush sapi-en 1' => dt('Enable index with the ID !id.', array('!id' => 1)), ), 'arguments' => array( 'index_id' => dt('The numeric ID or machine name of an index to enable.'), ), 'aliases' => array('sapi-en'), ); $items['search-api-disable'] = array( 'description' => 'Disable one or all enabled search_api indexes.', 'examples' => array( 'drush searchapi-disable' => dt('Disable all enabled indexes.'), 'drush sapi-dis' => dt('Alias to disable all enabled indexes.'), 'drush sapi-dis 1' => dt('Disable index with the ID !id.', array('!id' => 1)), ), 'arguments' => array( 'index_id' => dt('The numeric ID or machine name of an index to disable.'), ), 'aliases' => array('sapi-dis'), ); $items['search-api-status'] = array( 'description' => 'Show the status of one or all search indexes.', 'examples' => array( 'drush searchapi-status' => dt('Show the status of all search indexes.'), 'drush sapi-s' => dt('Alias to show the status of all search indexes.'), 'drush sapi-s 1' => dt('Show the status of the search index with the ID !id.', array('!id' => 1)), 'drush sapi-s default_node_index' => dt('Show the status of the search index with the machine name !name.', array('!name' => 'default_node_index')), ), 'arguments' => array( 'index_id' => dt('The numeric ID or machine name of an index.'), ), 'aliases' => array('sapi-s'), ); $items['search-api-index'] = array( 'description' => 'Index items for one or all enabled search_api indexes.', 'examples' => array( 'drush searchapi-index' => dt('Index items for all enabled indexes.'), 'drush sapi-i' => dt('Alias to index items for all enabled indexes.'), 'drush sapi-i 1' => dt('Index items for the index with the ID !id.', array('!id' => 1)), 'drush sapi-i default_node_index' => dt('Index items for the index with the machine name !name.', array('!name' => 'default_node_index')), 'drush sapi-i 1 100' => dt("Index a maximum number of !limit items (index's cron batch size items per batch run) for the index with the ID !id.", array('!limit' => 100, '!id' => 1)), 'drush sapi-i 1 100 10' => dt("Index a maximum number of !limit items (!batch_size items per batch run) for the index with the ID !id.", array('!limit' => 100, '!batch_size' => 10, '!id' => 1)), 'drush sapi-i 0 0 100' => dt("Index all items of all indexes with !batch_size items per batch run.", array('!batch_size' => 100)), ), 'arguments' => array( 'index_id' => dt('The numeric ID or machine name of an index. Set to 0 to index all indexes. Defaults to 0 (index all).'), 'limit' => dt("The number of items to index (index's cron batch size items per run). Set to 0 to index all items. Defaults to 0 (index all)."), 'batch_size' => dt("The number of items to index per batch run. Set to 0 to index all items at once. Defaults to the index's cron batch size."), ), 'aliases' => array('sapi-i'), ); $items['search-api-reindex'] = array( 'description' => 'Force reindexing of one or all search indexes, without clearing existing index data.', 'examples' => array( 'drush searchapi-reindex' => dt('Schedule all search indexes for reindexing.'), 'drush sapi-r' => dt('Alias to schedule all search indexes for reindexing .'), 'drush sapi-r 1' => dt('Schedule the search index with the ID !id for re-indexing.', array('!id' => 1)), 'drush sapi-r default_node_index' => dt('Schedule the search index with the machine name !name for re-indexing.', array('!name' => 'default_node_index')), ), 'arguments' => array( 'index_id' => dt('The numeric ID or machine name of an index.'), ), 'aliases' => array('sapi-r'), ); $items['search-api-reindex-items'] = array( 'description' => 'Force re-indexing of one or more specific items.', 'examples' => array( 'drush search-api-reindex-items node 12,34,56' => dt('Schedule the nodes with ID 12, 34 and 56 for re-indexing.'), ), 'arguments' => array( 'entity_type' => dt('The entity type whose items should be re-indexed.'), 'entities' => dt('The entities of the given entity type to be re-indexed.'), ), 'aliases' => array('sapi-ri'), ); $items['search-api-clear'] = array( 'description' => 'Clear one or all search indexes and mark them for re-indexing.', 'examples' => array( 'drush searchapi-clear' => dt('Clear all search indexes.'), 'drush sapi-c' => dt('Alias to clear all search indexes.'), 'drush sapi-c 1' => dt('Clear the search index with the ID !id.', array('!id' => 1)), 'drush sapi-c default_node_index' => dt('Clear the search index with the machine name !name.', array('!name' => 'default_node_index')), ), 'arguments' => array( 'index_id' => dt('The numeric ID or machine name of an index.'), ), 'aliases' => array('sapi-c'), ); $items['search-api-execute-tasks'] = array( 'description' => 'Execute all pending tasks or all for a given server.', 'examples' => array( 'drush search-api-execute-tasks my_solr_server' => dt('Execute all pending tasks on !server', array('!server' => 'my_solr_server')), 'drush sapi-et my_solr_server' => dt('Execute all pending tasks on !server', array('!server' => 'my_solr_server')), 'drush sapi-et' => dt('Execute all pending tasks on all servers.') ), 'arguments' => array( 'server_id' => dt('The numeric ID or machine name of a server to execute tasks on.'), ), 'aliases' => array('sapi-et') ); $items['search-api-set-index-server'] = array( 'description' => 'Set the search server used by a given index.', 'examples' => array( 'drush search-api-set-index-server default_node_index my_solr_server' => dt('Set the !index index to use the !server server.', array('!index' => 'default_node_index', '!server' => 'my_solr_server')), 'drush sapi-sis default_node_index my_solr_server' => dt('Alias to set the !index index to use the !server server.', array('!index' => 'default_node_index', '!server' => 'my_solr_server')), ), 'arguments' => array( 'index_id' => dt('The numeric ID or machine name of an index.'), 'server_id' => dt('The numeric ID or machine name of a server to set on the index.'), ), 'aliases' => array('sapi-sis'), ); $items['search-api-server-list'] = array( 'description' => 'List all search servers.', 'examples' => array( 'drush search-api-server-list' => dt('List all search servers.'), 'drush sapi-sl' => dt('Alias to list all search servers.'), ), 'aliases' => array('sapi-sl'), ); $items['search-api-server-enable'] = array( 'description' => 'Enable a search server.', 'examples' => array( 'drush search-api-server-e my_solr_server' => dt('Enable the !server search server.', array('!server' => 'my_solr_server')), 'drush sapi-se my_solr_server' => dt('Alias to enable the !server search server.', array('!server' => 'my_solr_server')), ), 'arguments' => array( 'server_id' => dt('The numeric ID or machine name of a search server to enable.'), ), 'aliases' => array('sapi-se'), ); $items['search-api-server-disable'] = array( 'description' => 'Disable a search server.', 'examples' => array( 'drush search-api-server-disable' => dt('Disable the !server search server.', array('!server' => 'my_solr_server')), 'drush sapi-sd' => dt('Alias to disable the !server search server.', array('!server' => 'my_solr_server')), ), 'arguments' => array( 'server_id' => dt('The numeric ID or machine name of a search server to disable.'), ), 'aliases' => array('sapi-sd'), ); return $items; } /** * List all search indexes. */ function drush_search_api_list() { if (search_api_drush_static(__FUNCTION__)) { return; } // See search_api_list_indexes() $indexes = search_api_index_load_multiple(FALSE); if (empty($indexes)) { drush_print(dt('There are no indexes present.')); return; } $rows[] = array( dt('Id'), dt('Name'), dt('Index'), dt('Server'), dt('Type'), dt('Status'), dt('Limit'), ); foreach ($indexes as $index) { $type = search_api_get_item_type_info($index->item_type); $type = isset($type['name']) ? $type['name'] : $index->item_type; try { $server = $index->server(); $server = $server ? $server->name : '(' . dt('none') . ')'; } catch (SearchApiException $e) { watchdog_exception('search_api', $e); $server = '(' . dt('unknown: !server', array('server' => $index->server)) . ')'; } $row = array( $index->id, $index->name, $index->machine_name, $server, $type, $index->enabled ? dt('enabled') : dt('disabled'), $index->options['cron_limit'], ); $rows[] = $row; } drush_print_table($rows); } /** * Enable index(es). * * @param string|integer $index_id * The index name or id which should be enabled. */ function drush_search_api_enable($index_id = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } $indexes = search_api_drush_get_index($index_id); if (empty($indexes)) { return; } foreach ($indexes as $index) { $vars = array('!index' => $index->name); if (!$index->enabled) { drush_log(dt("Enabling index !index and queueing items for indexing.", $vars), 'notice'); $success = FALSE; try { if ($success = search_api_index_enable($index->id)) { drush_log(dt("The index !index was successfully enabled.", $vars), 'ok'); } } catch (SearchApiException $e) { drush_log($e->getMessage(), 'error'); } if (!$success) { drush_log(dt("Error enabling index !index.", $vars), 'error'); } } else { drush_log(dt("The index !index is already enabled.", $vars), 'error'); } } } /** * Disable index(es). * * @param string|integer $index_id * The index name or id which should be disabled. */ function drush_search_api_disable($index_id = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } $indexes = search_api_drush_get_index($index_id); if (empty($indexes)) { return; } foreach ($indexes as $index) { $vars = array('!index' => $index->name); if ($index->enabled) { $success = FALSE; try { if ($success = search_api_index_disable($index->id)) { drush_log(dt("The index !index was successfully disabled.", $vars), 'ok'); } } catch (SearchApiException $e) { drush_log($e->getMessage(), 'error'); } if (!$success) { drush_log(dt("Error disabling index !index.", $vars), 'error'); } } else { drush_log(dt("The index !index is already disabled.", $vars), 'error'); } } } /** * Display index status. */ function drush_search_api_status($index_id = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } $indexes = search_api_drush_get_index($index_id); if (empty($indexes)) { return; } // See search_api_index_status() $rows = array(array( dt('Id'), dt('Index'), dt('% Complete'), dt('Indexed'), dt('Total'), )); foreach ($indexes as $index) { $status = search_api_index_status($index); $complete = ($status['total'] > 0) ? 100 * round($status['indexed'] / $status['total'], 3) . '%' : '-'; $row = array( $index->id, $index->name, $complete, $status['indexed'], $status['total'], ); $rows[] = $row; } drush_print_table($rows); } /** * Index items. * * @param string|integer $index_id * The index name or id for which items should be indexed. * @param integer $limit * Maximum number of items to index. * @param integer $batch_size * Number of items to index per batch. */ function drush_search_api_index($index_id = NULL, $limit = NULL, $batch_size = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } $index_id = !empty($index_id) ? $index_id : NULL; $indexes = search_api_drush_get_index($index_id); if (empty($indexes)) { return; } $process_batch = FALSE; foreach ($indexes as $index) { if (_drush_search_api_batch_indexing_create($index, $limit, $batch_size)) { $process_batch = TRUE; } } if ($process_batch) { drush_backend_batch_process(); } } /** * Creates and sets a batch for indexing items for a particular index. * * @param SearchApiIndex $index * The index for which items should be indexed. * @param int $limit * (optional) The maximum number of items to index, or NULL to index all * items. * @param int $batch_size * (optional) The number of items to index per batch, or NULL to index all * items at once. * * @return bool * TRUE if batch was created, FALSE otherwise. */ function _drush_search_api_batch_indexing_create(SearchApiIndex $index, $limit = NULL, $batch_size = NULL) { // Get the number of remaining items to index. try { $datasource = $index->datasource(); } catch (SearchApiException $e) { drush_log($e->getMessage(), 'error'); return FALSE; } $index_status = $datasource->getIndexStatus($index); $remaining = $index_status['total'] - $index_status['indexed']; if ($remaining <= 0) { drush_log(dt("The index !index is up to date.", array('!index' => $index->name)), 'ok'); return FALSE; } // Get the number of items to index per batch run. if (!isset($batch_size)) { $batch_size = empty($index->options['cron_limit']) ? SEARCH_API_DEFAULT_CRON_LIMIT : $index->options['cron_limit']; } elseif ($batch_size <= 0) { $batch_size = $remaining; } // Get the total number of items to index. if (!isset($limit) || !is_int($limit += 0) || $limit <= 0) { $limit = $remaining; } drush_log(dt("Indexing a maximum number of !limit items (!batch_size items per batch run) for the index !index.", array('!index' => $index->name, '!limit' => $limit, '!batch_size' => $batch_size)), 'ok'); // Create the batch. if (!_search_api_batch_indexing_create($index, $batch_size, $limit, $remaining, TRUE)) { drush_log(dt("Couldn't create a batch, please check the batch size and limit parameters."), 'error'); return FALSE; } return TRUE; } /** * Copy of formal_plural that works with drush as 't' may not be available. */ function _search_api_drush_format_plural($count, $singular, $plural, array $args = array(), array $options = array()) { $args['@count'] = $count; if ($count == 1) { return dt($singular, $args, $options); } // Get the plural index through the gettext formula. $index = (function_exists('locale_get_plural')) ? locale_get_plural($count, isset($options['langcode']) ? $options['langcode'] : NULL) : -1; // If the index cannot be computed, use the plural as a fallback (which // allows for most flexiblity with the replaceable @count value). if ($index < 0) { return dt($plural, $args, $options); } else { switch ($index) { case "0": return dt($singular, $args, $options); case "1": return dt($plural, $args, $options); default: unset($args['@count']); $args['@count[' . $index . ']'] = $count; return dt(strtr($plural, array('@count' => '@count[' . $index . ']')), $args, $options); } } } /** * Mark for re-indexing. */ function drush_search_api_reindex($index_id = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } $indexes = search_api_drush_get_index($index_id); if (empty($indexes)) { return; } // See search_api_index_reindex() foreach ($indexes as $index) { $index->reindex(); drush_log(dt('!index was successfully marked for re-indexing.', array('!index' => $index->machine_name)), 'ok'); } } /** * Marks the given entities as needing to be re-indexed. */ function drush_search_api_reindex_items($entity_type, $entities) { if (search_api_drush_static(__FUNCTION__)) { return; } // Validate list of entity ids. if (!empty($entities) && !preg_match('#^[0-9]*(,[0-9]*)*$#', $entities)) { drush_log(dt('Entities should be a single numeric entity ID or a list with the numeric entity IDs separated by comma.'), 'error'); return; } $ids = explode(',', $entities); if (!empty($ids)) { search_api_track_item_change($entity_type, $ids); $combined_ids = array(); foreach ($ids as $id) { $combined_ids[] = $entity_type . '/' . $id; } search_api_track_item_change('multiple', $combined_ids); } } /** * Clear an index. */ function drush_search_api_clear($index_id = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } $indexes = search_api_drush_get_index($index_id); if (empty($indexes)) { return; } // See search_api_index_reindex() foreach ($indexes as $index) { $index->clear(); drush_log(dt('!index was successfully cleared.', array('!index' => $index->machine_name)), 'ok'); } } /** * Execute all pending tasks or all for a given server. */ function drush_search_api_execute_tasks($server_id = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } // Attempt to load the associated server. $server = NULL; if ($server_id) { $servers = search_api_drush_get_server($server_id); if (!$servers) { return; } $server = reset($servers); } // Process batch op with drush. try { search_api_execute_pending_tasks($server); drush_log(dt('!server tasks have been successfully executed.', array('!server' => $server->machine_name ? $server->machine_name : 'All')), 'ok'); } catch (SearchApiException $e) { drush_log($e->getMessage(), 'error'); } } /** * Set the server for a given index. */ function drush_search_api_set_index_server($index_id = NULL, $server_id = NULL) { if (search_api_drush_static(__FUNCTION__)) { return; } // Make sure we have parameters to work with. if (empty($index_id) || empty($server_id)) { drush_log(dt('You must specify both an index and server.'), 'error'); return; } // Fetch current index and server data. $indexes = search_api_drush_get_index($index_id); $servers = search_api_drush_get_server($server_id); if (empty($indexes) || empty($servers)) { // If the specified index or server can't be found, just return. An // appropriate error message should have been printed already. return; } // Set the new server on the index. $success = FALSE; $index = reset($indexes); $server = reset($servers); try { $success = $index->update(array('server' => $server->machine_name)); } catch (SearchApiException $e) { drush_log($e->getMessage(), 'error'); } if ($success === FALSE) { drush_log(dt('There was an error setting index !index to use server !server.', array('!index' => $index->name, '!server' => $server->name)), 'error'); } elseif (!$success) { drush_log(dt('Index !index was already using server !server.', array('!index' => $index->name, '!server' => $server->name)), 'ok'); } else { drush_log(dt('Index !index has been set to use server !server and items have been queued for indexing.', array('!index' => $index->name, '!server' => $server->name)), 'ok'); } } /** * Returns an index or all indexes as an array. * * @param string|int|null $index_id * (optional) The ID or machine name of the index to load. Defaults to * loading all available indexes. * * @return SearchApiIndex[] * An array of indexes. */ function search_api_drush_get_index($index_id = NULL) { $ids = isset($index_id) ? array($index_id) : FALSE; $indexes = search_api_index_load_multiple($ids); if (empty($indexes)) { drush_set_error(dt('Invalid index_id or no indexes present. Listing all indexes:')); drush_print(); drush_search_api_list(); } return $indexes; } /** * Returns a server or all servers as an array. * * @param string|int|null $server_id * (optional) The ID or machine name of the server to load. Defaults to * loading all available servers. * * @return SearchApiServer[] * An array of servers. */ function search_api_drush_get_server($server_id = NULL) { $ids = isset($server_id) ? array($server_id) : FALSE; $servers = search_api_server_load_multiple($ids); if (empty($servers)) { drush_set_error(dt('Invalid server_id or no servers present.')); drush_print(); drush_search_api_server_list(); } return $servers; } /** * Does a static lookup to prevent Drush 4 from running twice. * * @param string $function * The Drush function being called. * * @return bool * TRUE if the function was already called in this Drush execution, FALSE * otherwise. * * @see http://drupal.org/node/704848 */ function search_api_drush_static($function) { static $index = array(); if (isset($index[$function])) { return TRUE; } $index[$function] = TRUE; return FALSE; } /** * Lists all search servers. */ function drush_search_api_server_list() { if (search_api_drush_static(__FUNCTION__)) { return; } $servers = search_api_server_load_multiple(FALSE); if (empty($servers)) { drush_print(dt('There are no servers present.')); return; } $rows[] = array( dt('Machine name'), dt('Name'), dt('Status'), ); foreach ($servers as $server) { $row = array( $server->machine_name, $server->name, $server->enabled ? dt('enabled') : dt('disabled'), ); $rows[] = $row; } drush_print_table($rows); } /** * Enables a search server. * * @param int|string $server_id * The numeric ID or machine name of the server to enable. */ function drush_search_api_server_enable($server_id = NULL) { if (!isset($server_id)) { drush_print(dt('Please provide a valid server id.')); return; } $server = search_api_server_load($server_id); if (empty($server)) { drush_print(dt('The server was not able to load.')); return; } else { $server->update(array('enabled' => 1)); drush_print(dt('The server was enabled successfully.')); } } /** * Disables a search server. * * @param int|string $server_id * The numeric ID or machine name of the server to disable. */ function drush_search_api_server_disable($server_id = NULL) { if (!isset($server_id)) { drush_print(dt('Please provide a valid server id.')); return; } $server = search_api_server_load($server_id); if (empty($server)) { drush_print(dt('The server was not able to load.')); return; } else { $server->update(array('enabled' => 0)); drush_print(dt('The server was disabled successfully.')); } }