/** * Prepares the link to the profile. * * @param \Drupal\Core\Entity\EntityInterface $profile * The profile entity this field belongs to. * @param ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($profile, ResultRow $values) { if ($profile->access('view')) { $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = 'profile/' . $profile->id(); return $profile->label(); } }
/** * Prepares the link to the node. * * @param \Drupal\Core\Entity\EntityInterface $node * The node entity this field belongs to. * @param ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($node, ResultRow $values) { if ($node->access('view')) { $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = 'node/' . $node->id(); $text = !empty($this->options['text']) ? $this->options['text'] : t('View'); return $text; } }
/** * Prepares the link to the node. * * @param \Drupal\Core\Entity\EntityInterface $node * The node entity this field belongs to. * @param ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($node, ResultRow $values) { if ($node->access('view')) { $this->options['alter']['make_link'] = TRUE; $this->options['alter']['url'] = $node->urlInfo(); $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('View'); return $text; } }
/** * {@inheritdoc} */ protected function renderLink(EntityInterface $entity, ResultRow $values) { if ($entity && $entity->access('update')) { $this->options['alter']['make_link'] = TRUE; $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Edit'); $this->options['alter']['url'] = $entity->urlInfo('edit-form', ['query' => ['destination' => $this->getDestinationArray()]]); return $text; } }
/** * Determines if the user specified has access to report the entity. * * @param \Drupal\core\Entity\EntityInterface $entity * The entity to check access for * @param $form_id string * The form that is protected for this entity. * @param \Drupal\Core\Session\AccountInterface $account * The account to use. If null, use the current user. * * @return \Drupal\Core\Access\AccessResultInterface */ public static function accessReport($entity, $form_id, $account = NULL) { // Check if the user has access to this comment. $result = $entity->access('edit', $account, TRUE)->andIf($entity->access('update', $account, TRUE)); if (!$result->isAllowed()) { return $result; } // Check if this entity type is protected. $form_entity = \Drupal::entityManager()->getStorage('mollom_form')->load($form_id); if (empty($form_entity)) { return new AccessResultForbidden(); } // Check any specific report access callbacks. $forms = FormController::getProtectableForms(); $info = $forms[$form_id]; if (empty($info)) { // Orphan form protection. return new AccessResultForbidden(); } $report_access_callbacks = []; $access_permissions = []; // If there is a 'report access callback' add it to the list. if (isset($info['report access callback']) && function_exists($info['report access callback']) && !in_array($info['report access callback'], $report_access_callbacks)) { $report_access_callbacks[] = $info['report access callback']; } else { if (isset($info['report access']) && !in_array($info['report access'], $access_permissions)) { $access_permissions += $info['report access']; } } foreach ($report_access_callbacks as $callback) { if (!$callback($entity->getEntityTypeId(), $entity->id())) { return new AccessResultForbidden(); } } foreach ($access_permissions as $permission) { if (empty($account)) { $account = \Drupal::currentUser(); } if (!$account->hasPermission($permission)) { return new AccessResultForbidden(); } } return new AccessResultAllowed(); }
/** * {@inheritdoc} */ protected function renderLink(EntityInterface $entity, ResultRow $values) { if ($entity && $entity->access('delete')) { $this->options['alter']['make_link'] = TRUE; $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Cancel account'); $this->options['alter']['url'] = $entity->urlInfo('cancel-form'); $this->options['alter']['query'] = drupal_get_destination(); return $text; } }
/** * {@inheritdoc} */ protected function access() { // Drupal 8 has unified APIs for access checks so this is pretty easy. if (is_object($this->entity)) { $entity_access = $this->entity->access('view'); $field_access = $this->entity->{$this->fieldName}->access('view'); return $entity_access && $field_access; } return FALSE; }
/** * Assert unaccessible items don't change the data of the fields. */ public function testAccess() { $field_name = $this->fieldName; $referencing_entity = entity_create($this->entityType, array('name' => $this->randomMachineName())); $referencing_entity->save(); $referencing_entity->{$field_name}->entity = $this->referencedEntity; // Assert user doesn't have access to the entity. $this->assertFalse($this->referencedEntity->access('view'), 'Current user does not have access to view the referenced entity.'); $formatter_manager = $this->container->get('plugin.manager.field.formatter'); // Get all the existing formatters. foreach ($formatter_manager->getOptions('entity_reference') as $formatter => $name) { // Set formatter type for the 'full' view mode. entity_get_display($this->entityType, $this->bundle, 'default')->setComponent($field_name, array('type' => $formatter))->save(); // Invoke entity view. entity_view($referencing_entity, 'default'); // Verify the un-accessible item still exists. $this->assertEqual($referencing_entity->{$field_name}->target_id, $this->referencedEntity->id(), format_string('The un-accessible item still exists after @name formatter was executed.', array('@name' => $name))); } }
/** * {@inheritdoc} */ protected function renderLink(EntityInterface $entity, ResultRow $values) { if ($entity && $entity->access('update')) { $this->options['alter']['make_link'] = TRUE; $text = !empty($this->options['text']) ? $this->options['text'] : t('Edit'); $this->options['alter']['path'] = $entity->getSystemPath('edit-form'); $this->options['alter']['query'] = drupal_get_destination(); return $text; } }
/** * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity) { // Only check access if the current file access control handler explicitly // opts in by implementing FileAccessFormatterControlHandlerInterface. $access_handler_class = $entity->getEntityType()->getHandlerClass('access'); if (is_subclass_of($access_handler_class, '\\Drupal\\file\\FileAccessFormatterControlHandlerInterface')) { return $entity->access('view', NULL, TRUE); } else { return AccessResult::allowed(); } }
/** * Prepares the link to delete a profile. * * @param \Drupal\Core\Entity\EntityInterface $profile * The profile entity this field belongs to. * @param \Drupal\views\ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($profile, ResultRow $values) { // Ensure user has access to delete this node. if (!$profile->access('delete')) { return; } $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = 'profile/' . $profile->id() . '/delete'; $this->options['alter']['query'] = \Drupal::destination()->getAsArray(); $text = !empty($this->options['text']) ? $this->options['text'] : t('Delete'); return $text; }
/** * Prepares the link to the profile. * * @param \Drupal\Core\Entity\EntityInterface $profile * The profile entity this field belongs to. * @param ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($profile, ResultRow $values) { // Ensure user has access to edit this profile. if (!$profile->access('update')) { return; } $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = "user/" . $profile->getOwnerId() . "/profile/" . $profile->bundle() . "/" . $profile->id(); $this->options['alter']['query'] = \Drupal::destination()->getAsArray(); $text = !empty($this->options['text']) ? $this->options['text'] : t('Edit'); return $text; }
/** * Prepares the link to the node. * * @param \Drupal\Core\Entity\EntityInterface $node * The node entity this field belongs to. * @param ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($node, ResultRow $values) { // Ensure user has access to edit this node. if (!$node->access('update')) { return; } $this->options['alter']['make_link'] = TRUE; $this->options['alter']['url'] = $node->urlInfo('edit-form'); $this->options['alter']['query'] = $this->getDestinationArray(); $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Edit'); return $text; }
/** * Prepares the link to the node. * * @param \Drupal\Core\Entity\EntityInterface $node * The node entity this field belongs to. * @param ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($node, ResultRow $values) { // Ensure user has access to edit this node. if (!$node->access('update')) { return; } $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = "node/" . $node->id() . "/edit"; $this->options['alter']['query'] = drupal_get_destination(); $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Edit'); return $text; }
/** * Prepares the link to delete a node. * * @param \Drupal\Core\Entity\EntityInterface $node * The node entity this field belongs to. * @param \Drupal\views\ResultRow $values * The values retrieved from the view's result set. * * @return string * Returns a string for the link text. */ protected function renderLink($node, ResultRow $values) { // Ensure user has access to delete this node. if (!$node->access('delete')) { return; } $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = $node->getSystemPath('delete-form'); $this->options['alter']['query'] = drupal_get_destination(); $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Delete'); return $text; }
/** * Returns an array of supported actions for the current entity form. * * @todo Consider introducing a 'preview' action here, since it is used by * many entity types. */ protected function actions(array $form, FormStateInterface $form_state) { // @todo Rename the action key from submit to save. $actions['submit'] = array('#type' => 'submit', '#value' => $this->t('Save'), '#validate' => array(array($this, 'validate')), '#submit' => array(array($this, 'submit'), array($this, 'save'))); if (!$this->entity->isNew() && $this->entity->hasLinkTemplate('delete-form')) { $route_info = $this->entity->urlInfo('delete-form'); if ($this->getRequest()->query->has('destination')) { $query = $route_info->getOption('query'); $query['destination'] = $this->getRequest()->query->get('destination'); $route_info->setOption('query', $query); } $actions['delete'] = array('#type' => 'link', '#title' => $this->t('Delete'), '#access' => $this->entity->access('delete'), '#attributes' => array('class' => array('button', 'button--danger'))); $actions['delete'] += $route_info->toRenderArray(); } return $actions; }
/** * Returns an array of supported actions for the current entity form. * * @todo Consider introducing a 'preview' action here, since it is used by * many entity types. */ protected function actions(array $form, FormStateInterface $form_state) { // @todo Consider renaming the action key from submit to save. The impacts // are hard to predict. For example, see // \Drupal\language\Element\LanguageConfiguration::processLanguageConfiguration(). $actions['submit'] = array('#type' => 'submit', '#value' => $this->t('Save'), '#validate' => array('::validate'), '#submit' => array('::submitForm', '::save')); if (!$this->entity->isNew() && $this->entity->hasLinkTemplate('delete-form')) { $route_info = $this->entity->urlInfo('delete-form'); if ($this->getRequest()->query->has('destination')) { $query = $route_info->getOption('query'); $query['destination'] = $this->getRequest()->query->get('destination'); $route_info->setOption('query', $query); } $actions['delete'] = array('#type' => 'link', '#title' => $this->t('Delete'), '#access' => $this->entity->access('delete'), '#attributes' => array('class' => array('button', 'button--danger'))); $actions['delete']['#url'] = $route_info; } return $actions; }
public function create(EntityInterface $entity) { if (!isset($entity->xmlsitemap)) { $entity->xmlsitemap = array(); if ($entity->id() && ($link = $this->load($entity->getEntityTypeId(), $entity->id()))) { $entity->xmlsitemap = $link; } } $settings = xmlsitemap_link_bundle_load($entity->getEntityTypeId(), $entity->bundle()); $uri = $entity->url(); $entity->xmlsitemap += array('type' => $entity->getEntityTypeId(), 'id' => (string) $entity->id(), 'subtype' => $entity->bundle(), 'status' => $settings['status'], 'status_default' => $settings['status'], 'status_override' => 0, 'priority' => $settings['priority'], 'priority_default' => $settings['priority'], 'priority_override' => 0, 'changefreq' => isset($settings['changefreq']) ? $settings['changefreq'] : 0); $url = $entity->url(); // The following values must always be checked because they are volatile. $entity->xmlsitemap['loc'] = $uri; $entity->xmlsitemap['access'] = isset($url) && $entity->access('view', $this->anonymousUser); $language = $entity->language(); $entity->xmlsitemap['language'] = !empty($language) ? $language->getId() : LanguageInterface::LANGCODE_NOT_SPECIFIED; return $entity->xmlsitemap; }
/** * Responds to entity GET requests. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object. * * @return \Drupal\rest\ResourceResponse * The response containing the entity with its accessible fields. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function get(EntityInterface $entity) { if (!$entity->access('view')) { throw new AccessDeniedHttpException(); } $fields = $entity->getFields(); $display_id = $entity->getEntityTypeId() . '.' . $entity->bundle() . '.restx'; // Remove hidden fields (Display mode 'default'). $view_display = \Drupal::entityManager()->getStorage('entity_view_display')->load($display_id); if ($view_display) { $content = $view_display->get('content'); foreach ($fields as $field_name => $field) { if (!$field->access('view') || substr($field_name, 0, 6) === 'field_' && !isset($content[$field_name])) { unset($fields[$field_name]); } } } $output = array('data' => $fields); $response = new ResourceResponse($output, ResourceResponse::HTTP_OK); $response->addCacheableDependency($output); return $response; }
/** * Form constructor for the comment reply form. * * There are several cases that have to be handled, including: * - replies to comments * - replies to entities * - attempts to reply to entities that can no longer accept comments * - respecting access permissions ('access comments', 'post comments', * etc.) * * @param \Symfony\Component\HttpFoundation\Request $request * The current request object. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity this comment belongs to. * @param string $field_name * The field_name to which the comment belongs. * @param int $pid * (optional) Some comments are replies to other comments. In those cases, * $pid is the parent comment's comment ID. Defaults to NULL. * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException * @return array|\Symfony\Component\HttpFoundation\RedirectResponse * One of the following: * An associative array containing: * - An array for rendering the entity or parent comment. * - comment_entity: If the comment is a reply to the entity. * - comment_parent: If the comment is a reply to another comment. * - comment_form: The comment form as a renderable array. * - A redirect response to current node: * - If user is not authorized to post comments. * - If parent comment doesn't belong to current entity. * - If user is not authorized to view comments. * - If current entity comments are disable. */ public function getReplyForm(Request $request, EntityInterface $entity, $field_name, $pid = NULL) { // Check if entity and field exists. $fields = $this->commentManager->getFields($entity->getEntityTypeId()); if (empty($fields[$field_name])) { throw new NotFoundHttpException(); } $account = $this->currentUser(); $uri = $entity->urlInfo()->setAbsolute(); $build = array(); // Check if the user has the proper permissions. if (!$account->hasPermission('post comments')) { drupal_set_message($this->t('You are not authorized to post comments.'), 'error'); return new RedirectResponse($uri->toString()); } // The user is not just previewing a comment. if ($request->request->get('op') != $this->t('Preview')) { $status = $entity->{$field_name}->status; if ($status != CommentItemInterface::OPEN) { drupal_set_message($this->t("This discussion is closed: you can't post new comments."), 'error'); return new RedirectResponse($uri->toString()); } // $pid indicates that this is a reply to a comment. if ($pid) { // Check if the user has the proper permissions. if (!$account->hasPermission('access comments')) { drupal_set_message($this->t('You are not authorized to view comments.'), 'error'); return new RedirectResponse($uri->toString()); } // Load the parent comment. $comment = $this->entityManager()->getStorage('comment')->load($pid); // Check if the parent comment is published and belongs to the entity. if (!$comment->isPublished() || $comment->getCommentedEntityId() != $entity->id()) { drupal_set_message($this->t('The comment you are replying to does not exist.'), 'error'); return new RedirectResponse($uri->toString()); } // Display the parent comment. $build['comment_parent'] = $this->entityManager()->getViewBuilder('comment')->view($comment); } elseif ($entity->access('view', $account)) { // We make sure the field value isn't set so we don't end up with a // redirect loop. $entity = clone $entity; $entity->{$field_name}->status = CommentItemInterface::HIDDEN; // Render array of the entity full view mode. $build['commented_entity'] = $this->entityManager()->getViewBuilder($entity->getEntityTypeId())->view($entity, 'full'); unset($build['commented_entity']['#cache']); } } else { $build['#title'] = $this->t('Preview comment'); } // Show the actual reply box. $comment = $this->entityManager()->getStorage('comment')->create(array('entity_id' => $entity->id(), 'pid' => $pid, 'entity_type' => $entity->getEntityTypeId(), 'field_name' => $field_name)); $build['comment_form'] = $this->entityFormBuilder()->getForm($comment); return $build; }
/** * {@inheritdoc} */ public function accessEditEntityField(EntityInterface $entity, $field_name) { return $entity->access('update', NULL, TRUE)->andIf($entity->get($field_name)->access('edit', NULL, TRUE)); }
/** * Responds to entity DELETE requests. * * @Thruway(name = "remove", type="procedure") * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object. * * @return array * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function delete(EntityInterface $entity) { if (!$entity->access('delete')) { throw new AccessDeniedHttpException(); } try { $entity->enforceIsNew(FALSE); $entity->delete(); // $this->logger->notice( // 'Deleted entity %type with ID %id.', // array('%type' => $entity->getEntityTypeId(), '%id' => $entity->id()) // ); // Delete responses have an empty body. return $entity; } catch (EntityStorageException $e) { throw new HttpException(500, t('Internal Server Error'), $e); } }
/** * Responds to entity DELETE requests. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object. * * @return \Drupal\rest\ResourceResponse * The HTTP response object. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function delete(EntityInterface $entity) { if (!$entity->access('delete')) { throw new AccessDeniedHttpException(); } try { $entity->delete(); $this->logger->notice('Deleted entity %type with ID %id.', array('%type' => $entity->getEntityTypeId(), '%id' => $entity->id())); // Delete responses have an empty body. return new ResourceResponse(NULL, 204); } catch (EntityStorageException $e) { throw new HttpException(500, 'Internal Server Error', $e); } }
/** * Form constructor for the comment reply form. * * There are several cases that have to be handled, including: * - replies to comments * - replies to entities * * @param \Symfony\Component\HttpFoundation\Request $request * The current request object. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity this comment belongs to. * @param string $field_name * The field_name to which the comment belongs. * @param int $pid * (optional) Some comments are replies to other comments. In those cases, * $pid is the parent comment's comment ID. Defaults to NULL. * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException * @return array|\Symfony\Component\HttpFoundation\RedirectResponse * An associative array containing: * - An array for rendering the entity or parent comment. * - comment_entity: If the comment is a reply to the entity. * - comment_parent: If the comment is a reply to another comment. * - comment_form: The comment form as a renderable array. */ public function getReplyForm(Request $request, EntityInterface $entity, $field_name, $pid = NULL) { $account = $this->currentUser(); $uri = $entity->urlInfo()->setAbsolute(); $build = array(); // The user is not just previewing a comment. if ($request->request->get('op') != $this->t('Preview')) { // $pid indicates that this is a reply to a comment. if ($pid) { // Load the parent comment. $comment = $this->entityManager()->getStorage('comment')->load($pid); // Display the parent comment. $build['comment_parent'] = $this->entityManager()->getViewBuilder('comment')->view($comment); } elseif ($entity->access('view', $account)) { // We make sure the field value isn't set so we don't end up with a // redirect loop. $entity = clone $entity; $entity->{$field_name}->status = CommentItemInterface::HIDDEN; // Render array of the entity full view mode. $build['commented_entity'] = $this->entityManager()->getViewBuilder($entity->getEntityTypeId())->view($entity, 'full'); unset($build['commented_entity']['#cache']); } } else { $build['#title'] = $this->t('Preview comment'); } // Show the actual reply box. $comment = $this->entityManager()->getStorage('comment')->create(array('entity_id' => $entity->id(), 'pid' => $pid, 'entity_type' => $entity->getEntityTypeId(), 'field_name' => $field_name)); $build['comment_form'] = $this->entityFormBuilder()->getForm($comment); return $build; }
/** * {@inheritdoc} */ protected function entitySaveAccess(EntityInterface $entity) { if ($this->configuration['authorize'] && !empty($entity->uid->value)) { // If the uid was mapped directly, rather than by email or username, it // could be invalid. if (!($account = $entity->uid->entity)) { $message = 'User %uid is not a valid user.'; throw new EntityAccessException(String::format($message, array('%uid' => $entity->uid->value))); } $op = $entity->isNew() ? 'create' : 'update'; if (!$entity->access($op, $account)) { $args = array('%name' => $account->getUsername(), '%op' => $op, '@bundle' => Unicode::strtolower($this->bundleLabel()), '%bundle' => $entity->bundle()); throw new EntityAccessException(String::format('User %name is not authorized to %op @bundle %bundle.', $args)); } } }
/** * Gets this list's default operations. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity the operations are for. * * @return array * The array structure is identical to the return value of * self::getOperations(). */ protected function getDefaultOperations(EntityInterface $entity) { $operations = array(); if ($entity->access('update') && $entity->hasLinkTemplate('edit-form')) { $operations['edit'] = array('title' => $this->t('Edit'), 'weight' => 10, 'url' => $entity->urlInfo('edit-form')); } if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) { $operations['delete'] = array('title' => $this->t('Delete'), 'weight' => 100, 'url' => $entity->urlInfo('delete-form')); } return $operations; }
/** * Validates an individual entity against class access settings. * * @param \Drupal\Core\Entity\EntityInterface $entity * * @return bool * True if validated. */ protected function validateEntity(EntityInterface $entity) { // If access restricted by entity operation. if ($this->options['access'] && !$entity->access($this->options['operation'])) { return FALSE; } // If restricted by bundle. $bundles = $this->options['bundles']; if (count($bundles) && empty($bundles[$entity->bundle()])) { return FALSE; } return TRUE; }
/** * {@inheritdoc} */ protected function entitySaveAccess(EntityInterface $entity) { // No need to authorize. if (!$this->configuration['authorize'] || !$entity instanceof EntityOwnerInterface) { return; } // If the uid was mapped directly, rather than by email or username, it // could be invalid. if (!($account = $entity->getOwner())) { throw new EntityAccessException($this->t('Invalid user mapped to %label.', ['%label' => $entity->label()])); } // We don't check access for anonymous users. if ($account->isAnonymous()) { return; } $op = $entity->isNew() ? 'create' : 'update'; // Access granted. if ($entity->access($op, $account)) { return; } $args = ['%name' => $account->getUsername(), '@op' => $op, '@bundle' => $this->getItemLabelPlural()]; throw new EntityAccessException($this->t('User %name is not authorized to @op @bundle.', $args)); }
/** * Checks access to the given entity. * * By default, entity access is checked. However, a subclass can choose to * exclude certain items from entity access checking by immediately granting * access. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to check. * * @return \Drupal\Core\Access\AccessResult * A cacheable access result. */ protected function checkAccess(EntityInterface $entity) { return $entity->access('view', NULL, TRUE); }
/** * {@inheritdoc} */ public function accessEditEntityField(EntityInterface $entity, $field_name) { return $entity->access('update') && $entity->get($field_name)->access('edit'); }