/** * Test adding custom links with wrong/private/correct paths. */ public function testCustomLinks() { $language = $this->languageManager->getCurrentLanguage(); // Set a path alias for the node page. $alias = array('source' => 'system/files', 'alias' => 'public-files'); $this->aliasStorage->save('system/files', 'public-files', $language->getId()); $this->drupalGet('admin/config/search/xmlsitemap/custom'); $this->clickLink(t('Add custom link')); // Test an invalid path. $edit['loc'] = 'invalid-testing-path'; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('The custom link @link is either invalid or it cannot be accessed by anonymous users.', array('@link' => $edit['loc']))); $this->assertNoSitemapLink(array('type' => 'custom', 'loc' => $edit['loc'])); // Test a path not accessible to anonymous user. $edit['loc'] = 'admin/people/people'; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('The custom link @link is either invalid or it cannot be accessed by anonymous users.', array('@link' => $edit['loc']))); $this->assertNoSitemapLink(array('type' => 'custom', 'loc' => $edit['loc'])); // Test that the current page, which should not give a false positive for // $menu_item['access'] since the result has been cached already. $edit['loc'] = 'admin/config/search/xmlsitemap/custom/add'; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('The custom link @link is either invalid or it cannot be accessed by anonymous users.', array('@link' => $edit['loc']))); $this->assertNoSitemapLink(array('type' => 'custom', 'loc' => $edit['loc'])); }
/** * Tests the action execution. * * @covers ::execute */ public function testActionExecution() { $alias = 'about/team'; $this->aliasStorage->delete(['alias' => $alias])->shouldBeCalledTimes(1); $this->action->setContextValue('alias', $alias); $this->action->execute(); }
/** * Tests the action execution. * * @covers ::execute */ public function testActionExecution() { $path = 'node/1'; $this->aliasStorage->delete(['path' => $path])->shouldBeCalledTimes(1); $this->action->setContextValue('path', $path); $this->action->execute(); }
/** * {@inheritdoc} */ public function execute() { $source = $this->getContextValue('source'); $alias = $this->getContextValue('alias'); $language = $this->getContextValue('language'); $langcode = isset($language) ? $language->getId() : LanguageInterface::LANGCODE_NOT_SPECIFIED; $this->aliasStorage->save($source, $alias, $langcode); }
/** * Tests the action execution when a language is specified. * * @covers ::execute */ public function testActionExecutionWithLanguage() { $language = $this->prophesize(LanguageInterface::class); $language->getId()->willReturn('en'); $this->aliasStorage->save('node/1', 'about', 'en')->shouldBeCalledTimes(1); $this->action->setContextValue('source', 'node/1')->setContextValue('alias', 'about')->setContextValue('language', $language->reveal()); $this->action->execute(); }
/** * Creates entity path alias. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity that should get an alias. * @param string $alias * The alias to be created. */ protected function doExecute(EntityInterface $entity, $alias) { // We need to save the entity before we can get its internal path. if ($entity->isNew()) { $entity->save(); } $path = $entity->urlInfo()->getInternalPath(); $langcode = $entity->language()->getId(); $this->aliasStorage->save($path, $alias, $langcode); }
/** * Tests the action execution with a saved entity. * * @covers ::execute */ public function testActionExecutionWithSavedEntity() { // Test that the alias is only saved once. $this->aliasStorage->save('test/1', 'about', 'en')->shouldBeCalledTimes(1); $entity = $this->getMockEntity(); $entity->isNew()->willReturn(FALSE)->shouldBeCalledTimes(1); // Test that existing entities are not saved again. $entity->save()->shouldNotBeCalled(); $this->action->setContextValue('entity', $entity->reveal())->setContextValue('alias', 'about'); $this->action->execute(); }
/** * {@inheritdoc} */ public function execute() { $alias = $this->getContextValue('alias'); $entity = $this->getContextValue('entity'); // We need to save the entity before we can get its internal path. if ($entity->isNew()) { $entity->save(); } $path = $entity->urlInfo()->getInternalPath(); $langcode = $entity->language()->getId(); $this->aliasStorage->save($path, $alias, $langcode); }
/** * Tests the getAliasByPath cache with an unpreloaded path with alias. * * @covers ::getAliasByPath * @covers ::writeCache */ public function testGetAliasByPathUncachedMissWithAlias() { $path_part1 = $this->randomMachineName(); $path_part2 = $this->randomMachineName(); $path = $path_part1 . '/' . $path_part2; $cached_path = $this->randomMachineName(); $cached_no_alias_path = $this->randomMachineName(); $cached_alias = $this->randomMachineName(); $new_alias = $this->randomMachineName(); $language = $this->setUpCurrentLanguage(); $cached_paths = array($language->getId() => array($cached_path, $cached_no_alias_path)); $this->cache->expects($this->once())->method('get')->with($this->cacheKey)->will($this->returnValue((object) array('data' => $cached_paths))); // Simulate a request so that the preloaded paths are fetched. $this->aliasManager->setCacheKey($this->path); $this->aliasWhitelist->expects($this->any())->method('get')->with($path_part1)->will($this->returnValue(TRUE)); $this->aliasStorage->expects($this->once())->method('preloadPathAlias')->with($cached_paths[$language->getId()], $language->getId())->will($this->returnValue(array($cached_path => $cached_alias))); $this->aliasStorage->expects($this->once())->method('lookupPathAlias')->with($path, $language->getId())->will($this->returnValue($new_alias)); $this->assertEquals($new_alias, $this->aliasManager->getAliasByPath($path)); // Call it twice to test the static cache. $this->assertEquals($new_alias, $this->aliasManager->getAliasByPath($path)); // This needs to write out the cache. $expected_new_cache = array($language->getId() => array($cached_path, $path, $cached_no_alias_path)); $this->cache->expects($this->once())->method('set')->with($this->cacheKey, $expected_new_cache, (int) $_SERVER['REQUEST_TIME'] + 60 * 60 * 24); $this->aliasManager->writeCache(); }
/** * Tests the getAliasByPath cache with an unpreloaded path with alias. * * @covers ::getAliasByPath * @covers ::writeCache */ public function testGetAliasByPathUncachedMissWithAlias() { $path_part1 = $this->randomMachineName(); $path_part2 = $this->randomMachineName(); $path = '/' . $path_part1 . '/' . $path_part2; $cached_path = $this->randomMachineName(); $cached_no_alias_path = $this->randomMachineName(); $cached_alias = $this->randomMachineName(); $new_alias = $this->randomMachineName(); $language = $this->setUpCurrentLanguage(); $cached_paths = array($language->getId() => array($cached_path, $cached_no_alias_path)); $this->cache->expects($this->once())->method('get')->with($this->cacheKey)->will($this->returnValue((object) array('data' => $cached_paths))); // Simulate a request so that the preloaded paths are fetched. $this->aliasManager->setCacheKey($this->path); $this->aliasWhitelist->expects($this->any())->method('get')->with($path_part1)->will($this->returnValue(TRUE)); $this->aliasStorage->expects($this->once())->method('preloadPathAlias')->with($cached_paths[$language->getId()], $language->getId())->will($this->returnValue(array($cached_path => $cached_alias))); $this->aliasStorage->expects($this->once())->method('lookupPathAlias')->with($path, $language->getId())->will($this->returnValue($new_alias)); $this->assertEquals($new_alias, $this->aliasManager->getAliasByPath($path)); // Call it twice to test the static cache. $this->assertEquals($new_alias, $this->aliasManager->getAliasByPath($path)); // There is already a cache entry, so this should not write out to the // cache. $this->cache->expects($this->never())->method('set'); $this->aliasManager->writeCache(); }
/** * {@inheritdoc} */ public function getAliasByPath($path, $langcode = NULL) { if ($path[0] !== '/') { throw new \InvalidArgumentException(sprintf('Source path %s has to start with a slash.', $path)); } // If no language is explicitly specified we default to the current URL // language. If we used a language different from the one conveyed by the // requested URL, we might end up being unable to check if there is a path // alias matching the URL path. $langcode = $langcode ?: $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId(); // Check the path whitelist, if the top-level part before the first / // is not in the list, then there is no need to do anything further, // it is not in the database. if ($path === '/' || !$this->whitelist->get(strtok(trim($path, '/'), '/'))) { return $path; } // During the first call to this method per language, load the expected // paths for the page from cache. if (empty($this->langcodePreloaded[$langcode])) { $this->langcodePreloaded[$langcode] = TRUE; $this->lookupMap[$langcode] = array(); // Load the cached paths that should be used for preloading. This only // happens if a cache key has been set. if ($this->preloadedPathLookups === FALSE) { $this->preloadedPathLookups = array(); if ($this->cacheKey) { if ($cached = $this->cache->get($this->cacheKey)) { $this->preloadedPathLookups = $cached->data; } else { $this->cacheNeedsWriting = TRUE; } } } // Load paths from cache. if (!empty($this->preloadedPathLookups[$langcode])) { $this->lookupMap[$langcode] = $this->storage->preloadPathAlias($this->preloadedPathLookups[$langcode], $langcode); // Keep a record of paths with no alias to avoid querying twice. $this->noAlias[$langcode] = array_flip(array_diff_key($this->preloadedPathLookups[$langcode], array_keys($this->lookupMap[$langcode]))); } } // If we already know that there are no aliases for this path simply return. if (!empty($this->noAlias[$langcode][$path])) { return $path; } // If the alias has already been loaded, return it from static cache. if (isset($this->lookupMap[$langcode][$path])) { return $this->lookupMap[$langcode][$path]; } // Try to load alias from storage. if ($alias = $this->storage->lookupPathAlias($path, $langcode)) { $this->lookupMap[$langcode][$path] = $alias; return $alias; } // We can't record anything into $this->lookupMap because we didn't find any // aliases for this path. Thus cache to $this->noAlias. $this->noAlias[$langcode][$path] = TRUE; return $path; }
/** * {@inheritdoc} */ public function resolveCacheMiss($root) { $exists = $this->aliasStorage->pathHasMatchingAlias('/' . $root); $this->storage[$root] = $exists; $this->persist($root); if ($exists) { return TRUE; } }
/** * Displays the path administration overview page. * * @param \Symfony\Component\HttpFoundation\Request $request * The request object. * * @return array * A render array as expected by drupal_render(). */ public function adminOverview(Request $request) { $keys = $request->query->get('search'); // Add the filter form above the overview table. $build['path_admin_filter_form'] = $this->formBuilder()->getForm('Drupal\\path\\Form\\PathFilterForm', $keys); // Enable language column if language.module is enabled or if we have any // alias with a language. $multilanguage = $this->moduleHandler()->moduleExists('language') || $this->aliasStorage->languageAliasExists(); $header = array(); $header[] = array('data' => $this->t('Alias'), 'field' => 'alias', 'sort' => 'asc'); $header[] = array('data' => $this->t('System'), 'field' => 'source'); if ($multilanguage) { $header[] = array('data' => $this->t('Language'), 'field' => 'langcode'); } $header[] = $this->t('Operations'); $rows = array(); $destination = $this->getDestinationArray(); foreach ($this->aliasStorage->getAliasesForAdminListing($header, $keys) as $data) { $row = array(); // @todo Should Path module store leading slashes? See // https://www.drupal.org/node/2430593. $row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput($data->source, array('attributes' => array('title' => $data->alias)))); $row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput($data->source, array('alias' => TRUE, 'attributes' => array('title' => $data->source)))); if ($multilanguage) { $row['data']['language_name'] = $this->languageManager()->getLanguageName($data->langcode); } $operations = array(); $operations['edit'] = array('title' => $this->t('Edit'), 'url' => Url::fromRoute('path.admin_edit', ['pid' => $data->pid], ['query' => $destination])); $operations['delete'] = array('title' => $this->t('Delete'), 'url' => Url::fromRoute('path.delete', ['pid' => $data->pid], ['query' => $destination])); $row['data']['operations'] = array('data' => array('#type' => 'operations', '#links' => $operations)); // If the system path maps to a different URL alias, highlight this table // row to let the user know of old aliases. if ($data->alias != $this->aliasManager->getAliasByPath($data->source, $data->langcode)) { $row['class'] = array('warning'); } $rows[] = $row; } $build['path_table'] = array('#type' => 'table', '#header' => $header, '#rows' => $rows, '#empty' => $this->t('No URL aliases available. <a href=":link">Add URL alias</a>.', array(':link' => $this->url('path.admin_add')))); $build['path_pager'] = array('#type' => 'pager'); return $build; }
public function adminOverview($keys) { // Add the filter form above the overview table. $build['path_admin_filter_form'] = $this->formBuilder()->getForm('Drupal\\path\\Form\\PathFilterForm', $keys); // Enable language column if language.module is enabled or if we have any // alias with a language. $multilanguage = $this->moduleHandler()->moduleExists('language') || $this->aliasStorage->languageAliasExists(); $header = array(); $header[] = array('data' => $this->t('Alias'), 'field' => 'alias', 'sort' => 'asc'); $header[] = array('data' => $this->t('System'), 'field' => 'source'); if ($multilanguage) { $header[] = array('data' => $this->t('Language'), 'field' => 'langcode'); } $header[] = $this->t('Operations'); $rows = array(); $destination = drupal_get_destination(); foreach ($this->aliasStorage->getAliasesForAdminListing($header, $keys) as $data) { $row = array(); $row['data']['alias'] = l(truncate_utf8($data->alias, 50, FALSE, TRUE), $data->source, array('attributes' => array('title' => $data->alias))); $row['data']['source'] = l(truncate_utf8($data->source, 50, FALSE, TRUE), $data->source, array('alias' => TRUE, 'attributes' => array('title' => $data->source))); if ($multilanguage) { $row['data']['language_name'] = $this->languageManager()->getLanguageName($data->langcode); } $operations = array(); $operations['edit'] = array('title' => $this->t('Edit'), 'route_name' => 'path.admin_edit', 'route_parameters' => array('pid' => $data->pid), 'query' => $destination); $operations['delete'] = array('title' => $this->t('Delete'), 'route_name' => 'path.delete', 'route_parameters' => array('pid' => $data->pid), 'query' => $destination); $row['data']['operations'] = array('data' => array('#type' => 'operations', '#links' => $operations)); // If the system path maps to a different URL alias, highlight this table // row to let the user know of old aliases. if ($data->alias != $this->aliasManager->getAliasByPath($data->source, $data->langcode)) { $row['class'] = array('warning'); } $rows[] = $row; } $build['path_table'] = array('#type' => 'table', '#header' => $header, '#rows' => $rows, '#empty' => $this->t('No URL aliases available. <a href="@link">Add URL alias</a>.', array('@link' => $this->url('path.admin_add')))); $build['path_pager'] = array('#theme' => 'pager'); return $build; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { // Remove unnecessary values. $form_state->cleanValues(); $pid = $form_state->getValue('pid', 0); $source = $form_state->getValue('source'); $alias = $form_state->getValue('alias'); // Language is only set if language.module is enabled, otherwise save for all // languages. $langcode = $form_state->getValue('langcode', LanguageInterface::LANGCODE_NOT_SPECIFIED); $this->aliasStorage->save($source, $alias, $langcode, $pid); drupal_set_message($this->t('The alias has been saved.')); $form_state->setRedirect('path.admin_overview'); }
/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { // Remove unnecessary values. form_state_values_clean($form_state); $pid = isset($form_state['values']['pid']) ? $form_state['values']['pid'] : 0; $source =& $form_state['values']['source']; $source = $this->aliasManager->getPathByAlias($source); $alias = $form_state['values']['alias']; // Language is only set if language.module is enabled, otherwise save for all // languages. $langcode = isset($form_state['values']['langcode']) ? $form_state['values']['langcode'] : LanguageInterface::LANGCODE_NOT_SPECIFIED; $this->aliasStorage->save($source, $alias, $langcode, $pid); drupal_set_message($this->t('The alias has been saved.')); $form_state['redirect_route'] = new Url('path.admin_overview'); }
protected function preloadSourceItems($langcode) { if ($item = cache_get($this->cacheKey, 'cache_path')) { // FIXME $sources = $item->data; if (!empty($sources)) { $aliases = $this->storage->preloadPathAlias($item->data, $langcode); // Also set to false anything that is not set. foreach ($sources as $source) { if (!isset($aliases[$source])) { $aliases[$source] = false; } } return $aliases; } } return []; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->aliasStorage->delete(array('pid' => $this->pathAlias['pid'])); $form_state->setRedirect('path.admin_overview'); }
/** * {@inheritdoc} */ public function execute() { $path = $this->getContextValue('path'); $this->aliasStorage->delete(['path' => $path]); }
/** * Creates an alias for an existing path. * * @param string $source * The existing path that should be aliased. * @param string $alias * The alias path that should be created. * @param \Drupal\Core\Language\LanguageInterface $language * (optional) The language. */ protected function doExecute($source, $alias, LanguageInterface $language = NULL) { $langcode = isset($language) ? $language->getId() : LanguageInterface::LANGCODE_NOT_SPECIFIED; $this->aliasStorage->save($source, $alias, $langcode); }
/** * {@inheritdoc} */ public function execute() { $alias = $this->getContextValue('alias'); $this->aliasStorage->delete(['alias' => $alias]); }
public function testTheMockUp() { // Tests registered aliases $this->assertSame('alias-en', $this->aliasStorage->lookupPathAlias('duplicate-langcode', 'en')); $this->assertSame('alias-fr', $this->aliasStorage->lookupPathAlias('duplicate-langcode', 'fr')); $this->assertSame('alias-und', $this->aliasStorage->lookupPathAlias('duplicate-langcode', LanguageInterface::LANGCODE_NOT_SPECIFIED)); // Non existing language returns the undefined language alias $this->assertSame('alias-und', $this->aliasStorage->lookupPathAlias('duplicate-langcode', 'martian')); // More basic tests $this->assertSame('duplicate-langcode', $this->aliasStorage->lookupPathSource('alias-fr', 'fr')); $this->assertSame('duplicate-langcode', $this->aliasStorage->lookupPathSource('alias-en', 'en')); $this->assertFalse($this->aliasStorage->lookupPathSource('alias-fr', LanguageInterface::LANGCODE_NOT_SPECIFIED)); $this->assertFalse($this->aliasStorage->lookupPathSource('alias-en', LanguageInterface::LANGCODE_NOT_SPECIFIED)); $this->assertFalse($this->aliasStorage->lookupPathSource('alias-fr', 'en')); $this->assertFalse($this->aliasStorage->lookupPathSource('alias-en', 'fr')); }
/** * {@inheritdoc} */ public function deleteMultiple($pids) { foreach ($pids as $pid) { $this->aliasStorage->delete(array('pid' => $pid)); } }
/** * Delete an existing alias by a given path. * * @param string $path * Existing system path. */ protected function doExecute($path) { $this->aliasStorage->delete(['path' => $path]); }
/** * Implements \Drupal\Core\Form\FormInterface::submitForm(). */ public function submitForm(array &$form, array &$form_state) { $this->aliasStorage->delete(array('pid' => $this->pathAlias['pid'])); $form_state['redirect'] = 'admin/config/search/path'; }