diff --git a/message_private.module b/message_private.module index b0dfd57..6c87a15 100755 --- a/message_private.module +++ b/message_private.module @@ -100,59 +100,6 @@ function message_private_menu_alter(&$items) { return $items; } -/** - * Override instance list provided by Message UI. - * - * Create links to all message create forms by type, allowing for creation of - * link to custom Private Message create form URI. - * - * @return null|string - * @throws Exception - */ -// @todo - remove in place of getAllowedInstanceList() override in Message UI. -function message_private_create_new_message_instance_list() { - $items = array(); - $allowed_types = message_ui_user_can_create_message(); - - if ($types = message_ui_get_types()) { - foreach ($types as $type => $title) { - if ($allowed_types || (is_array($allowed_types) && $allowed_types[$type])) { - // Create links to message create forms. - if ($type != 'private_message') { - // @FIXME -// l() expects a Url object, created from a route name or external URI. -// $items[] = l($title, 'admin/content/message/create/' . str_replace('_', '-', $type)); - - } - else { - // Create link to customised menu item for private_message create. - // @FIXME -// l() expects a Url object, created from a route name or external URI. -// $items[] = l($title, 'message/create/' . str_replace('_', '-', $type)); - - } - } - } - } - else { - // @FIXME -// url() expects a route name or an external URI. -// return t("There are no messages types. You can create a new message type here.", array('@url' => url('admin/structure/messages/add'))); - - } - - // @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 -// return theme('item_list', array('items' => $items)); - -} - /** * Implements hook_form_FORM_ID_alter(). * diff --git a/message_private.services.yml b/message_private.services.yml index 9b06b0c..786a1f5 100644 --- a/message_private.services.yml +++ b/message_private.services.yml @@ -3,4 +3,13 @@ services: class: Drupal\message_private\Access\MessagePrivateAddAccessCheck arguments: ['@entity.manager'] tags: - - { name: access_check, applies_to: _message_private_add_access } \ No newline at end of file + - { name: access_check, applies_to: _message_private_add_access } + access_check.message_private.edit: + class: Drupal\message_private\Access\MessagePrivateEditAccessCheck + arguments: ['@entity.manager'] + tags: + - { name: access_check, applies_to: _message_private_edit_access } + message_private.route_subscriber: + class: Drupal\message_private\Routing\RouteSubscriber + tags: + - { name: event_subscriber } \ No newline at end of file diff --git a/src/Access/MessagePrivateAddAccessCheck.php b/src/Access/MessagePrivateAddAccessCheck.php index 9743d6a..4705ddc 100644 --- a/src/Access/MessagePrivateAddAccessCheck.php +++ b/src/Access/MessagePrivateAddAccessCheck.php @@ -43,8 +43,8 @@ public function __construct(EntityManagerInterface $entity_manager) { * @param \Drupal\Core\Session\AccountInterface $account * The currently logged in account. * @param \Drupal\message\MessageTypeInterface $message_type - * (optional) The node type. If not specified, access is allowed if there - * exists at least one node type for which the user may create a node. + * (optional) The message type. If not specified, access is allowed if there + * exists at least one message type for which the user may create a message. * * @return string * A \Drupal\Core\Access\AccessInterface constant value. @@ -59,64 +59,13 @@ public function access(AccountInterface $account, MessageTypeInterface $message_ if ($message_type) { return $access_control_handler->createAccess($message_type->id(), $account, [], TRUE); } - // If checking whether a node of any type may be created. + // If checking whether a message of any type may be created. foreach ($this->entityManager->getStorage('message_type')->loadMultiple() as $message_type) { if (($access = $access_control_handler->createAccess($message_type->id(), $account, [], TRUE)) && $access->isAllowed()) { return $access; } } - // @todo: go through the below, previously message_private_access_control(). - /** - if (empty($user_obj)) { - $user = \Drupal::currentUser(); - $account = \Drupal::entityManager()->getStorage('user')->load($user->uid); - } - else { - $user = $user_obj; - $account = \Drupal::entityManager()->getStorage('user')->load($user->uid); - } - - // Get the message type from the function argument or from the message object. - $type = is_object($message) ? $message->type : $message; - - // If this is not a private message then use the message callback provided by - // message_ui module. - if ($type != 'private_message') { - return message_ui_access_control($operation, $message); - } - else { - - if ($account->hasPermission('bypass private message access control')) { - return TRUE; - } - - // Verify that the user can apply the op. - if ($account->hasPermission($operation . ' any message instance') - || $account->hasPermission($operation . ' a ' . $type . ' message instance') - ) { - if ($type == 'private_message' && $operation != 'create') { - // Check if the user is message author. - if ($message->uid == $account->uid) { - return TRUE; - } - $users = field_get_items('message', $message, 'field_message_user_ref'); - if ($users && is_array($users)) { - foreach ($users as $user_ref) { - if ($user_ref['target_id'] == $account->uid) { - return TRUE; - } - } - } - } - else { - return TRUE; - } - } - } - return FALSE; - */ - // No opinion. return AccessResult::neutral(); } diff --git a/src/Access/MessagePrivateEditAccessCheck.php b/src/Access/MessagePrivateEditAccessCheck.php new file mode 100644 index 0000000..5f49563 --- /dev/null +++ b/src/Access/MessagePrivateEditAccessCheck.php @@ -0,0 +1,102 @@ +entityManager = $entity_manager; + } + + /** + * Checks access to the message edit page for the message entity. + * + * @param \Drupal\Core\Session\AccountInterface $account + * The currently logged in account. + * @param \Drupal\message\MessageInterface $message + * + * @return string + * A \Drupal\Core\Access\AccessInterface constant value. + */ + public function access(AccountInterface $account, MessageInterface $message = NULL) { + $access_control_handler = $this->entityManager->getAccessControlHandler('message'); + // If checking whether a node of a particular type may be created. + if ($account->hasPermission('administer message private') + || $account->hasPermission('bypass private message access control')) { + return AccessResult::allowed()->cachePerPermissions(); + } + + // @todo: go through the below, previously message_private_access_control(). + + // Get the message type from the function argument or from the message object. + $type = $message->bundle(); + + // If this is not a private message then use the message callback provided + // by message_ui module. + if ($type != 'private_message') { + // No opinion. + return AccessResult::neutral(); + } + else { + if ($account->hasPermission('bypass private message access control')) { + return TRUE; + } + + $operation = 'edit'; + + // Verify that the user can apply the op. + if ($account->hasPermission($operation . ' any message instance') + || $account->hasPermission($operation . ' a ' . $type . ' message instance') + ) { + if ($type == 'private_message' && $operation != 'create') { + // Check if the user is message author. + /* @var $message \Drupal\message\Entity\Message */ + if ($message->getAuthorId() == $account->id()) { + return TRUE; + } + $users = $message->get('field_message_user_ref'); + if ($users && is_array($users)) { + foreach ($users as $user_ref) { + if ($user_ref['target_id'] == $account->id()) { + return TRUE; + } + } + } + } + else { + return TRUE; + } + } + } + return FALSE; + } +} diff --git a/src/Controller/MessagePrivateController.php b/src/Controller/MessagePrivateController.php new file mode 100644 index 0000000..ac2f7a6 --- /dev/null +++ b/src/Controller/MessagePrivateController.php @@ -0,0 +1,140 @@ +entityManager = \Drupal::entityManager(); + } + + /** + * Display list of message types to create an instance for them. + * + */ + // @todo - remove note: message_ui_create_new_message_instance_list in D7. + public function getAllowedInstanceList() { + // $access_controller = new MessageAccessControlHandler('message'); + // $allowed_types = $access_controller->userCreateMessageAccess(); + + /* + // From D7 message_private instance list override fn: + $items = array(); + $allowed_types = message_ui_user_can_create_message(); + + if ($types = message_ui_get_types()) { + foreach ($types as $type => $title) { + if ($allowed_types || (is_array($allowed_types) && $allowed_types[$type])) { + // Create links to message create forms. + if ($type != 'private_message') { + // @FIXME +// l() expects a Url object, created from a route name or external URI. +// $items[] = l($title, 'admin/content/message/create/' . str_replace('_', '-', $type)); + + } + else { + // Create link to customised menu item for private_message create. + // @FIXME +// l() expects a Url object, created from a route name or external URI. +// $items[] = l($title, 'message/create/' . str_replace('_', '-', $type)); + + } + } + } + } + else { + // @FIXME +// url() expects a route name or an external URI. +// return t("There are no messages types. You can create a new message type here.", array('@url' => url('admin/structure/messages/add'))); + + } + + // @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 +// return theme('item_list', array('items' => $items)); + */ + + // @todo - replace this line with access controlled type list: + $allowed_types = MessageType::loadMultiple(); + + if ($types = MessageType::loadMultiple()) { + foreach ($types as $type) { + if ($allowed_types || (is_array($allowed_types) && array_key_exists($type, $allowed_types))) { + return $allowed_types; + } + } + } + return FALSE; + } + + /** + * Generates output of all message type entities with permission to create. + * + * @return array + * An array as expected by drupal_render(). + */ + public function showTypes() { + // $account = $this->currentUser(); + + // @todo add access control for message_type, see message_ui_access_control. + + $items = array(); + // @todo : Use the following or MessageType's method? $this->entityManager()->getStorage('message_type')->loadMultiple() + // Only use node types the user has access to. + // @todo - override the path for private messages, or is there a better way? + foreach ($this->getAllowedInstanceList() as $type => $entity) { + // @todo - get access control working below. + // \Doctrine\Common\Util\Debug::dump($this->entityManager()->getAccessControlHandler('message')->createAccess($type->id())); + // if ($this->entityManager()->getAccessControlHandler('message')->createAccess($type->id())) { + /* @var $entity MessageType */ + $url = Url::fromUri('internal:/admin/content/messages/create/' . str_replace('_', '-', $type)); + $items[] = array( + 'type' => $type, + 'name' => $entity->label(), + 'internal_link' => \Drupal::l(ucfirst(str_replace('_', ' ', $type)), $url), + ); + //\Doctrine\Common\Util\Debug::dump($content); + // } + } + + // Bypass the admin/content/messages/create listing if only one content type is available. + /* if (count($content) == 1) { + $type = array_shift($content); + return $this->redirect('message_ui.create_message_by_type', array('message_type' => $type->id())); + } */ + + if ($items) { + return array( + '#theme' => 'instance_item_list', + '#items' => $items, + '#type' => 'ul' + ); + } + else { + $url = Url::fromRoute('message.type_add'); + return t("There are no messages types. You can create a new message type here."); + } + } +} diff --git a/src/Routing/RouteSubscriber.php b/src/Routing/RouteSubscriber.php new file mode 100644 index 0000000..7b9e4fb --- /dev/null +++ b/src/Routing/RouteSubscriber.php @@ -0,0 +1,35 @@ +get('message_ui.edit_message'); + if ($route) { + $route->setRequirements(array( + '_message_private_edit_access' => '{message}', + )); + } + $route = $collection->get('message_ui.create_message'); + if ($route) { + // @todo - check for message_type of 'private_message' and if so, set. + // $route->setDefault('controller', '\Drupal\message_private\Controller\MessagePrivateController::showTypes'); + } + } +}