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())); | |
} | |
} |