diff --git a/core/lib/Drupal/Core/Composer/Composer.php b/core/lib/Drupal/Core/Composer/Composer.php
index 2f1310f..cfc9155 100644
--- a/core/lib/Drupal/Core/Composer/Composer.php
+++ b/core/lib/Drupal/Core/Composer/Composer.php
@@ -149,7 +149,6 @@ public static function ensureHtaccess(Event $event) {
*/
public static function vendorTestCodeCleanup(PackageEvent $event) {
$vendor_dir = $event->getComposer()->getConfig()->get('vendor-dir');
- $io = $event->getIO();
$op = $event->getOperation();
if ($op->getJobType() == 'update') {
$package = $op->getTargetPackage();
@@ -158,39 +157,14 @@ public static function vendorTestCodeCleanup(PackageEvent $event) {
$package = $op->getPackage();
}
$package_key = static::findPackageKey($package->getName());
- $message = sprintf(" Processing %s", $package->getPrettyName());
- if ($io->isVeryVerbose()) {
- $io->write($message);
- }
if ($package_key) {
foreach (static::$packageToCleanup[$package_key] as $path) {
$dir_to_remove = $vendor_dir . '/' . $package_key . '/' . $path;
- $print_message = $io->isVeryVerbose();
if (is_dir($dir_to_remove)) {
- if (static::deleteRecursive($dir_to_remove)) {
- $message = sprintf(" Removing directory '%s'", $path);
- }
- else {
- // Always display a message if this fails as it means something has
- // gone wrong. Therefore the message has to include the package name
- // as the first informational message might not exist.
- $print_message = TRUE;
- $message = sprintf(" Failure removing directory '%s' in package %s.", $path, $package->getPrettyName());
+ if (!static::deleteRecursive($dir_to_remove)) {
+ throw new \RuntimeException(sprintf("Failure removing directory '%s' in package '%s'.", $path, $package->getPrettyName()));
}
}
- else {
- // If the package has changed or the --prefer-dist version does not
- // include the directory this is not an error.
- $message = sprintf(" Directory '%s' does not exist", $path);
- }
- if ($print_message) {
- $io->write($message);
- }
- }
-
- if ($io->isVeryVerbose()) {
- // Add a new line to separate this output from the next package.
- $io->write("");
}
}
}
diff --git a/core/modules/contact/config/install/contact.form.personal.yml b/core/modules/contact/config/install/contact.form.personal.yml
index c766fdd..f08682a 100644
--- a/core/modules/contact/config/install/contact.form.personal.yml
+++ b/core/modules/contact/config/install/contact.form.personal.yml
@@ -6,3 +6,5 @@ label: 'Personal contact form'
recipients: { }
reply: ''
weight: 0
+message: 'Your message has been sent.'
+redirect: ''
diff --git a/core/modules/contact/config/schema/contact.schema.yml b/core/modules/contact/config/schema/contact.schema.yml
index 5a62e9d..77cfc18 100644
--- a/core/modules/contact/config/schema/contact.schema.yml
+++ b/core/modules/contact/config/schema/contact.schema.yml
@@ -22,6 +22,12 @@ contact.form.*:
weight:
type: integer
label: 'Weight'
+ message:
+ type: label
+ label: 'Message'
+ redirect:
+ type: path
+ label: 'Redirect Path'
contact.settings:
type: config_object
diff --git a/core/modules/contact/contact.post_update.php b/core/modules/contact/contact.post_update.php
new file mode 100644
index 0000000..908c7a6
--- /dev/null
+++ b/core/modules/contact/contact.post_update.php
@@ -0,0 +1,30 @@
+setMessage('Your message has been sent.')
+ ->setRedirectPath('')
+ ->save();
+ }
+}
+
+/**
+ * @} End of "addtogroup updates-8.0.x-to-8.1.x".
+ */
diff --git a/core/modules/contact/src/ContactFormEditForm.php b/core/modules/contact/src/ContactFormEditForm.php
index b4adde6..83435c7 100644
--- a/core/modules/contact/src/ContactFormEditForm.php
+++ b/core/modules/contact/src/ContactFormEditForm.php
@@ -14,6 +14,8 @@
use Drupal\Core\Form\ConfigFormBaseTrait;
use Drupal\Core\Form\FormStateInterface;
use Egulias\EmailValidator\EmailValidator;
+use Drupal\Core\Path\PathValidatorInterface;
+use Drupal\Core\Render\Element\PathElement;
/**
* Base form for contact form edit forms.
@@ -29,13 +31,21 @@ class ContactFormEditForm extends EntityForm implements ContainerInjectionInterf
protected $emailValidator;
/**
+ * The path validator.
+ *
+ * @var \Drupal\Core\Path\PathValidatorInterface
+ */
+ protected $pathValidator;
+
+ /**
* Constructs a new ContactFormEditForm.
*
* @param \Egulias\EmailValidator\EmailValidator $email_validator
* The email validator.
*/
- public function __construct(EmailValidator $email_validator) {
+ public function __construct(EmailValidator $email_validator, PathValidatorInterface $path_validator) {
$this->emailValidator = $email_validator;
+ $this->pathValidator = $path_validator;
}
/**
@@ -43,7 +53,8 @@ public function __construct(EmailValidator $email_validator) {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('email.validator')
+ $container->get('email.validator'),
+ $container->get('path.validator')
);
}
@@ -87,6 +98,19 @@ public function form(array $form, FormStateInterface $form_state) {
'#description' => $this->t("Example: 'webmaster@example.com' or 'sales@example.com,support@example.com' . To specify multiple recipients, separate each email address with a comma."),
'#required' => TRUE,
);
+ $form['message'] = array(
+ '#type' => 'textarea',
+ '#title' => $this->t('Message'),
+ '#default_value' => $contact_form->getMessage(),
+ '#description' => $this->t('The message to display to the user after submission of this form. Leave blank for no message.'),
+ );
+ $form['redirect'] = array(
+ '#type' => 'path',
+ '#title' => $this->t('Redirect path'),
+ '#convert_path' => PathElement::CONVERT_NONE,
+ '#default_value' => $contact_form->getRedirectPath(),
+ '#description' => $this->t('The path you would like to redirect to after this form has been submitted.The path of the page should be prefixed with /. Leave blank for redirect to the site front page.'),
+ );
$form['reply'] = array(
'#type' => 'textarea',
'#title' => $this->t('Auto-reply'),
@@ -124,6 +148,12 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
}
}
$form_state->setValue('recipients', $recipients);
+ $redirect_url = $form_state->getValue('redirect');
+ if ($redirect_url && $this->pathValidator->isValid($redirect_url)) {
+ if(substr($redirect_url, 0, 1) != '/') {
+ $form_state->setErrorByName('redirect', $this->t('The path should start with /.'));
+ }
+ }
}
/**
diff --git a/core/modules/contact/src/ContactFormInterface.php b/core/modules/contact/src/ContactFormInterface.php
index 8f588ee..11f3ec3 100644
--- a/core/modules/contact/src/ContactFormInterface.php
+++ b/core/modules/contact/src/ContactFormInterface.php
@@ -15,6 +15,14 @@
interface ContactFormInterface extends ConfigEntityInterface {
/**
+ * Returns the message to be displayed to user.
+ *
+ * @return string
+ * A user message.
+ */
+ public function getMessage();
+
+ /**
* Returns list of recipient email addresses.
*
* @return array
@@ -23,10 +31,28 @@
public function getRecipients();
/**
+ * Returns the path for redirect.
+ *
+ * @return string
+ * The redirect path.
+ */
+ public function getRedirectPath();
+
+ /**
+ * Returns the url object for redirect path.
+ *
+ * Empty redirect property results a url object of front page.
+ *
+ * @return \Drupal\core\Url
+ * The redirect url object.
+ */
+ public function getRedirectUrl();
+
+ /**
* Returns an auto-reply message to send to the message author.
*
* @return string
- * An auto-reply message
+ * An auto-reply message.
*/
public function getReply();
@@ -39,6 +65,16 @@ public function getReply();
public function getWeight();
/**
+ * Sets the message to be displayed to the user.
+ *
+ * @param string $message
+ * The message to display after form is submitted.
+ *
+ * @return $this
+ */
+ public function setMessage($message);
+
+ /**
* Sets list of recipient email addresses.
*
* @param array $recipients
@@ -49,6 +85,16 @@ public function getWeight();
public function setRecipients($recipients);
/**
+ * Sets the redirect path.
+ *
+ * @param string $redirect
+ * The desired path.
+ *
+ * @return $this
+ */
+ public function setRedirectPath($redirect);
+
+ /**
* Sets an auto-reply message to send to the message author.
*
* @param string $reply
diff --git a/core/modules/contact/src/Entity/ContactForm.php b/core/modules/contact/src/Entity/ContactForm.php
index 1a9f73a..7320ddd 100644
--- a/core/modules/contact/src/Entity/ContactForm.php
+++ b/core/modules/contact/src/Entity/ContactForm.php
@@ -9,6 +9,7 @@
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\contact\ContactFormInterface;
+use Drupal\Core\Url;
/**
* Defines the contact form entity.
@@ -44,6 +45,8 @@
* "recipients",
* "reply",
* "weight",
+ * "message",
+ * "redirect",
* }
* )
*/
@@ -64,6 +67,13 @@ class ContactForm extends ConfigEntityBundleBase implements ContactFormInterface
protected $label;
/**
+ * The message displayed to user.
+ *
+ * @var string
+ */
+ protected $message;
+
+ /**
* List of recipient email addresses.
*
* @var array
@@ -71,6 +81,13 @@ class ContactForm extends ConfigEntityBundleBase implements ContactFormInterface
protected $recipients = array();
/**
+ * The path to redirect to.
+ *
+ * @var string
+ */
+ protected $redirect;
+
+ /**
* An auto-reply message.
*
* @var string
@@ -87,6 +104,21 @@ class ContactForm extends ConfigEntityBundleBase implements ContactFormInterface
/**
* {@inheritdoc}
*/
+ public function getMessage() {
+ return $this->get('message');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMessage($message) {
+ $this->set('message', $message);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function getRecipients() {
return $this->recipients;
}
@@ -102,6 +134,34 @@ public function setRecipients($recipients) {
/**
* {@inheritdoc}
*/
+ public function getRedirectPath() {
+ return $this->redirect;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRedirectUrl() {
+ if ($this->redirect) {
+ $url = Url::fromUserInput($this->redirect);
+ }
+ else {
+ $url = Url::fromRoute('');
+ }
+ return $url;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setRedirectPath($redirect) {
+ $this->set('redirect', $redirect);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function getReply() {
return $this->reply;
}
diff --git a/core/modules/contact/src/MessageForm.php b/core/modules/contact/src/MessageForm.php
index 46bb5d9..c99a15d 100644
--- a/core/modules/contact/src/MessageForm.php
+++ b/core/modules/contact/src/MessageForm.php
@@ -211,9 +211,12 @@ public function save(array $form, FormStateInterface $form_state) {
$message = $this->entity;
$user = $this->currentUser();
$this->mailHandler->sendMailMessages($message, $user);
+ $contact_form = $message->getContactForm();
$this->flood->register('contact', $this->config('contact.settings')->get('flood.interval'));
- drupal_set_message($this->t('Your message has been sent.'));
+ if ($submission_message = $contact_form->getMessage()) {
+ drupal_set_message($submission_message);
+ }
// To avoid false error messages caused by flood control, redirect away from
// the contact form; either to the contacted user account or the front page.
@@ -221,7 +224,7 @@ public function save(array $form, FormStateInterface $form_state) {
$form_state->setRedirectUrl($message->getPersonalRecipient()->urlInfo());
}
else {
- $form_state->setRedirect('');
+ $form_state->setRedirectUrl($contact_form->getRedirectUrl());
}
// Save the message. In core this is a no-op but should contrib wish to
// implement message storage, this will make the task of swapping in a real
diff --git a/core/modules/contact/src/Tests/ContactSitewideTest.php b/core/modules/contact/src/Tests/ContactSitewideTest.php
index a29a45b..7d9a4df 100644
--- a/core/modules/contact/src/Tests/ContactSitewideTest.php
+++ b/core/modules/contact/src/Tests/ContactSitewideTest.php
@@ -10,6 +10,7 @@
use Drupal\Component\Utility\Unicode;
use Drupal\contact\Entity\ContactForm;
use Drupal\Core\Mail\MailFormatHelper;
+use Drupal\Core\Url;
use Drupal\field_ui\Tests\FieldUiTestTrait;
use Drupal\simpletest\WebTestBase;
use Drupal\Core\Entity\EntityTypeInterface;
@@ -151,7 +152,7 @@ function testSiteWideContact() {
$this->assertEscaped($recipients[0]);
// Test update contact form.
- $this->updateContactForm($id, $label = $this->randomMachineName(16), $recipients_str = implode(',', array($recipients[0], $recipients[1])), $reply = $this->randomMachineName(30), FALSE);
+ $this->updateContactForm($id, $label = $this->randomMachineName(16), $recipients_str = implode(',', array($recipients[0], $recipients[1])), $reply = $this->randomMachineName(30), FALSE, 'Your message has been sent.', '/user');
$config = $this->config('contact.form.' . $id)->get();
$this->assertEqual($config['label'], $label);
$this->assertEqual($config['recipients'], array($recipients[0], $recipients[1]));
@@ -295,6 +296,46 @@ function testSiteWideContact() {
$this->assertEqual($mail['subject'], t('[@label] @subject', array('@label' => $label, '@subject' => $edit['subject[0][value]'])));
$this->assertTrue(strpos($mail['body'], $field_label));
$this->assertTrue(strpos($mail['body'], $edit[$field_name . '[0][value]']));
+
+ // Test messages and redirect.
+ /** @var \Drupal\contact\ContactFormInterface $form */
+ $form = ContactForm::load($contact_form);
+ $form->setMessage('Thanks for your submission.');
+ $form->setRedirectPath('/user/' . $admin_user->id());
+ $form->save();
+ // Check that the field is displayed.
+ $this->drupalGet('contact/' . $contact_form);
+
+ // Submit the contact form and verify the content.
+ $edit = array(
+ 'subject[0][value]' => $this->randomMachineName(),
+ 'message[0][value]' => $this->randomMachineName(),
+ $field_name . '[0][value]' => $this->randomMachineName(),
+ );
+ $this->drupalPostForm(NULL, $edit, t('Send message'));
+ $this->assertText('Thanks for your submission.');
+ $this->assertUrl('user/' . $admin_user->id());
+
+ // Test Empty message.
+ /** @var \Drupal\contact\ContactFormInterface $form */
+ $form = ContactForm::load($contact_form);
+ $form->setMessage('');
+ $form->setRedirectPath('/user/' . $admin_user->id());
+ $form->save();
+ $this->drupalGet('admin/structure/contact/manage/' . $contact_form);
+ // Check that the field is displayed.
+ $this->drupalGet('contact/' . $contact_form);
+
+ // Submit the contact form and verify the content.
+ $edit = array(
+ 'subject[0][value]' => $this->randomMachineName(),
+ 'message[0][value]' => $this->randomMachineName(),
+ $field_name . '[0][value]' => $this->randomMachineName(),
+ );
+ $this->drupalPostForm(NULL, $edit, t('Send message'));
+ $result = $this->xpath('//div[@role=:role]', array(':role' => 'contentinfo'));
+ $this->assertEqual(count($result), 0, 'Messages not found.');
+ $this->assertUrl('user/' . $admin_user->id());
}
/**
@@ -356,13 +397,17 @@ function testAutoReply() {
* form.
* @param bool $selected
* A Boolean indicating whether the form should be selected by default.
+ * @param string $message
+ * The message that will be displayed to a user upon completing the contact
+ * form.
* @param array $third_party_settings
* Array of third party settings to be added to the posted form data.
*/
- function addContactForm($id, $label, $recipients, $reply, $selected, $third_party_settings = []) {
+ function addContactForm($id, $label, $recipients, $reply, $selected, $message = 'Your message has been sent.', $third_party_settings = []) {
$edit = array();
$edit['label'] = $label;
$edit['id'] = $id;
+ $edit['message'] = $message;
$edit['recipients'] = $recipients;
$edit['reply'] = $reply;
$edit['selected'] = ($selected ? TRUE : FALSE);
@@ -384,13 +429,20 @@ function addContactForm($id, $label, $recipients, $reply, $selected, $third_part
* form.
* @param bool $selected
* A Boolean indicating whether the form should be selected by default.
+ * @param string $message
+ * The message that will be displayed to a user upon completing the contact
+ * form.
+ * @param string $redirect
+ * The path where user will be redirect after this form has been submitted..
*/
- function updateContactForm($id, $label, $recipients, $reply, $selected) {
+ function updateContactForm($id, $label, $recipients, $reply, $selected, $message = 'Your message has been sent.', $redirect = '/') {
$edit = array();
$edit['label'] = $label;
$edit['recipients'] = $recipients;
$edit['reply'] = $reply;
$edit['selected'] = ($selected ? TRUE : FALSE);
+ $edit['message'] = $message;
+ $edit['redirect'] = $redirect;
$this->drupalPostForm("admin/structure/contact/manage/$id", $edit, t('Save'));
}
diff --git a/core/modules/contact/src/Tests/ContactStorageTest.php b/core/modules/contact/src/Tests/ContactStorageTest.php
index f18d10e..a5f8119 100644
--- a/core/modules/contact/src/Tests/ContactStorageTest.php
+++ b/core/modules/contact/src/Tests/ContactStorageTest.php
@@ -52,7 +52,7 @@ public function testContactStorage() {
$this->drupalLogin($admin_user);
// Create first valid contact form.
$mail = 'simpletest@example.com';
- $this->addContactForm($id = Unicode::strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', array($mail)), '', TRUE, [
+ $this->addContactForm($id = Unicode::strtolower($this->randomMachineName(16)), $label = $this->randomMachineName(16), implode(',', array($mail)), '', TRUE, 'Your message has been sent.', [
'send_a_pony' => 1,
]);
$this->assertRaw(t('Contact form %label has been added.', array('%label' => $label)));
diff --git a/core/modules/contact/src/Tests/Update/ContactUpdateTest.php b/core/modules/contact/src/Tests/Update/ContactUpdateTest.php
new file mode 100644
index 0000000..c50dbe5
--- /dev/null
+++ b/core/modules/contact/src/Tests/Update/ContactUpdateTest.php
@@ -0,0 +1,55 @@
+databaseDumpFiles = [
+ __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
+ ];
+ }
+
+ /**
+ * Tests contact_form updates.
+ *
+ * @see contact_post_update_add_message_redirect_field_to_contact_form()
+ */
+ public function testPostUpdateContactFormFields() {
+ // Check that contact_form does not have fields redirect and message.
+ $entities = ContactForm::loadMultiple();
+ foreach($entities as $contact) {
+ // Check whether 'message' and 'redirect' property does not exist for this entity.
+ $this->assertFalse(isset($contact->message), 'Message does not exist');
+ $this->assertFalse(isset($contact->redirect), 'Redirect does not exist');
+ }
+
+ // Run updates.
+ $this->runUpdates();
+
+ // Check that contact_form have fields 'redirect' and 'message'.
+ $entities = ContactForm::loadMultiple();
+ foreach($entities as $contact) {
+ // Check whether 'message' and 'redirect' property exist for this entity.
+ $this->assertFalse(isset($contact->message), 'Message property exists');
+ $this->assertFalse(isset($contact->redirect), 'Redirect property exists');
+ }
+ }
+
+}
diff --git a/core/modules/contact/tests/modules/contact_test/config/install/contact.form.feedback.yml b/core/modules/contact/tests/modules/contact_test/config/install/contact.form.feedback.yml
index 8fb7765..d6e048f 100644
--- a/core/modules/contact/tests/modules/contact_test/config/install/contact.form.feedback.yml
+++ b/core/modules/contact/tests/modules/contact_test/config/install/contact.form.feedback.yml
@@ -5,3 +5,5 @@ reply: ''
weight: 0
status: true
langcode: en
+message: 'Your message has been sent.'
+redirect: ''
diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php
index 5d6ae1d..b2a7dfc 100644
--- a/core/modules/taxonomy/src/Entity/Vocabulary.php
+++ b/core/modules/taxonomy/src/Entity/Vocabulary.php
@@ -20,6 +20,7 @@
* handlers = {
* "storage" = "Drupal\taxonomy\VocabularyStorage",
* "list_builder" = "Drupal\taxonomy\VocabularyListBuilder",
+ * "access" = "Drupal\taxonomy\VocabularyAccessControlHandler",
* "form" = {
* "default" = "Drupal\taxonomy\VocabularyForm",
* "reset" = "Drupal\taxonomy\Form\VocabularyResetForm",
diff --git a/core/modules/taxonomy/src/TermViewsData.php b/core/modules/taxonomy/src/TermViewsData.php
index 618b4d7..7108504 100644
--- a/core/modules/taxonomy/src/TermViewsData.php
+++ b/core/modules/taxonomy/src/TermViewsData.php
@@ -71,7 +71,7 @@ public function getViewsData() {
);
$data['taxonomy_term_field_data']['vid']['help'] = $this->t('Filter the results of "Taxonomy: Term" to a particular vocabulary.');
- unset($data['taxonomy_term_field_data']['vid']['field']);
+ $data['taxonomy_term_field_data']['vid']['field']['help'] = $this->t('The vocabulary name.');
unset($data['taxonomy_term_field_data']['vid']['argument']);
unset($data['taxonomy_term_field_data']['vid']['sort']);
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldVidTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldVidTest.php
new file mode 100644
index 0000000..f1ba681
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldVidTest.php
@@ -0,0 +1,44 @@
+executeView($view);
+
+ $actual = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
+ return $view->field['vid']->advancedRender($view->result[0]);
+ });
+ $vocabulary = Vocabulary::load($this->term1->getVocabularyId());
+ $expected = $vocabulary->get('name');
+
+ $this->assertEqual($expected, $actual);
+ }
+
+}
diff --git a/core/modules/taxonomy/src/VocabularyAccessControlHandler.php b/core/modules/taxonomy/src/VocabularyAccessControlHandler.php
new file mode 100644
index 0000000..29289c6
--- /dev/null
+++ b/core/modules/taxonomy/src/VocabularyAccessControlHandler.php
@@ -0,0 +1,37 @@
+