diff --git a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php index bba66e0..e235d7a 100644 --- a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php +++ b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php @@ -22,7 +22,7 @@ * label = @Translation("Search page"), * controllers = { * "access" = "Drupal\search\SearchPageAccessController", - * "storage" = "Drupal\search\SearchPageStorage", + * "storage" = "Drupal\Core\Config\Entity\ConfigStorageController", * "list" = "Drupal\search\SearchPageListController", * "form" = { * "add" = "Drupal\search\Form\SearchPageAddForm", @@ -118,7 +118,7 @@ class SearchPage extends ConfigEntityBase implements SearchPageInterface { public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); - $this->pluginBag = new SearchPluginBag(\Drupal::service('plugin.manager.search'), array($this->plugin), $this->configuration); + $this->pluginBag = new SearchPluginBag($this->searchPluginManager(), array($this->plugin), $this->configuration); } /** @@ -147,7 +147,7 @@ public function isIndexable() { * {@inheritdoc} */ public function isDefaultSearch() { - return \Drupal::config('search.settings')->get('default_page') == $this->id(); + return $this->configFactory()->get('search.settings')->get('default_page') == $this->id(); } /** @@ -221,7 +221,7 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) { parent::postSave($storage_controller, $update); - \Drupal::state()->set('menu_rebuild_needed', TRUE); + $this->state()->set('menu_rebuild_needed', TRUE); } /** @@ -230,9 +230,9 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $ public static function postDelete(EntityStorageControllerInterface $storage_controller, array $entities) { parent::postDelete($storage_controller, $entities); - /** @var $storage_controller \Drupal\search\SearchPageStorageInterface */ - if (!$storage_controller->isSearchActive()) { - \Drupal::config('search.settings')->clear('default_page')->save(); + $search_page_repository = static::searchPageRepository(); + if (!$search_page_repository->isSearchActive()) { + $search_page_repository->clearDefaultSearchPage(); } } @@ -250,4 +250,40 @@ public static function sort($a, $b) { return parent::sort($a, $b); } + /** + * Wraps the state storage. + * + * @return \Drupal\Core\KeyValueStore\StateInterface + */ + protected function state() { + return \Drupal::state(); + } + + /** + * Wraps the config factory. + * + * @return \Drupal\Core\Config\ConfigFactory + */ + protected function configFactory() { + return \Drupal::service('config.factory'); + } + + /** + * Wraps the search page repository. + * + * @return \Drupal\search\SearchPageRepositoryInterface + */ + protected static function searchPageRepository() { + return \Drupal::service('search.search_page_repository'); + } + + /** + * Wraps the search plugin manager. + * + * @return \Drupal\Component\Plugin\PluginManagerInterface + */ + protected function searchPluginManager() { + return \Drupal::service('plugin.manager.search'); + } + } diff --git a/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php b/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php index 5cbe59f..ad96735 100644 --- a/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php +++ b/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php @@ -8,7 +8,7 @@ namespace Drupal\search\Form; use Drupal\Core\Form\FormBase; -use Drupal\search\SearchPageStorageInterface; +use Drupal\search\SearchPageRepositoryInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -17,20 +17,20 @@ class SearchBlockForm extends FormBase { /** - * The search storage. + * The search page repository. * - * @var \Drupal\search\SearchPageStorageInterface + * @var \Drupal\search\SearchPageRepositoryInterface */ - protected $searchStorage; + protected $searchPageRepository; /** - * Constructs a new search controller. + * Constructs a new SearchBlockForm. * - * @param \Drupal\search\SearchPageStorageInterface $search_storage - * The search storage. + * @param \Drupal\search\SearchPageRepositoryInterface $search_page_repository + * The search page repository. */ - public function __construct(SearchPageStorageInterface $search_storage) { - $this->searchStorage = $search_storage; + public function __construct(SearchPageRepositoryInterface $search_page_repository) { + $this->searchPageRepository = $search_page_repository; } /** @@ -38,7 +38,7 @@ public function __construct(SearchPageStorageInterface $search_storage) { */ public static function create(ContainerInterface $container) { return new static( - $container->get('entity.manager')->getStorageController('search_page') + $container->get('search.search_page_repository') ); } @@ -90,7 +90,7 @@ public function submitForm(array &$form, array &$form_state) { } $form_id = $form['form_id']['#value']; - if ($entity_id = $this->searchStorage->getDefaultSearchPage()) { + if ($entity_id = $this->searchPageRepository->getDefaultSearchPage()) { $form_state['redirect_route'] = array( 'route_name' => 'search.view_' . $entity_id, 'route_parameters' => array( diff --git a/core/modules/search/lib/Drupal/search/Plugin/Derivative/SearchLocalTask.php b/core/modules/search/lib/Drupal/search/Plugin/Derivative/SearchLocalTask.php index ea1f50f..2bf5e17 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/Derivative/SearchLocalTask.php +++ b/core/modules/search/lib/Drupal/search/Plugin/Derivative/SearchLocalTask.php @@ -8,9 +8,8 @@ namespace Drupal\search\Plugin\Derivative; use Drupal\Component\Plugin\Derivative\DerivativeBase; -use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface; -use Drupal\search\SearchPageStorageInterface; +use Drupal\search\SearchPageRepositoryInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -19,30 +18,20 @@ class SearchLocalTask extends DerivativeBase implements ContainerDerivativeInterface { /** - * The search storage. + * The search page repository. * - * @var \Drupal\search\SearchPageStorageInterface + * @var \Drupal\search\SearchPageRepositoryInterface */ - protected $searchStorage; - - /** - * The search settings. - * - * @var \Drupal\Core\Config\Config - */ - protected $searchSettings; + protected $searchPageRepository; /** * Constructs a new SearchLocalTask. * - * @param \Drupal\search\SearchPageStorageInterface $search_storage - * The search storage. - * @param \Drupal\Core\Config\ConfigFactory $config_factory - * The config factory. + * @param \Drupal\search\SearchPageRepositoryInterface $search_page_repository + * The search page repository. */ - public function __construct(SearchPageStorageInterface $search_storage, ConfigFactory $config_factory) { - $this->searchStorage = $search_storage; - $this->searchSettings = $config_factory->get('search.settings'); + public function __construct(SearchPageRepositoryInterface $search_page_repository) { + $this->searchPageRepository = $search_page_repository; } /** @@ -50,8 +39,7 @@ public function __construct(SearchPageStorageInterface $search_storage, ConfigFa */ public static function create(ContainerInterface $container, $base_plugin_id) { return new static( - $container->get('entity.manager')->getStorageController('search_page'), - $container->get('config.factory') + $container->get('search.search_page_repository') ); } @@ -61,8 +49,8 @@ public static function create(ContainerInterface $container, $base_plugin_id) { public function getDerivativeDefinitions(array $base_plugin_definition) { $this->derivatives = array(); - if ($default = $this->searchSettings->get('default_page')) { - foreach ($this->searchStorage->getActiveSearchPages() as $entity_id => $entity) { + if ($default = $this->searchPageRepository->getDefaultSearchPage()) { + foreach ($this->searchPageRepository->getActiveSearchPages() as $entity_id => $entity) { $this->derivatives[$entity_id] = array( 'title' => $entity->getTitle(), 'route_name' => 'search.view_' . $entity_id, diff --git a/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php b/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php index fa8d439..8678628 100644 --- a/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php +++ b/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php @@ -7,8 +7,8 @@ namespace Drupal\search\Routing; -use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Routing\RouteSubscriberBase; +use Drupal\search\SearchPageRepositoryInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -18,30 +18,29 @@ class SearchRouteSubscriber extends RouteSubscriberBase { /** - * The search storage. + * The search page repository. * - * @var \Drupal\search\SearchPageStorageInterface + * @var \Drupal\search\SearchPageRepositoryInterface */ - protected $searchStorage; + protected $searchPageRepository; /** * Constructs a new search route subscriber. * - * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The entity manager. + * @param \Drupal\search\SearchPageRepositoryInterface $search_page_repository + * The search page repository. */ - public function __construct(EntityManagerInterface $entity_manager) { - $this->searchStorage = $entity_manager->getStorageController('search_page'); + public function __construct(SearchPageRepositoryInterface $search_page_repository) { + $this->searchPageRepository = $search_page_repository; } /** * {@inheritdoc} */ protected function routes(RouteCollection $collection) { - $active_pages = $this->searchStorage->getActiveSearchPages(); // @todo Decide if /search should continue to redirect to /search/$default, // or just perform the appropriate search. - if ($default_page = $this->searchStorage->getDefaultSearchPage()) { + if ($default_page = $this->searchPageRepository->getDefaultSearchPage()) { $defaults = array( '_content' => 'Drupal\search\Controller\SearchController::redirectSearchPage', '_title' => 'Search', @@ -61,6 +60,8 @@ protected function routes(RouteCollection $collection) { $route = new Route('/search', $defaults, $requirements, $options); $collection->add('search.view', $route); } + + $active_pages = $this->searchPageRepository->getActiveSearchPages(); foreach ($active_pages as $entity_id => $entity) { $path = '/search/' . $entity->getPath() . '/{keys}'; $defaults = array( diff --git a/core/modules/search/lib/Drupal/search/SearchPageListController.php b/core/modules/search/lib/Drupal/search/SearchPageListController.php index 9593519..a4dc655 100644 --- a/core/modules/search/lib/Drupal/search/SearchPageListController.php +++ b/core/modules/search/lib/Drupal/search/SearchPageListController.php @@ -25,13 +25,6 @@ class SearchPageListController extends DraggableListController implements FormInterface { /** - * The entity storage controller class. - * - * @var \Drupal\search\SearchPageStorageInterface - */ - protected $storage; - - /** * The entities being listed. * * @var \Drupal\search\SearchPageInterface[] diff --git a/core/modules/search/lib/Drupal/search/SearchPageRepository.php b/core/modules/search/lib/Drupal/search/SearchPageRepository.php new file mode 100644 index 0000000..32b1cdd --- /dev/null +++ b/core/modules/search/lib/Drupal/search/SearchPageRepository.php @@ -0,0 +1,110 @@ +configFactory = $config_factory; + $this->storage = $entity_manager->getStorageController('search_page'); + } + + /** + * {@inheritdoc} + */ + public function getActiveSearchPages() { + $ids = $this->getQuery() + ->condition('status', TRUE) + ->execute(); + return $this->storage->loadMultiple($ids); + } + + /** + * {@inheritdoc} + */ + public function isSearchActive() { + return (bool) $this->getQuery() + ->condition('status', TRUE) + ->range(0, 1) + ->execute(); + } + + /** + * {@inheritdoc} + */ + public function getIndexableSearchPages() { + return array_filter($this->getActiveSearchPages(), function (SearchPageInterface $search) { + return $search->isIndexable(); + }); + } + + /** + * {@inheritdoc} + */ + public function getDefaultSearchPage() { + // Find all active search pages (without loading them). + $search_pages = $this->getQuery() + ->condition('status', TRUE) + ->execute(); + + // If the default page is active, return it. + $default = $this->configFactory->get('search.settings')->get('default_page'); + if (isset($search_pages[$default])) { + return $default; + } + + // Otherwise, use the first active search page. + return reset($search_pages); + } + + /** + * {@inheritdoc} + */ + public function clearDefaultSearchPage() { + $this->configFactory->get('search.settings')->clear('default_page')->save(); + } + + /** + * Returns an entity query instance. + * + * @return \Drupal\Core\Entity\Query\QueryInterface + * The query instance. + */ + protected function getQuery() { + return $this->storage->getQuery(); + } + +} diff --git a/core/modules/search/lib/Drupal/search/SearchPageStorageInterface.php b/core/modules/search/lib/Drupal/search/SearchPageRepositoryInterface.php similarity index 71% rename from core/modules/search/lib/Drupal/search/SearchPageStorageInterface.php rename to core/modules/search/lib/Drupal/search/SearchPageRepositoryInterface.php index b87b0c0..697d797 100644 --- a/core/modules/search/lib/Drupal/search/SearchPageStorageInterface.php +++ b/core/modules/search/lib/Drupal/search/SearchPageRepositoryInterface.php @@ -2,17 +2,15 @@ /** * @file - * Contains \Drupal\search\SearchPageStorageInterface; + * Contains \Drupal\search\SearchPageRepositoryInterface; */ namespace Drupal\search; -use Drupal\Core\Entity\EntityStorageControllerInterface; - /** * Provides the interface for a storage class for Search pages. */ -interface SearchPageStorageInterface extends EntityStorageControllerInterface { +interface SearchPageRepositoryInterface { /** * Returns all active search entities. @@ -47,13 +45,8 @@ public function getIndexableSearchPages(); public function getDefaultSearchPage(); /** - * Loads a single search page. - * - * @param string $id - * The entity ID. - * - * @return \Drupal\search\SearchPageInterface|null + * Clears the default search page. */ - public function load($id); + public function clearDefaultSearchPage(); } diff --git a/core/modules/search/lib/Drupal/search/SearchPageStorage.php b/core/modules/search/lib/Drupal/search/SearchPageStorage.php deleted file mode 100644 index 929035f..0000000 --- a/core/modules/search/lib/Drupal/search/SearchPageStorage.php +++ /dev/null @@ -1,65 +0,0 @@ -getQuery() - ->condition('status', TRUE) - ->execute(); - return $this->loadMultiple($ids); - } - - /** - * {@inheritdoc} - */ - public function isSearchActive() { - return (bool) $this->getQuery() - ->condition('status', TRUE) - ->range(0, 1) - ->execute(); - } - - /** - * {@inheritdoc} - */ - public function getIndexableSearchPages() { - return array_filter($this->getActiveSearchPages(), function (SearchPageInterface $search) { - return $search->isIndexable(); - }); - } - - /** - * {@inheritdoc} - */ - public function getDefaultSearchPage() { - // Find all active search pages (without loading them). - $search_pages = $this->getQuery() - ->condition('status', TRUE) - ->execute(); - - // If the default page is active, return it. - $default = $this->configFactory->get('search.settings')->get('default_page'); - if (isset($search_pages[$default])) { - return $default; - } - - // Otherwise, use the first active search page. - return reset($search_pages); - } - -} diff --git a/core/modules/search/search.module b/core/modules/search/search.module index 49eecb2..3266bd8 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -185,9 +185,9 @@ function search_menu() { */ function search_reindex($sid = NULL, $type = NULL, $reindex = FALSE, $langcode = NULL) { if ($type == NULL && $sid == NULL) { - /** @var $search_storage \Drupal\search\SearchPageStorageInterface */ - $search_storage = \Drupal::entityManager()->getStorageController('search_page'); - foreach ($search_storage->getIndexableSearchPages() as $entity) { + /** @var $search_page_repository \Drupal\search\SearchPageRepositoryInterface */ + $search_page_repository = \Drupal::service('search.search_page_repository'); + foreach ($search_page_repository->getIndexableSearchPages() as $entity) { $entity->getPlugin()->resetIndex(); } } @@ -238,9 +238,9 @@ function search_cron() { // to date. drupal_register_shutdown_function('search_update_totals'); - /** @var $search_storage \Drupal\search\SearchPageStorageInterface */ - $search_storage = \Drupal::entityManager()->getStorageController('search_page'); - foreach ($search_storage->getIndexableSearchPages() as $entity) { + /** @var $search_page_repository \Drupal\search\SearchPageRepositoryInterface */ + $search_page_repository = \Drupal::service('search.search_page_repository'); + foreach ($search_page_repository->getIndexableSearchPages() as $entity) { $entity->getPlugin()->updateIndex(); } } diff --git a/core/modules/search/search.services.yml b/core/modules/search/search.services.yml index 524d528..3fc8472 100644 --- a/core/modules/search/search.services.yml +++ b/core/modules/search/search.services.yml @@ -5,6 +5,10 @@ services: route_subscriber.search: class: Drupal\search\Routing\SearchRouteSubscriber - arguments: ['@entity.manager'] + arguments: ['@search.search_page_repository'] tags: - { name: event_subscriber } + + search.search_page_repository: + class: Drupal\search\SearchPageRepository + arguments: ['@config.factory', '@entity.manager'] diff --git a/core/modules/search/tests/Drupal/search/Tests/SearchPageRepositoryTest.php b/core/modules/search/tests/Drupal/search/Tests/SearchPageRepositoryTest.php new file mode 100644 index 0000000..51307a8 --- /dev/null +++ b/core/modules/search/tests/Drupal/search/Tests/SearchPageRepositoryTest.php @@ -0,0 +1,232 @@ + 'Search page repository test', + 'description' => 'Tests methods on the \Drupal\search\SearchPageRepository class', + 'group' => 'Search', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + $this->query = $this->getMock('Drupal\Core\Entity\Query\QueryInterface'); + + $this->storage = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigStorageController') + ->disableOriginalConstructor() + ->getMock(); + $this->storage->expects($this->any()) + ->method('getQuery') + ->will($this->returnValue($this->query)); + + $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); + $entity_manager->expects($this->any()) + ->method('getStorageController') + ->will($this->returnValue($this->storage)); + + $this->configFactory = $this->getMockBuilder('Drupal\Core\Config\ConfigFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->searchPageRepository = new SearchPageRepository($this->configFactory, $entity_manager); + } + + /** + * Tests the getActiveSearchPages() method. + */ + public function testGetActiveSearchPages() { + $this->query->expects($this->once()) + ->method('condition') + ->with('status', TRUE) + ->will($this->returnValue($this->query)); + $this->query->expects($this->once()) + ->method('execute') + ->will($this->returnValue(array('test' => 'test', 'other_test' => 'other_test'))); + + $entities = array(); + $entities['test'] = $this->getMock('Drupal\search\SearchPageInterface'); + $entities['other_test'] = $this->getMock('Drupal\search\SearchPageInterface'); + $this->storage->expects($this->once()) + ->method('loadMultiple') + ->with(array('test' => 'test', 'other_test' => 'other_test')) + ->will($this->returnValue($entities)); + + $result = $this->searchPageRepository->getActiveSearchPages(); + $this->assertSame($entities, $result); + } + + /** + * Tests the isSearchActive() method. + */ + public function testIsSearchActive() { + $this->query->expects($this->once()) + ->method('condition') + ->with('status', TRUE) + ->will($this->returnValue($this->query)); + $this->query->expects($this->once()) + ->method('range') + ->with(0, 1) + ->will($this->returnValue($this->query)); + $this->query->expects($this->once()) + ->method('execute') + ->will($this->returnValue(array('test' => 'test'))); + + $this->assertSame(TRUE, $this->searchPageRepository->isSearchActive()); + } + + /** + * Tests the getIndexableSearchPages() method. + */ + public function testGetIndexableSearchPages() { + $this->query->expects($this->once()) + ->method('condition') + ->with('status', TRUE) + ->will($this->returnValue($this->query)); + $this->query->expects($this->once()) + ->method('execute') + ->will($this->returnValue(array('test' => 'test', 'other_test' => 'other_test'))); + + $entities = array(); + $entities['test'] = $this->getMock('Drupal\search\SearchPageInterface'); + $entities['test']->expects($this->once()) + ->method('isIndexable') + ->will($this->returnValue(TRUE)); + $entities['other_test'] = $this->getMock('Drupal\search\SearchPageInterface'); + $entities['other_test']->expects($this->once()) + ->method('isIndexable') + ->will($this->returnValue(FALSE)); + $this->storage->expects($this->once()) + ->method('loadMultiple') + ->with(array('test' => 'test', 'other_test' => 'other_test')) + ->will($this->returnValue($entities)); + + $result = $this->searchPageRepository->getIndexableSearchPages(); + $this->assertCount(1, $result); + $this->assertSame($entities['test'], reset($result)); + } + + /** + * Tests the clearDefaultSearchPage() method. + */ + public function testClearDefaultSearchPage() { + $config = $this->getMockBuilder('Drupal\Core\Config\Config') + ->disableOriginalConstructor() + ->getMock(); + $config->expects($this->once()) + ->method('clear') + ->with('default_page') + ->will($this->returnValue($config)); + $this->configFactory->expects($this->once()) + ->method('get') + ->with('search.settings') + ->will($this->returnValue($config)); + $this->searchPageRepository->clearDefaultSearchPage(); + } + + /** + * Tests the getDefaultSearchPage() method when the default is active. + */ + public function testGetDefaultSearchPageWithActiveDefault() { + $this->query->expects($this->once()) + ->method('condition') + ->with('status', TRUE) + ->will($this->returnValue($this->query)); + $this->query->expects($this->once()) + ->method('execute') + ->will($this->returnValue(array('test' => 'test', 'other_test' => 'other_test'))); + + $config = $this->getMockBuilder('Drupal\Core\Config\Config') + ->disableOriginalConstructor() + ->getMock(); + $config->expects($this->once()) + ->method('get') + ->with('default_page') + ->will($this->returnValue('test')); + $this->configFactory->expects($this->once()) + ->method('get') + ->with('search.settings') + ->will($this->returnValue($config)); + + $this->assertSame('test', $this->searchPageRepository->getDefaultSearchPage()); + } + + /** + * Tests the getDefaultSearchPage() method when the default is inactive. + */ + public function testGetDefaultSearchPageWithInactiveDefault() { + $this->query->expects($this->once()) + ->method('condition') + ->with('status', TRUE) + ->will($this->returnValue($this->query)); + $this->query->expects($this->once()) + ->method('execute') + ->will($this->returnValue(array('test' => 'test'))); + + $config = $this->getMockBuilder('Drupal\Core\Config\Config') + ->disableOriginalConstructor() + ->getMock(); + $config->expects($this->once()) + ->method('get') + ->with('default_page') + ->will($this->returnValue('other_test')); + $this->configFactory->expects($this->once()) + ->method('get') + ->with('search.settings') + ->will($this->returnValue($config)); + + $this->assertSame('test', $this->searchPageRepository->getDefaultSearchPage()); + } + +}