diff --git a/.gitignore b/.gitignore
index 3d72576..cabdd8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
+/composer.lock
+/vendor/
+
.DS_Store
-.idea
\ No newline at end of file
+.idea
diff --git a/.travis.yml b/.travis.yml
index 42d63fd..3cd27af 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,103 +1,71 @@
language: php
+sudo: true
php:
- - 5.5
- - 5.6
- - 7.0
-
-matrix:
- allow_failures:
- - php: 7.0
+- 5.6
+- 7.0
+#- 7.1
+#- 7.2
env:
global:
- - MESSAGE_MODULE='message'
- - MESSAGE_REPO='https://github.com/Gizra/message.git'
- - MESSAGE_VERSION='8.x-1.x'
- - MESSAGE_NOTIFY_MODULE='message_notify'
- - MESSAGE_NOTIFY_REPO='https://github.com/Gizra/message_notify.git'
- - MESSAGE_NOTIFY_VERSION='8.x-1.x'
- - MESSAGE_UI_MODULE='message_ui'
- - MESSAGE_UI_REPO='https://github.com/mccrodp/message_ui.git'
- - MESSAGE_UI_VERSION='8.x-1.x'
- - MODULE_NAME='message_private'
- - MODULE_TEST_GROUP='Message Private'
- - DRUPAL_REPO='git://drupalcode.org/project/drupal.git'
- - DRUPAL_VERSION='8.0.5'
- - PHPCS_VERSION='2.0.*@dev'
- - CODER_VERSION='8.2.0-beta1'
-
-before_install:
- # Ensure we have the latest sources.
- - sudo apt-get -y update
-
- # Composer.
- - sed -i '1i export PATH="$HOME/.composer/vendor/bin:$PATH"' $HOME/.bashrc
- - source $HOME/.bashrc
- # - composer self-update
-
- # Drush.
- - composer global require "youngj/httpserver:dev-master#41dd2b7"
- - composer global require drush/drush:~8
-
- # Codesniffer.
- - composer global require squizlabs/php_codesniffer:$PHPCS_VERSION
-
- # Coder.
- - composer global require drupal/coder:$CODER_VERSION
- - ln -s ~/.composer/vendor/drupal/coder/coder_sniffer/Drupal ~/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/
+ - COMPOSER_MEMORY_LIMIT=2G
+ - DRUPAL_DIR=${TRAVIS_BUILD_DIR}/../build
+ - MODULES_DIR=${DRUPAL_DIR}/modules/contrib
+ - MODULE_DIR=${MODULES_DIR}/message_private
+ matrix:
+ - TEST_SUITE=PHP_CodeSniffer
+ - TEST_SUITE=8.5.x
+# - TEST_SUITE=8.6.x
+# - TEST_SUITE=8.7.x
+
+# Only run the coding standards check once.
+matrix:
+ exclude:
+ - php: 5.6
+ env: TEST_SUITE=PHP_CodeSniffer
+# - php: 7.0
+# env: TEST_SUITE=PHP_CodeSniffer
+# - php: 7.1
+# env: TEST_SUITE=PHP_CodeSniffer
+
+mysql:
+ database: message_private
+ username: root
+ encoding: utf8
- # Ensure the PHP environment is ready.
- - phpenv rehash
+before_script:
+# Remove Xdebug as we don't need it and it causes "PHP Fatal error: Maximum
+# function nesting level of '256' reached."
+# We also don't care if that file exists or not on PHP 7.
+- phpenv config-rm xdebug.ini || true
-install:
- # Basic PHP packages.
- - sudo apt-get install -y --force-yes php5-cgi php5-mysql
+# Require the version of Drupal 8 core under test.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || composer require --no-update drupal/core:$TEST_SUITE webflo/drupal-core-require-dev:$TEST_SUITE
- # Move the checked out module into the correct structure.
- - mkdir /tmp/$MODULE_NAME
- - mv * /tmp/$MODULE_NAME/
- - git clone --branch $DRUPAL_VERSION $DRUPAL_REPO drupal --depth 1
- - mv /tmp/$MODULE_NAME drupal/modules/
- - cd drupal/modules
- - git clone --branch $MESSAGE_VERSION $MESSAGE_REPO
- - git clone --branch $MESSAGE_NOTIFY_VERSION $MESSAGE_NOTIFY_REPO
- - git clone --branch $MESSAGE_UI_VERSION $MESSAGE_UI_REPO
- - cd ../
+# PHPUnit 6 is required when running tests on PHP 7.x.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || test ${TRAVIS_PHP_VERSION:0:3} == "5.6" || composer require --no-update --update-with-dependencies --dev phpunit/phpunit:~6
-before_script:
+# Install dependencies.
+- composer install
- # Install Composer dependencies.
- - composer self-update && composer install
+# Create database.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || mysql -e 'CREATE DATABASE message_private'
- # This fixes a fail when install Drupal.
- - echo 'sendmail_path = /bin/true' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+# Symlink the module into the Drupal site.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || mkdir -p $MODULES_DIR
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || ln -s $TRAVIS_BUILD_DIR $MODULE_DIR
- # Mysql might time out for long tests, increase the wait timeout.
- - mysql -e 'SET @@GLOBAL.wait_timeout=1200'
+# Start a web server on port 8888 in the background.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || nohup php -S localhost:8888 --docroot $DRUPAL_DIR > /dev/null 2>&1 &
- # Install Drupal and enable the required modules (including this one).
- - mysql -e 'create database drupal;'
- - cd $TRAVIS_BUILD_DIR/drupal && drush --yes site-install testing --db-url="mysql://root@127.0.0.1/drupal"
- - cd $TRAVIS_BUILD_DIR/drupal && drush --yes en $MODULE_NAME
- - cd $TRAVIS_BUILD_DIR/drupal && drush --yes en simpletest
+# Wait until the web server is responding.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || until curl -s localhost:8888; do true; done > /dev/null
- # Start a web server.
- - drush runserver 127.0.0.1:8080 &
- - until netstat -an 2>/dev/null | grep '8080.*LISTEN'; do true; done
+# Export web server URL for browser tests.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || export SIMPLETEST_BASE_URL=http://localhost:8888
-script:
- # Run code sniffer.
- - phpcs --report=full --standard=Drupal $TRAVIS_BUILD_DIR/drupal/modules/$MODULE_NAME
+# Export database variable for kernel tests.
+- test ${TEST_SUITE} == "PHP_CodeSniffer" || export SIMPLETEST_DB=mysql://root:@127.0.0.1/message_private
- # Run the tests
- - php $TRAVIS_BUILD_DIR/drupal/core/scripts/run-tests.sh --verbose --color --php `which php` --url http://127.0.0.1:8080 "$MODULE_TEST_GROUP" | tee /tmp/test.txt; TEST_EXIT=${PIPESTATUS[0]}; echo $TEST_EXIT
- # Check if we had fails in the run-tests.sh script
- # Exit with the inverted value, because if there are no fails found, it will
- # exit with 1 and for us that is a good thing so invert it to 0. Travis has
- # some issues with the exclamation mark in front so we have to fiddle a bit.
- # Also make the grep case insensitive and fail on run-tests.sh regular fails
- # as well on fatal errors.
- - TEST_OUTPUT=$(! egrep -i "([0-9]+ fails)|(PHP Fatal error)|([0-9]+ exceptions)" /tmp/test.txt > /dev/null)$?; echo $TEST_OUTPUT
- # Exit the build
- - if [ $TEST_EXIT -eq 0 ] && [ $TEST_OUTPUT -eq 0 ]; then exit 0; else exit 1; fi
+script: ${TRAVIS_BUILD_DIR}/scripts/travis-ci/run-tests.sh ${TEST_SUITE}
diff --git a/.travis/apache-vhost.conf b/.travis/apache-vhost.conf
deleted file mode 100644
index 7e91196..0000000
--- a/.travis/apache-vhost.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-
- DocumentRoot %TRAVIS_BUILD_DIR%
-
-
- Options FollowSymLinks MultiViews ExecCGI
- AllowOverride All
- Order deny,allow
- Allow from all
-
-
-
- AddHandler php5-fcgi .php
- Action php5-fcgi /php5-fcgi
- Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
- FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
-
-
diff --git a/README.md b/README.md
index f97ba70..bb0e7d5 100755
--- a/README.md
+++ b/README.md
@@ -13,13 +13,14 @@ CONTENTS OF THIS FILE
INTRODUCTION
------------
A message template and entity reference fields, enabling sending and receiving
-private messages using The Message Stack. Messages of template "Private Message" can
-be sent by creating the private_message message instance with fields referencing
-user entities.
+private messages using The Message Stack. Messages of template "Private Message"
+can be sent by creating the private_message message instance with fields
+referencing user entities.
-The message_private module includes the following.
-+ A message template "Private Message" with entity reference field referencing users
-+ A message view, message_private for "User Messages"
+The message_private module includes the following:
+* A message template "Private Message" with entity reference field referencing
+ users
+* A message view, message_private for "User Messages"
DEPENDENCIES
@@ -39,8 +40,9 @@ INSTALLATION
CONFIGURATION
-------------
-Show notification boolean on user form fields: /admin/config/people/accounts/form-display
-This will be addressed automatically in a hook later.
+Show notification boolean on user form fields:
+`/admin/config/people/accounts/form-display`. This will be addressed
+automatically in a hook later.
HOW TO USE
diff --git a/composer.json b/composer.json
index d72e0e5..c477239 100644
--- a/composer.json
+++ b/composer.json
@@ -1,8 +1,35 @@
{
"name": "drupal/message_private",
- "description": "Message Private",
+ "description": "Private messaging module based on Message stack.",
"type": "drupal-module",
"license": "GPL-2.0+",
"minimum-stability": "dev",
- "require": {}
+ "prefer-stable": true,
+ "homepage": "https://www.drupal.org/project/message_private",
+ "require": {
+ "php": "^5.6|^7.0",
+ "drupal/core": "^8.6",
+ "drupal/message": "^1.0",
+ "drupal/message_notify": "^1.0",
+ "drupal/message_ui": "^1.0"
+ },
+ "require-dev": {
+ "composer/installers": "^1.2",
+ "drupal-composer/drupal-scaffold": "^2.5",
+ "drupal/coder": "^8.3.1",
+ "webflo/drupal-core-require-dev": "~8.5"
+ },
+ "repositories": [
+ {
+ "type": "composer",
+ "url": "https://packages.drupal.org/8"
+ }
+ ],
+ "extra": {
+ "installer-paths": {
+ "../build/core": ["type:drupal-core"],
+ "../build/modules/contrib/{$name}": ["type:drupal-module"],
+ "../build/themes/contrib/{$name}": ["type:drupal-theme"]
+ }
+ }
}
diff --git a/config/optional/message_private.settings.yml b/config/optional/message_private.settings.yml
index 60e5129..0559280 100644
--- a/config/optional/message_private.settings.yml
+++ b/config/optional/message_private.settings.yml
@@ -2,4 +2,4 @@ message_private_message_limit: 0
email_notify: 1
message_add_local_action: 1
default_limit: 0
-default_interval: 0
\ No newline at end of file
+default_interval: 0
diff --git a/message_private.info.yml b/message_private.info.yml
index 5c55bc8..0511853 100644
--- a/message_private.info.yml
+++ b/message_private.info.yml
@@ -9,4 +9,3 @@ dependencies:
- message
- message_notify
- message_ui
-
diff --git a/message_private.install b/message_private.install
index 84078a6..2d4ac58 100644
--- a/message_private.install
+++ b/message_private.install
@@ -1,20 +1,21 @@
'user',
'bundle' => 'user',
'include_deleted' => TRUE,
- );
+ ];
// Get the fields based on the above properties.
$fields = \Drupal::entityManager()->getStorage('field_config')->loadByProperties($properties);
@@ -23,7 +24,7 @@ function message_private_uninstall() {
foreach ($fields as $field) {
/* @var \Drupal\Core\Field\FieldConfigBase $field */
// If we have the user notify field, purge the data and remove.
- if(!empty($field->getName() == 'field_message_private_usr_notify')) {
+ if (!empty($field->getName() == 'field_message_private_usr_notify')) {
// Purge previously deleted field tables for entity type.
Drupal::entityManager()->getStorage($field->getTargetEntityTypeId())->purgeFieldData($field, 100);
field_cron();
diff --git a/message_private.links.task.yml b/message_private.links.task.yml
index 721bd98..bbd2892 100644
--- a/message_private.links.task.yml
+++ b/message_private.links.task.yml
@@ -18,4 +18,3 @@ message_private.messages.sent:
# Provide dynamic local tasks.
message_private.messages:
deriver: 'Drupal\message_private\Plugin\Derivative\DynamicLocalTasks'
-
diff --git a/message_private.module b/message_private.module
index 7b03ecd..5b02abf 100755
--- a/message_private.module
+++ b/message_private.module
@@ -1,19 +1,23 @@
moduleExists('markdown') ? \Drupal\Component\Utility\Xss::filterAdmin(\Drupal::moduleHandler()->invoke('markdown', 'filter', ['process', 0, -1, $output])) : '
Message Private README
' . \Drupal\Component\Utility\Html::escape($output) . '
';
+ $module_hander = \Drupal::moduleHandler();
+ return $module_hander->moduleExists('markdown') ? Xss::filterAdmin($module_hander->invoke('markdown', 'filter', [
+ 'process',
+ 0,
+ -1,
+ $output,
+ ])) : 'Message Private README
' . Html::escape($output) . '
';
}
}
@@ -110,7 +119,12 @@ function message_private_message_access(EntityInterface $message, $operation, Ac
* @return bool
* TRUE if the user is allowed perform the operation, FALSE otherwise.
*/
-// @todo: code as Access class & associate service entry to local task/actions.
+
+/**
+ * Provides an access callback.
+ *
+ * @todo: code as Access class & associate service entry to local task/actions.
+ */
function message_private_access_callback($message) {
if ($message->template == 'private_message') {
return \Drupal::currentUser()->hasPermission('bypass private message access control') || \Drupal::currentUser()->hasPermission('view a private_message message instance');
@@ -124,25 +138,30 @@ function message_private_access_callback($message) {
* This function is defined to override that provided by Message UI module. This
* allows override specific values of the form such as the cancel link. It hides
* the message_text on the edit and create form, and adds custom validation.
+ *
+ * @todo - check form ID is matching D8 form id.
*/
-// @todo - check form ID is matching D8 form id.
function message_private_form_message_private_message_form_alter(&$form, FormStateInterface $form_state) {
_message_private_message_form_alter($form, $form_state);
}
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
function message_private_form_message_private_message_edit_form_alter(&$form, FormStateInterface $form_state) {
_message_private_message_form_alter($form, $form_state);
}
-/*
- * Helper function to modify message form
+/**
+ * Helper function to modify message form.
*/
-function _message_private_message_form_alter(&$form, FormStateInterface $form_state){
+function _message_private_message_form_alter(&$form, FormStateInterface $form_state) {
$entity = $form_state->getFormObject()->getEntity();
if ($entity->bundle() == 'private_message') {
$form['field_message_private_to_user']['widget']['add_more']['#value'] = new TranslatableMarkup('Add another user');
if (isset($form['text']['#type'])) {
- $form['text']['#type'] = 'hidden'; // @todo - is this necessary now?
+ // @todo - is this necessary now?
+ $form['text']['#type'] = 'hidden';
}
// @todo - owner access and validation callback needs testing.
$form['owner']['#access'] = \Drupal::currentUser()->hasPermission('bypass private message access control');
@@ -159,7 +178,12 @@ function _message_private_message_form_alter(&$form, FormStateInterface $form_st
* @param mixed $form_state
* The form state including values submitted.
*/
-// @todo - test this is called and if form should be passed by reference.
+
+/**
+ * Provides a validation callback.
+ *
+ * @todo - test this is called and if form should be passed by reference.
+ */
function message_private_form_message_private_message_form_validate(&$form, FormStateInterface $form_state) {
// If there is an imposed message limit set in the admin settings interface.
// The correct configuration object could not be determined. You'll need to
@@ -187,10 +211,10 @@ function message_private_form_message_private_message_form_validate(&$form, Form
// Get total amount of this user's messages since last interval.
$query = \Drupal::entityQuery('message');
$total = $query->condition('template', 'private_message')
- ->condition('timestamp', $interval_timestamp, '>')
- ->condition('uid', $user->id())
- ->count()
- ->execute();
+ ->condition('timestamp', $interval_timestamp, '>')
+ ->condition('uid', $user->id())
+ ->count()
+ ->execute();
// Display error preventing message create when total messages over limit.
if ($total >= $limit) {
@@ -208,7 +232,7 @@ function message_private_form_message_private_message_form_validate(&$form, Form
* this may be an issue with the message module itself as I don't
* think escaping strings for email should be done in this module.
*/
-function message_private_message_insert(\Drupal\message\MessageInterface $message) {
+function message_private_message_insert(MessageInterface $message) {
// Prepare message notifications for private messages if notifications are on.
// The correct configuration object could not be determined. You'll need to
// rewrite this call manually.
@@ -219,12 +243,12 @@ function message_private_message_insert(\Drupal\message\MessageInterface $messag
// function message_notify_send_message tries to re-save as a new message.
$message = Message::load($message->id());
- $mail = array();
+ $mail = [];
$users = $message->get('field_message_private_to_user');
if (!empty($users)) {
// Make users an array if user ref field is configured to 1 entry.
- $users = is_array($users) ? $users : array($users);
+ $users = is_array($users) ? $users : [$users];
foreach ($users as $user) {
$notify = $user->get('field_private_message_notify');
if (!empty($notify) && is_array($notify)) {
@@ -241,7 +265,7 @@ function message_private_message_insert(\Drupal\message\MessageInterface $messag
/* @var \Drupal\message_notify\MessageNotifier $message_notifier */
$message_notifier = \Drupal::service('message_notify.sender');
// @todo - figure out how to pass the email addresses to the notify plugin / hook.
- $message_notifier->send($message, array('mail' => implode(',', $mail), 'email'));
+ $message_notifier->send($message, ['mail' => implode(',', $mail), 'email']);
}
}
}
@@ -251,8 +275,9 @@ function message_private_message_insert(\Drupal\message\MessageInterface $messag
*
* If email notifications are disabled, hide the per user setting on user
* profiles, unless the user is in role with bypass access control permission.
+ *
+ * @todo - check form ID matches D8 form id & add config for user notify field.
*/
-// @todo - check form ID matches D8 form id & add config for user notify field.
function message_private_form_user_profile_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// The correct configuration object could not be determined. You'll need to
// rewrite this call manually.
@@ -264,30 +289,32 @@ function message_private_form_user_profile_form_alter(&$form, FormStateInterface
/**
* Implements hook_theme().
+ *
+ * @todo - Is this still required in D8 to make twig template discoverable?
*/
-// @todo - Is this still required in D8 to make twig template discoverable?
function message_private_theme() {
- return array(
- 'message_private' => array(
+ return [
+ 'message_private' => [
'render element' => 'elements',
'template' => 'message--private_message',
'base hook' => 'message_private',
- ),
- // Template is discoverable if the theme name is the same as the template with '_' instead of '-'
- 'message_private__inbox' => array(
- 'variables' => array('messages' => array()),
- ),
- 'message_private__sent' => array(
- 'variables' => array('messages' => array()),
- ),
- );
+ ],
+ // Template is discoverable if the theme name is the same as the template
+ // with '_' instead of '-'.
+ 'message_private__inbox' => [
+ 'variables' => ['messages' => []],
+ ],
+ 'message_private__sent' => [
+ 'variables' => ['messages' => []],
+ ],
+ ];
}
-
/**
* Implements hook_message_view_alter().
+ *
+ * @todo - Is this still required in D8 to make twig template discoverable?
*/
-// @todo - Is this still required in D8 to make twig template discoverable?
function message_private_message_view_alter(&$build) {
// Use template_preprocess_message_private for private_message messages only.
if (!empty($build['#bundle']) && $build['#bundle'] == 'private_message') {
@@ -297,8 +324,9 @@ function message_private_message_view_alter(&$build) {
/**
* Process variables for message--private_message.html.twig.
+ *
+ * @todo - Is there a better alternative to this?
*/
-// @todo - Is there a better alternative to this?
function template_preprocess_message_private(&$variables) {
// Call the parent message template function defined in message module.
if (function_exists('template_preprocess_message')) {
@@ -312,19 +340,18 @@ function template_preprocess_message_private(&$variables) {
if (!empty($message) && $uid = $message->uid) {
$variables['date'] = format_date($message->timestamp);
// @FIXME
-// theme() has been renamed to _theme() and should NEVER be called directly.
-// Calling _theme() directly can alter the expected output and potentially
-// introduce security issues (see https://www.drupal.org/node/2195739). You
-// should use renderable arrays instead.
-//
-//
-// @see https://www.drupal.org/node/2195739
-// $variables['name'] = theme('username', array('account' => user_load($uid)));
-
- $variables['submitted'] = t('Sent by !username on !datetime', array(
- '!username' => $variables['name'],
- '!datetime' => $variables['date'],
- ));
+ // theme() has been renamed to _theme() and should NEVER be called directly.
+ // Calling _theme() directly can alter the expected output and potentially
+ // introduce security issues (see https://www.drupal.org/node/2195739). You
+ // should use renderable arrays instead.
+ //
+ //
+ // @see https://www.drupal.org/node/2195739
+ // $variables['name'] = theme('username', ['account' => user_load($uid)]);
+ $variables['submitted'] = t('Sent by !username on !datetime', [
+ '!username' => $variables['name'],
+ '!datetime' => $variables['date'],
+ ]);
}
}
@@ -339,10 +366,11 @@ function template_preprocess_message_private(&$variables) {
*
* @return mixed
* Either a role id or null.
+ *
+ * @todo - Is there a better location for this?
*/
-// @todo - Is there a better location for this?
function _message_private_max_message_limit_role($roles) {
- $limits = array();
+ $limits = [];
// The correct configuration object could not be determined. You'll need to
// rewrite this call manually.
@@ -371,7 +399,6 @@ function _message_private_max_message_limit_role($roles) {
// rewrite this call manually.
$limit = \Drupal::config('message_private.settings')->get($limit_name);
-
// Ensure we have existing valid numerical values for both variables.
if (!empty($limit) && ctype_digit($limit) && !empty($interval) && ctype_digit($interval)) {
$limits[$rid] = $interval / $limit;
@@ -385,6 +412,7 @@ function _message_private_max_message_limit_role($roles) {
* Views Plugin access callback.
*
* @return \Drupal\Core\Access\AccessResult
+ * The access result object.
*/
function _message_private_inbox_access() {
$account = \Drupal::currentUser();
@@ -396,36 +424,38 @@ function _message_private_inbox_access() {
return AccessResult::allowed();
}
- // Allow if the user has the bypass permission
+ // Allow if the user has the bypass permission.
return AccessResult::allowedIfHasPermission($account, 'bypass private message access control');
}
-
-function message_private_entity_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {
+/**
+ * Implements hook_entity_view_alter().
+ */
+function message_private_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
if ($entity->bundle() === 'private_message') {
if ($build['#view_mode'] == 'inbox') {
$component = $display->getComponent('author');
- // Add the author field
+ // Add the author field.
$author = User::load($entity->get('uid')->getValue()[0]['target_id']);
- $build['author'] = array(
+ $build['author'] = [
'#type' => 'link',
'#url' => $author->toUrl(),
'#title' => $author->getDisplayName(),
'#weight' => $component['weight'],
- '#attributes' => array(
- 'class' => array('message-private-author')
- )
+ '#attributes' => [
+ 'class' => ['message-private-author'],
+ ],
- );
+ ];
$created = $entity->getCreatedTime();
$component = $display->getComponent('created');
$build['created'] = [
- '#markup' => 'Hello
' . \Drupal::service('date.formatter')->format($created, 'date_text'),
- '#weight'=> $component['weight']
+ '#markup' => 'Hello
' . \Drupal::service('date.formatter')->format($created, 'date_text'),
+ '#weight' => $component['weight'],
];
}
@@ -450,3 +480,13 @@ function message_private_entity_extra_field_info() {
];
return $extra_fields;
}
+
+/**
+ * Implements hook_entity_type_alter().
+ */
+function message_private_entity_type_alter(array &$entity_types) {
+
+ // Set the access class for message to our module version.
+ $entity_types['message']
+ ->setAccessClass('default', 'Drupal\message_private\MessagePrivateAccessControlHandler');
+}
diff --git a/phpcs-ruleset.xml.dist b/phpcs-ruleset.xml.dist
new file mode 100644
index 0000000..c32ebc3
--- /dev/null
+++ b/phpcs-ruleset.xml.dist
@@ -0,0 +1,20 @@
+
+
+
+
+Drupal coding standard for contributed modules
+
+
+*.gif
+*.less
+*.png
+
+
+*.min.css
+*.min.js
+
+
+
+
+
+
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..cb63668
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,10 @@
+
+
+ Default PHP CodeSniffer configuration for Drupal modules.
+
+
+
+
+ .
+ ./vendor
+
diff --git a/scripts/travis-ci/run-tests.sh b/scripts/travis-ci/run-tests.sh
new file mode 100755
index 0000000..58ca5c5
--- /dev/null
+++ b/scripts/travis-ci/run-tests.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Run either PHPUnit tests or PHP_CodeSniffer tests on Travis CI, depending
+# on the passed in parameter.
+
+mysql_to_ramdisk() {
+ sudo service mysql stop
+ sudo mv /var/lib/mysql /var/run/tmpfs
+ sudo ln -s /var/run/tmpfs /var/lib/mysql
+ sudo service mysql start
+}
+
+case "$1" in
+ PHP_CodeSniffer)
+ cd ${TRAVIS_BUILD_DIR}/
+ ./vendor/bin/phpcs
+ exit $?
+ ;;
+ 8.*.x)
+ mysql_to_ramdisk
+ cd ${TRAVIS_BUILD_DIR}/
+ ls -la
+ ls -la ../build/modules/contrib/
+ ./vendor/bin/phpunit -c ${DRUPAL_DIR}/core ./tests
+ exit $?
+ ;;
+ *)
+ echo "Unknown test '$1'"
+ exit 1
+esac
diff --git a/src/Controller/MessagePrivateController.php b/src/Controller/MessagePrivateController.php
index 2121b27..ca656c7 100644
--- a/src/Controller/MessagePrivateController.php
+++ b/src/Controller/MessagePrivateController.php
@@ -3,11 +3,8 @@
namespace Drupal\message_private\Controller;
use Drupal\Core\Url;
-use Drupal\user\entity\User;
use Drupal\Core\Controller\ControllerBase;
-use Drupal\message\Entity\Message;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
-use Drupal\message\MessageTemplateInterface;
/**
* Controller for viewing private messages.
@@ -37,36 +34,35 @@ public function __construct() {
}
/**
- * Generates output of all messages sent to the current user
+ * Generates output of all messages sent to the current user.
*
- *
- * @return
+ * @return array
* A render array for a list of the messages;
*/
public function inBox($user) {
- $messages = array();
+ $messages = [];
// Get messages sent to the current user
// Return build array.
if (!empty($messages)) {
- return array(
+ return [
'#theme' => 'message_private__inbox',
- '#messages' => $messages
- );
+ '#messages' => $messages,
+ ];
}
else {
$url = Url::fromRoute('message.template_add');
- return array(
- '#markup' => 'You have no messages in your inbox. Try sending a message to someone sending a message to someone.'
- );
+ return [
+ '#markup' => 'You have no messages in your inbox. Try sending a message to someone sending a message to someone.',
+ ];
}
}
/**
* Generates form output for adding a new message entity of message_template.
*
- * @param \Drupal\message\MessageTemplateInterface $message_template
- * The message template object.
+ * @param mixed $user
+ * TBD.
*
* @return array
* An array as expected by drupal_render().
@@ -74,18 +70,17 @@ public function inBox($user) {
public function sent($user) {
// Return build array.
if (!empty($messages)) {
- return array(
+ return [
'#theme' => 'message_private__inbox',
- '#messages' => $messages
- );
+ '#messages' => $messages,
+ ];
}
else {
$url = Url::fromRoute('message.template_add');
- return array(
- '#markup' => 'You have no messages in your inbox. Try sending a message to someone sending a message to someone.'
- );
+ return [
+ '#markup' => 'You have no messages in your inbox. Try sending a message to someone sending a message to someone.',
+ ];
}
}
-
}
diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index a4587d5..7c66606 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -1,9 +1,4 @@
$this->t('Enter a message limit') . ' ' . MESSAGE_PRIVATE_MESSAGE_LIMIT_MIN . ' - ' . MESSAGE_PRIVATE_MESSAGE_LIMIT_MAX,
];
-
- $form['interval_limit'][MESSAGE_PRIVATE_DEFAULT_INDEX]['default_interval'] = [
- '#type' => 'textfield',
- '#title' => $this->t('Interval'),
- '#default_value' => $config->get('default_interval'),
- '#description' => $this->t('Enter an interval in minutes') . ' ' . MESSAGE_PRIVATE_MESSAGE_INTERVAL_MIN . ' - ' . MESSAGE_PRIVATE_MESSAGE_INTERVAL_MAX,
- ];
-
+ $form['interval_limit'][MESSAGE_PRIVATE_DEFAULT_INDEX]['default_interval'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Interval'),
+ '#default_value' => $config->get('default_interval'),
+ '#description' => $this->t('Enter an interval in minutes') . ' ' . MESSAGE_PRIVATE_MESSAGE_INTERVAL_MIN . ' - ' . MESSAGE_PRIVATE_MESSAGE_INTERVAL_MAX,
+ ];
// Generate variable names for all roles used with get/set in admin form.
foreach (user_roles() as $id => $role) {
@@ -150,26 +142,26 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$limit_name = 'message_private_' . $role_name . '_limit';
$interval_name = 'message_private_' . $role_name . '_interval';
- $form['interval_limit'][$id] = array(
+ $form['interval_limit'][$id] = [
'#type' => 'fieldset',
'#title' => $role->label(),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
- );
+ ];
- $form['interval_limit'][$id][$limit_name] = array(
+ $form['interval_limit'][$id][$limit_name] = [
'#type' => 'textfield',
'#title' => $this->t('Limit'),
'#default_value' => $config->get($limit_name),
'#description' => $this->t('Enter a message limit') . ' ' . MESSAGE_PRIVATE_MESSAGE_LIMIT_MIN . ' - ' . MESSAGE_PRIVATE_MESSAGE_LIMIT_MAX,
- );
+ ];
- $form['interval_limit'][$id][$interval_name] = array(
+ $form['interval_limit'][$id][$interval_name] = [
'#type' => 'textfield',
'#title' => $this->t('Interval'),
'#default_value' => $config->get($interval_name),
'#description' => $this->t('Enter an interval in minutes') . ' ' . MESSAGE_PRIVATE_MESSAGE_INTERVAL_MIN . ' - ' . MESSAGE_PRIVATE_MESSAGE_INTERVAL_MAX,
- );
+ ];
}
return parent::buildForm($form, $form_state);
@@ -236,9 +228,10 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
- * Validate limit and interval values and show any errors on the form elements.
+ * Validate limit and interval values and show any errors on form elements.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
+ * The form state object.
* @param mixed $limit_element
* Limit form element reference.
* @param mixed $interval_element
@@ -259,7 +252,7 @@ private function validateFieldset(FormStateInterface $form_state, &$limit_elemen
}
// Check is numeric and between the boundaries.
if (!ctype_digit($interval) || $interval > MESSAGE_PRIVATE_MESSAGE_INTERVAL_MAX || $interval < MESSAGE_PRIVATE_MESSAGE_INTERVAL_MIN) {
- $form_state->setErrorByName($interval_element,
+ $form_state->setErrorByName($interval_element,
$this->t('Enter a numerical interval in minutes between') . ' '
. MESSAGE_PRIVATE_MESSAGE_INTERVAL_MIN . ' - ' . MESSAGE_PRIVATE_MESSAGE_INTERVAL_MAX . '.');
}
@@ -270,4 +263,5 @@ private function validateFieldset(FormStateInterface $form_state, &$limit_elemen
$form_state->setErrorByName($interval_element);
}
}
+
}
diff --git a/src/MessagePrivateAccessControlHandler.php b/src/MessagePrivateAccessControlHandler.php
new file mode 100644
index 0000000..f5f959e
--- /dev/null
+++ b/src/MessagePrivateAccessControlHandler.php
@@ -0,0 +1,64 @@
+hasPermission('administer message private')
+ || $account->hasPermission('bypass private message access control')) {
+ return AccessResult::allowed()->cachePerPermissions();
+ }
+ // Verify that the user can apply the op.
+ if ($account->hasPermission($operation . ' any private message')
+ || $account->hasPermission($operation . ' own private messages', $account)) {
+ if ($operation != 'create') {
+ // Check if the user is message author.
+ /* @var Drupal\message\Entity\message $message */
+ if ($entity->getOwnerId() == $account->id()) {
+ return AccessResult::allowed()->cachePerPermissions();
+ }
+ // Grant view access for recipients of the private message.
+ if ($operation == 'view') {
+ $users = $entity->get('field_message_private_to_user')->getValue();
+ if ($users && is_array($users)) {
+ foreach ($users as $user_ref) {
+ if ($user_ref['target_id'] == $account->id()) {
+ return AccessResult::allowed()->cachePerPermissions();
+ }
+ }
+ }
+ }
+ // Deny if user is not message author or viewing recipient.
+ return AccessResult::forbidden()->cachePerPermissions();
+ }
+ else {
+ return AccessResult::allowed()->cachePerPermissions();
+ }
+ }
+ // Unknown operation, no opinion.
+ return AccessResult::neutral();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+ return AccessResult::allowedIfHasPermission($account, 'create a private message');
+ }
+
+}
diff --git a/src/Plugin/Block/MessageHistory.php b/src/Plugin/Block/MessageHistory.php
index 928556b..8894e39 100644
--- a/src/Plugin/Block/MessageHistory.php
+++ b/src/Plugin/Block/MessageHistory.php
@@ -8,7 +8,7 @@
use Drupal\Core\Extension\ModuleHandler;
/**
- * Provides a 'Message History' Block with links to all new messages
+ * Provides a 'Message History' Block with links to all new messages.
*
* @Block(
* id = "message_private_new_message",
@@ -18,7 +18,7 @@
class MessageHistory extends BlockBase implements ContainerFactoryPluginInterface {
/**
- * The module handler
+ * The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandler
*/
@@ -41,7 +41,6 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
$this->moduleHandler = $module_handler;
}
-
/**
* {@inheritdoc}
*/
@@ -66,32 +65,35 @@ public function build() {
foreach ($result as $row) {
$children[$row->mid] = [
'New message' => [
- '#markup' => ''. $row->name . '',
+ '#markup' => '' . $row->name . '',
'#wrapper_attributes' => [
'class' => ['message-history-item'],
],
- ]
+ ],
];
}
if (empty($children)) {
return [
- '#markup' => t('You have no new messages')
+ '#markup' => t('You have no new messages'),
];
}
$items[] = [
'#theme' => 'item_list',
'#items' => $children,
'#cache' => [
- 'max-age' => 0
- ]
+ 'max-age' => 0,
+ ],
];
return $items;
}
+ /**
+ * TBD.
+ */
protected function getUnreadMessages() {
- // Find messages for the current user
+ // Find messages for the current user.
return db_query("SELECT mfd.mid, mfd.uid, ufd.name
FROM {message_field_data} mfd
LEFT JOIN {message__field_message_private_to_user} pu
@@ -106,14 +108,17 @@ protected function getUnreadMessages() {
AND pu.field_message_private_to_user_target_id = :uid
AND mfd.created > :limit
AND mfd.uid != :uid", [
- ':uid' => \Drupal::currentUser()->id(),
- ':limit' => HISTORY_READ_LIMIT
- ]);
+ ':uid' => \Drupal::currentUser()->id(),
+ ':limit' => HISTORY_READ_LIMIT,
+ ]);
}
+ /**
+ * TBD.
+ */
protected function messageHistoryModuleRequired() {
return [
- '#markup' => t('Enable Message History Module to display New Messages block')
+ '#markup' => t('Enable Message History Module to display New Messages block'),
];
}
diff --git a/src/Plugin/Derivative/DynamicLocalTasks.php b/src/Plugin/Derivative/DynamicLocalTasks.php
index 3368765..1210373 100644
--- a/src/Plugin/Derivative/DynamicLocalTasks.php
+++ b/src/Plugin/Derivative/DynamicLocalTasks.php
@@ -1,21 +1,17 @@
derivatives['message_private.messages']['route_name'] = 'message_private.user.add';
return $this->derivatives;
}
+
}
diff --git a/src/Plugin/views/access/InboxPermission.php b/src/Plugin/views/access/InboxPermission.php
index 93a6d56..ab49c11 100644
--- a/src/Plugin/views/access/InboxPermission.php
+++ b/src/Plugin/views/access/InboxPermission.php
@@ -1,10 +1,5 @@
setRequirement('_custom_access', '_message_private_inbox_access');
}
+ /**
+ * TBD.
+ */
public function summaryTitle() {
return $this->t('InboxPermission');
}
diff --git a/tests/src/Functional/MessagePrivatePermissions.php b/tests/src/Functional/MessagePrivatePermissionsTests.php
similarity index 72%
rename from tests/src/Functional/MessagePrivatePermissions.php
rename to tests/src/Functional/MessagePrivatePermissionsTests.php
index 7c67c35..03dc118 100644
--- a/tests/src/Functional/MessagePrivatePermissions.php
+++ b/tests/src/Functional/MessagePrivatePermissionsTests.php
@@ -1,10 +1,5 @@
'Message Private permissions',
- 'description' => 'Testing the use case of message_private_message_access hook.',
- 'group' => 'Message Private',
- );
- }
+ public static $modules = [
+ 'message',
+ 'message_notify',
+ 'message_ui',
+ 'message_private',
+ ];
/**
* {@inheritdoc}
*/
- function setUp() {
+ public function setUp() {
parent::setUp();
$this->accessHandler = \Drupal::entityManager()->getAccessControlHandler('message');
@@ -71,25 +65,30 @@ function setUp() {
/**
* Test private message workflow.
*/
- function testMessageUiPermissions() {
- $this->drupalLogin($this->account); // User login.
- $create_url = '/message/add/private_message'; // Set our create url.
+ public function testMessageUiPermissions() {
+ // User login.
+ $this->drupalLogin($this->account);
+ // Set our create url.
+ $create_url = '/message/add/private_message';
// Verify the user can't create the message.
$this->drupalGet($create_url);
- $this->assertResponse(403); // The user can't create a private message.
+ // The user can't create a private message.
+ $this->assertResponse(403);
// Grant and check create permissions for a message.
$this->grantMessagePrivatePermission('create');
$this->drupalGet($create_url);
// If we get a valid response.
- $this->assertResponse(200); // Check for valid response.
+ // Check for valid response.
+ $this->assertResponse(200);
// Create a message at current page / url.
- $this->drupalPostForm(NULL, array(), t('Save'));
+ $this->drupalPostForm(NULL, [], t('Save'));
- $msg_url = '/message/1'; // Create the message url.
+ // Create the message url.
+ $msg_url = '/message/1';
// Verify the user now can see the text.
$this->grantMessagePrivatePermission('view');
@@ -119,7 +118,7 @@ function testMessageUiPermissions() {
// Grant the permission to the user.
$this->grantMessagePrivatePermission('delete');
- $this->drupalPostForm($msg_url . '/delete', array(), t('Delete'));
+ $this->drupalPostForm($msg_url . '/delete', [], t('Delete'));
// The user can delete a private message.
$this->assertResponse(200);
@@ -132,15 +131,15 @@ function testMessageUiPermissions() {
// The user cannot administer message_private.
$this->assertResponse(403);
- user_role_grant_permissions($this->rid, array('administer message private'));
+ user_role_grant_permissions($this->rid, ['administer message private']);
$this->drupalGet($admin_url);
// The user can administer message_private.
$this->assertResponse(200);
- // Create a new user with the bypass access permission and verify the bypass.
+ // Create a user with the bypass access permission and verify the bypass.
$this->drupalLogout();
- $user = $this->drupalCreateUser(array('bypass private message access control'));
+ $user = $this->drupalCreateUser(['bypass private message access control']);
// Verify the user can by pass the message access control.
$this->drupalLogin($user);
@@ -153,11 +152,11 @@ function testMessageUiPermissions() {
/**
* Grant to the user a specific permission.
*
- * @param $operation
- * The type of operation - create, update, delete or view.
+ * @param string $operation
+ * The type of operation - create, update, delete or view.
*/
private function grantMessagePrivatePermission($operation) {
- user_role_grant_permissions($this->rid, array($operation . ' private_message message'));
+ user_role_grant_permissions($this->rid, [$operation . ' private_message message']);
}
/**
@@ -167,17 +166,17 @@ public function testMessagePrivateAccessHook() {
$this->drupalLogin($this->account);
// Setting up the operation and the expected value from the access callback.
- $permissions = array(
+ $permissions = [
'create' => TRUE,
'view' => TRUE,
'delete' => FALSE,
'update' => FALSE,
- );
+ ];
// Get the message template and create an instance.
$message_template = $this->loadMessageTemplate('private_message');
/* @var $message Message */
- $message = Message::create(array('template' => $message_template->id()));
+ $message = Message::create(['template' => $message_template->id()]);
$message->setOwner($this->account);
$message->save();
@@ -186,12 +185,13 @@ public function testMessagePrivateAccessHook() {
// check which value need to return. If the access control function will
// return the expected value then we know the hook got in action.
$message->{$op} = $value;
- $params = array(
+ $params = [
'@operation' => $op,
'@value' => $value,
- );
+ ];
$this->assertEqual($value, $this->accessHandler->access($message, $op, $this->account), new FormattableMarkup('The hook return @value for @operation', $params));
}
}
+
}
diff --git a/tests/src/Unit/FakeTest.php b/tests/src/Unit/FakeTest.php
new file mode 100644
index 0000000..e6c5aee
--- /dev/null
+++ b/tests/src/Unit/FakeTest.php
@@ -0,0 +1,21 @@
+assertTrue(TRUE);
+ }
+
+}