Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 137 |
| NodeController | |
0.00% |
0 / 1 |
|
0.00% |
0 / 8 |
756 | |
0.00% |
0 / 137 |
| __construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
| create | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 5 |
|||
| addPage | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 21 |
|||
| add | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 6 |
|||
| revisionShow | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 6 |
|||
| revisionPageTitle | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
| revisionOverview | |
0.00% |
0 / 1 |
306 | |
0.00% |
0 / 91 |
|||
| addPageTitle | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\node\Controller\NodeController. | |
| */ | |
| namespace Drupal\node\Controller; | |
| use Drupal\Component\Utility\Xss; | |
| use Drupal\Core\Controller\ControllerBase; | |
| use Drupal\Core\Datetime\DateFormatterInterface; | |
| use Drupal\Core\DependencyInjection\ContainerInjectionInterface; | |
| use Drupal\Core\Language\LanguageInterface; | |
| use Drupal\Core\Render\RendererInterface; | |
| use Drupal\Core\Url; | |
| use Drupal\node\NodeTypeInterface; | |
| use Drupal\node\NodeInterface; | |
| use Symfony\Component\DependencyInjection\ContainerInterface; | |
| /** | |
| * Returns responses for Node routes. | |
| */ | |
| class NodeController extends ControllerBase implements ContainerInjectionInterface { | |
| /** | |
| * The date formatter service. | |
| * | |
| * @var \Drupal\Core\Datetime\DateFormatterInterface | |
| */ | |
| protected $dateFormatter; | |
| /** | |
| * The renderer service. | |
| * | |
| * @var \Drupal\Core\Render\RendererInterface | |
| */ | |
| protected $renderer; | |
| /** | |
| * Constructs a NodeController object. | |
| * | |
| * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter | |
| * The date formatter service. | |
| * @param \Drupal\Core\Render\RendererInterface $renderer | |
| * The renderer service. | |
| */ | |
| public function __construct(DateFormatterInterface $date_formatter, RendererInterface $renderer) { | |
| $this->dateFormatter = $date_formatter; | |
| $this->renderer = $renderer; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public static function create(ContainerInterface $container) { | |
| return new static( | |
| $container->get('date.formatter'), | |
| $container->get('renderer') | |
| ); | |
| } | |
| /** | |
| * Displays add content links for available content types. | |
| * | |
| * Redirects to node/add/[type] if only one content type is available. | |
| * | |
| * @return array|\Symfony\Component\HttpFoundation\RedirectResponse | |
| * A render array for a list of the node types that can be added; however, | |
| * if there is only one node type defined for the site, the function | |
| * will return a RedirectResponse to the node add page for that one node | |
| * type. | |
| */ | |
| public function addPage() { | |
| $build = [ | |
| '#theme' => 'node_add_list', | |
| '#cache' => [ | |
| 'tags' => $this->entityManager()->getDefinition('node_type')->getListCacheTags(), | |
| ], | |
| ]; | |
| $content = array(); | |
| // Only use node types the user has access to. | |
| foreach ($this->entityManager()->getStorage('node_type')->loadMultiple() as $type) { | |
| $access = $this->entityManager()->getAccessControlHandler('node')->createAccess($type->id(), NULL, [], TRUE); | |
| if ($access->isAllowed()) { | |
| $content[$type->id()] = $type; | |
| } | |
| $this->renderer->addCacheableDependency($build, $access); | |
| } | |
| // Bypass the node/add listing if only one content type is available. | |
| if (count($content) == 1) { | |
| $type = array_shift($content); | |
| return $this->redirect('node.add', array('node_type' => $type->id())); | |
| } | |
| $build['#content'] = $content; | |
| return $build; | |
| } | |
| /** | |
| * Provides the node submission form. | |
| * | |
| * @param \Drupal\node\NodeTypeInterface $node_type | |
| * The node type entity for the node. | |
| * | |
| * @return array | |
| * A node submission form. | |
| */ | |
| public function add(NodeTypeInterface $node_type) { | |
| $node = $this->entityManager()->getStorage('node')->create(array( | |
| 'type' => $node_type->id(), | |
| )); | |
| $form = $this->entityFormBuilder()->getForm($node); | |
| return $form; | |
| } | |
| /** | |
| * Displays a node revision. | |
| * | |
| * @param int $node_revision | |
| * The node revision ID. | |
| * | |
| * @return array | |
| * An array suitable for drupal_render(). | |
| */ | |
| public function revisionShow($node_revision) { | |
| $node = $this->entityManager()->getStorage('node')->loadRevision($node_revision); | |
| $node_view_controller = new NodeViewController($this->entityManager, $this->renderer); | |
| $page = $node_view_controller->view($node); | |
| unset($page['nodes'][$node->id()]['#cache']); | |
| return $page; | |
| } | |
| /** | |
| * Page title callback for a node revision. | |
| * | |
| * @param int $node_revision | |
| * The node revision ID. | |
| * | |
| * @return string | |
| * The page title. | |
| */ | |
| public function revisionPageTitle($node_revision) { | |
| $node = $this->entityManager()->getStorage('node')->loadRevision($node_revision); | |
| return $this->t('Revision of %title from %date', array('%title' => $node->label(), '%date' => format_date($node->getRevisionCreationTime()))); | |
| } | |
| /** | |
| * Generates an overview table of older revisions of a node. | |
| * | |
| * @param \Drupal\node\NodeInterface $node | |
| * A node object. | |
| * | |
| * @return array | |
| * An array as expected by drupal_render(). | |
| */ | |
| public function revisionOverview(NodeInterface $node) { | |
| $account = $this->currentUser(); | |
| $langcode = $this->languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(); | |
| $langname = $this->languageManager()->getLanguageName($langcode); | |
| $languages = $node->getTranslationLanguages(); | |
| $has_translations = (count($languages) > 1); | |
| $node_storage = $this->entityManager()->getStorage('node'); | |
| $type = $node->getType(); | |
| $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]); | |
| $header = array($this->t('Revision'), $this->t('Operations')); | |
| $revert_permission = (($account->hasPermission("revert $type revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update')); | |
| $delete_permission = (($account->hasPermission("delete $type revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete')); | |
| $rows = array(); | |
| $vids = $node_storage->revisionIds($node); | |
| $latest_revision = TRUE; | |
| foreach (array_reverse($vids) as $vid) { | |
| /** @var \Drupal\node\NodeInterface $revision */ | |
| $revision = $node_storage->loadRevision($vid); | |
| if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { | |
| $username = [ | |
| '#theme' => 'username', | |
| '#account' => $revision->getRevisionAuthor(), | |
| ]; | |
| // Use revision link to link to revisions that are not active. | |
| $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short'); | |
| if ($vid != $node->getRevisionId()) { | |
| $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid])); | |
| } | |
| else { | |
| $link = $node->link($date); | |
| } | |
| $row = []; | |
| $column = [ | |
| 'data' => [ | |
| '#type' => 'inline_template', | |
| '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', | |
| '#context' => [ | |
| 'date' => $link, | |
| 'username' => $this->renderer->renderPlain($username), | |
| 'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()], | |
| ], | |
| ], | |
| ]; | |
| // @todo Simplify once https://www.drupal.org/node/2334319 lands. | |
| $this->renderer->addCacheableDependency($column['data'], $username); | |
| $row[] = $column; | |
| if ($latest_revision) { | |
| $row[] = [ | |
| 'data' => [ | |
| '#prefix' => '<em>', | |
| '#markup' => $this->t('Current revision'), | |
| '#suffix' => '</em>', | |
| ], | |
| ]; | |
| foreach ($row as &$current) { | |
| $current['class'] = ['revision-current']; | |
| } | |
| $latest_revision = FALSE; | |
| } | |
| else { | |
| $links = []; | |
| if ($revert_permission) { | |
| $links['revert'] = [ | |
| 'title' => $this->t('Revert'), | |
| 'url' => $has_translations ? | |
| Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) : | |
| Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]), | |
| ]; | |
| } | |
| if ($delete_permission) { | |
| $links['delete'] = [ | |
| 'title' => $this->t('Delete'), | |
| 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]), | |
| ]; | |
| } | |
| $row[] = [ | |
| 'data' => [ | |
| '#type' => 'operations', | |
| '#links' => $links, | |
| ], | |
| ]; | |
| } | |
| $rows[] = $row; | |
| } | |
| } | |
| $build['node_revisions_table'] = array( | |
| '#theme' => 'table', | |
| '#rows' => $rows, | |
| '#header' => $header, | |
| '#attached' => array( | |
| 'library' => array('node/drupal.node.admin'), | |
| ), | |
| ); | |
| return $build; | |
| } | |
| /** | |
| * The _title_callback for the node.add route. | |
| * | |
| * @param \Drupal\node\NodeTypeInterface $node_type | |
| * The current node. | |
| * | |
| * @return string | |
| * The page title. | |
| */ | |
| public function addPageTitle(NodeTypeInterface $node_type) { | |
| return $this->t('Create @name', array('@name' => $node_type->label())); | |
| } | |
| } |