composer update
This commit is contained in:
parent
f6abc3dce2
commit
71dfaca858
1753 changed files with 45274 additions and 14619 deletions
|
@ -4,6 +4,7 @@ namespace Drupal\path\Plugin\Field\FieldType;
|
|||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Field\FieldItemList;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\TypedData\ComputedItemListTrait;
|
||||
|
||||
|
@ -26,12 +27,18 @@ class PathFieldItemList extends FieldItemList {
|
|||
|
||||
$entity = $this->getEntity();
|
||||
if (!$entity->isNew()) {
|
||||
// @todo Support loading language neutral aliases in
|
||||
// https://www.drupal.org/node/2511968.
|
||||
$alias = \Drupal::service('path.alias_storage')->load([
|
||||
$conditions = [
|
||||
'source' => '/' . $entity->toUrl()->getInternalPath(),
|
||||
'langcode' => $this->getLangcode(),
|
||||
]);
|
||||
];
|
||||
$alias = \Drupal::service('path.alias_storage')->load($conditions);
|
||||
if ($alias === FALSE) {
|
||||
// Fall back to non-specific language.
|
||||
if ($this->getLangcode() !== LanguageInterface::LANGCODE_NOT_SPECIFIED) {
|
||||
$conditions['langcode'] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
$alias = \Drupal::service('path.alias_storage')->load($conditions);
|
||||
}
|
||||
}
|
||||
|
||||
if ($alias) {
|
||||
$value = $alias;
|
||||
|
|
|
@ -63,10 +63,15 @@ class PathItem extends FieldItemBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function postSave($update) {
|
||||
// If specified, rely on the langcode property for the language, so that the
|
||||
// existing language of an alias can be kept. That could for example be
|
||||
// unspecified even if the field/entity has a specific langcode.
|
||||
$alias_langcode = ($this->langcode && $this->pid) ? $this->langcode : $this->getLangcode();
|
||||
|
||||
if (!$update) {
|
||||
if ($this->alias) {
|
||||
$entity = $this->getEntity();
|
||||
if ($path = \Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode())) {
|
||||
if ($path = \Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $alias_langcode)) {
|
||||
$this->pid = $path['pid'];
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +84,7 @@ class PathItem extends FieldItemBase {
|
|||
// Only save a non-empty alias.
|
||||
elseif ($this->alias) {
|
||||
$entity = $this->getEntity();
|
||||
\Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode(), $this->pid);
|
||||
\Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $alias_langcode, $this->pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,14 @@ class PathAliasConstraintValidator extends ConstraintValidator implements Contai
|
|||
if ($entity && !$entity->isNew() && !$entity->isDefaultRevision()) {
|
||||
/** @var \Drupal\Core\Entity\ContentEntityInterface $original */
|
||||
$original = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
|
||||
if ($value->alias != $original->path->alias) {
|
||||
$this->context->addViolation($constraint->message);
|
||||
$entity_langcode = $entity->language()->getId();
|
||||
|
||||
// Only add the violation if the current translation does not have the
|
||||
// same path alias.
|
||||
if ($original->hasTranslation($entity_langcode)) {
|
||||
if ($value->alias != $original->getTranslation($entity_langcode)->path->alias) {
|
||||
$this->context->addViolation($constraint->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Drupal\Tests\path\Functional;
|
||||
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
|
@ -21,17 +21,26 @@ class PathContentModerationTest extends BrowserTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'path', 'content_moderation'];
|
||||
public static $modules = [
|
||||
'node',
|
||||
'path',
|
||||
'content_moderation',
|
||||
'content_translation',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
ConfigurableLanguage::createFromLangcode('fr')->save();
|
||||
$this->rebuildContainer();
|
||||
|
||||
// Created a content type.
|
||||
$node_type = NodeType::create(['name' => 'moderated', 'type' => 'moderated']);
|
||||
$node_type->save();
|
||||
$this->drupalCreateContentType([
|
||||
'name' => 'moderated',
|
||||
'type' => 'moderated',
|
||||
]);
|
||||
|
||||
// Set the content type as moderated.
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
|
@ -39,6 +48,21 @@ class PathContentModerationTest extends BrowserTestBase {
|
|||
$workflow->save();
|
||||
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
// Enable URL language detection and selection.
|
||||
$edit = ['language_interface[enabled][language-url]' => 1];
|
||||
$this->drupalPostForm('admin/config/regional/language/detection', $edit, 'Save settings');
|
||||
|
||||
// Enable translation for moderated node.
|
||||
$edit = [
|
||||
'entity_types[node]' => 1,
|
||||
'settings[node][moderated][translatable]' => 1,
|
||||
'settings[node][moderated][fields][path]' => 1,
|
||||
'settings[node][moderated][fields][body]' => 1,
|
||||
'settings[node][moderated][settings][language][language_alterable]' => 1,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/content-language', $edit, 'Save configuration');
|
||||
\Drupal::entityTypeManager()->clearCachedDefinitions();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,4 +130,104 @@ class PathContentModerationTest extends BrowserTestBase {
|
|||
$this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that translated and moderated node can get new draft revision.
|
||||
*/
|
||||
public function testTranslatedModeratedNodeAlias() {
|
||||
// Create one node with a random alias.
|
||||
$default_node = $this->drupalCreateNode([
|
||||
'type' => 'moderated',
|
||||
'langcode' => 'en',
|
||||
'moderation_state' => 'published',
|
||||
'path' => '/' . $this->randomMachineName(),
|
||||
]);
|
||||
|
||||
// Add published translation with another alias.
|
||||
$this->drupalGet('node/' . $default_node->id());
|
||||
$this->drupalGet('node/' . $default_node->id() . '/translations');
|
||||
$this->clickLink('Add');
|
||||
$edit_translation = [
|
||||
'body[0][value]' => $this->randomMachineName(),
|
||||
'moderation_state[0][state]' => 'published',
|
||||
'path[0][alias]' => '/' . $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit_translation, 'Save (this translation)');
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet('fr' . $edit_translation['path[0][alias]']);
|
||||
$this->assertSession()->pageTextContains($edit_translation['body[0][value]']);
|
||||
|
||||
$default_path = $default_node->path->alias;
|
||||
$translation_path = 'fr' . $edit_translation['path[0][alias]'];
|
||||
|
||||
$this->assertPathsAreAccessible([$default_path, $translation_path]);
|
||||
|
||||
// Try to create new draft revision for translation with a new path alias.
|
||||
$edit_new_translation_draft_with_alias = [
|
||||
'moderation_state[0][state]' => 'draft',
|
||||
'path[0][alias]' => '/' . $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_with_alias, 'Save (this translation)');
|
||||
// Confirm the expected error.
|
||||
$this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.');
|
||||
|
||||
// Create new draft revision for translation without changing path alias.
|
||||
$edit_new_translation_draft = [
|
||||
'body[0][value]' => $this->randomMachineName(),
|
||||
'moderation_state[0][state]' => 'draft',
|
||||
];
|
||||
$this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft, t('Save (this translation)'));
|
||||
// Confirm that the new draft revision was created.
|
||||
$this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.');
|
||||
$this->assertSession()->pageTextContains($edit_new_translation_draft['body[0][value]']);
|
||||
$this->assertPathsAreAccessible([$default_path, $translation_path]);
|
||||
|
||||
// Try to create a new draft revision for translation with path alias from
|
||||
// the original language's default revision.
|
||||
$edit_new_translation_draft_with_defaults_alias = [
|
||||
'moderation_state[0][state]' => 'draft',
|
||||
'path[0][alias]' => $default_node->path->alias,
|
||||
];
|
||||
$this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_with_defaults_alias, 'Save (this translation)');
|
||||
// Verify the expected error.
|
||||
$this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.');
|
||||
|
||||
// Try to create new draft revision for translation with deleted (empty)
|
||||
// path alias.
|
||||
$edit_new_translation_draft_empty_alias = [
|
||||
'body[0][value]' => $this->randomMachineName(),
|
||||
'moderation_state[0][state]' => 'draft',
|
||||
'path[0][alias]' => '',
|
||||
];
|
||||
$this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_empty_alias, 'Save (this translation)');
|
||||
// Confirm the expected error.
|
||||
$this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.');
|
||||
|
||||
// Create new default (published) revision for translation with new path
|
||||
// alias.
|
||||
$edit_new_translation = [
|
||||
'body[0][value]' => $this->randomMachineName(),
|
||||
'moderation_state[0][state]' => 'published',
|
||||
'path[0][alias]' => '/' . $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation, 'Save (this translation)');
|
||||
// Confirm that the new published revision was created.
|
||||
$this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.');
|
||||
$this->assertSession()->pageTextContains($edit_new_translation['body[0][value]']);
|
||||
$this->assertSession()->addressEquals('fr' . $edit_new_translation['path[0][alias]']);
|
||||
$this->assertPathsAreAccessible([$default_path]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper callback to verify paths are responding with status 200.
|
||||
*
|
||||
* @param string[] $paths
|
||||
* An array of paths to check for.
|
||||
*/
|
||||
public function assertPathsAreAccessible(array $paths) {
|
||||
foreach ($paths as $path) {
|
||||
$this->drupalGet($path);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Drupal\Tests\path\Functional;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
|
||||
/**
|
||||
* Confirm that the Path module user interface works with languages.
|
||||
*
|
||||
|
@ -78,4 +80,36 @@ class PathLanguageUiTest extends PathTestBase {
|
|||
$this->assertText(t('Filter aliases'), 'Foreign URL alias works');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that language unspecific aliases are shown and saved in the node form.
|
||||
*/
|
||||
public function testNotSpecifiedNode() {
|
||||
// Create test node.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
// Create a language-unspecific alias in the admin UI, ensure that is
|
||||
// displayed and the langcode is not changed when saving.
|
||||
$edit = [
|
||||
'source' => '/node/' . $node->id(),
|
||||
'alias' => '/' . $this->getRandomGenerator()->word(8),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
$this->drupalGet($node->toUrl('edit-form'));
|
||||
$this->assertSession()->fieldValueEquals('path[0][alias]', $edit['alias']);
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
|
||||
$this->drupalGet('admin/config/search/path');
|
||||
$this->assertSession()->pageTextContains('None');
|
||||
$this->assertSession()->pageTextNotContains('English');
|
||||
|
||||
// Create another node, with no alias, to ensure non-language specific
|
||||
// aliases are loaded correctly.
|
||||
$node = $this->drupalCreateNode();
|
||||
$this->drupalget($node->toUrl('edit-form'));
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
$this->assertSession()->pageTextNotContains(t('The alias is already in use.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue