updated core and modules

This commit is contained in:
Bachir Soussi Chiadmi
2017-09-09 16:27:51 +02:00
parent 027aa99b32
commit 41863f872c
7810 changed files with 318922 additions and 83631 deletions
@@ -35,7 +35,7 @@ class NodeRevisionAccessCheck implements AccessInterface {
*
* @var array
*/
protected $access = array();
protected $access = [];
/**
* Constructs a new NodeRevisionAccessCheck.
@@ -90,17 +90,17 @@ class NodeRevisionAccessCheck implements AccessInterface {
* TRUE if the operation may be performed, FALSE otherwise.
*/
public function checkAccess(NodeInterface $node, AccountInterface $account, $op = 'view') {
$map = array(
$map = [
'view' => 'view all revisions',
'update' => 'revert all revisions',
'delete' => 'delete all revisions',
);
];
$bundle = $node->bundle();
$type_map = array(
$type_map = [
'view' => "view $bundle revisions",
'update' => "revert $bundle revisions",
'delete' => "delete $bundle revisions",
);
];
if (!$node || !isset($map[$op]) || !isset($type_map[$op])) {
// If there was no node to check against, or the $op was not one of the
@@ -48,7 +48,7 @@ class NodeRouteContext implements ContextProviderInterface {
}
elseif ($this->routeMatch->getRouteName() == 'node.add') {
$node_type = $this->routeMatch->getParameter('node_type');
$value = Node::create(array('type' => $node_type->id()));
$value = Node::create(['type' => $node_type->id()]);
}
$cacheability = new CacheableMetadata();
@@ -74,7 +74,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
],
];
$content = array();
$content = [];
// Only use node types the user has access to.
foreach ($this->entityManager()->getStorage('node_type')->loadMultiple() as $type) {
@@ -88,7 +88,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
// 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()));
return $this->redirect('node.add', ['node_type' => $type->id()]);
}
$build['#content'] = $content;
@@ -106,9 +106,9 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
* A node submission form.
*/
public function add(NodeTypeInterface $node_type) {
$node = $this->entityManager()->getStorage('node')->create(array(
$node = $this->entityManager()->getStorage('node')->create([
'type' => $node_type->id(),
));
]);
$form = $this->entityFormBuilder()->getForm($node);
@@ -127,7 +127,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
public function revisionShow($node_revision) {
$node = $this->entityManager()->getStorage('node')->loadRevision($node_revision);
$node = $this->entityManager()->getTranslationFromContext($node);
$node_view_controller = new NodeViewController($this->entityManager, $this->renderer);
$node_view_controller = new NodeViewController($this->entityManager, $this->renderer, $this->currentUser());
$page = $node_view_controller->view($node);
unset($page['nodes'][$node->id()]['#cache']);
return $page;
@@ -144,7 +144,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
*/
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())));
return $this->t('Revision of %title from %date', ['%title' => $node->label(), '%date' => format_date($node->getRevisionCreationTime())]);
}
/**
@@ -166,15 +166,15 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
$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'));
$header = [$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();
$latest_revision = TRUE;
$rows = [];
$default_revision = $node->getRevisionId();
foreach ($this->_getRevisionIds($node, $node_storage) as $vid) {
foreach ($this->getRevisionIds($node, $node_storage) as $vid) {
/** @var \Drupal\node\NodeInterface $revision */
$revision = $node_storage->loadRevision($vid);
// Only show revisions that are affected by the language that is being
@@ -182,7 +182,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
$username = [
'#theme' => 'username',
'#account' => $revision->getRevisionAuthor(),
'#account' => $revision->getRevisionUser(),
];
// Use revision link to link to revisions that are not active.
@@ -210,7 +210,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
$this->renderer->addCacheableDependency($column['data'], $username);
$row[] = $column;
if ($latest_revision) {
if ($vid == $default_revision) {
$row[] = [
'data' => [
'#prefix' => '<em>',
@@ -218,16 +218,17 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
'#suffix' => '</em>',
],
];
foreach ($row as &$current) {
$current['class'] = ['revision-current'];
}
$latest_revision = FALSE;
$rows[] = [
'data' => $row,
'class' => ['revision-current'],
];
}
else {
$links = [];
if ($revert_permission) {
$links['revert'] = [
'title' => $this->t('Revert'),
'title' => $vid < $node->getRevisionId() ? $this->t('Revert') : $this->t('Set as current revision'),
'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]),
@@ -247,22 +248,23 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
'#links' => $links,
],
];
}
$rows[] = $row;
$rows[] = $row;
}
}
}
$build['node_revisions_table'] = array(
$build['node_revisions_table'] = [
'#theme' => 'table',
'#rows' => $rows,
'#header' => $header,
'#attached' => array(
'library' => array('node/drupal.node.admin'),
),
);
'#attached' => [
'library' => ['node/drupal.node.admin'],
],
'#attributes' => ['class' => 'node-revision-table'],
];
$build['pager'] = array('#type' => 'pager');
$build['pager'] = ['#type' => 'pager'];
return $build;
}
@@ -277,13 +279,13 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
* The page title.
*/
public function addPageTitle(NodeTypeInterface $node_type) {
return $this->t('Create @name', array('@name' => $node_type->label()));
return $this->t('Create @name', ['@name' => $node_type->label()]);
}
/**
* Gets a list of node revision IDs for a specific node.
*
* @param \Drupal\node\NodeInterface
* @param \Drupal\node\NodeInterface $node
* The node entity.
* @param \Drupal\node\NodeStorageInterface $node_storage
* The node storage handler.
@@ -291,7 +293,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
* @return int[]
* Node revision IDs (in descending order).
*/
protected function _getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) {
protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) {
$result = $node_storage->getQuery()
->allRevisions()
->condition($node->getEntityType()->getKey('id'), $node->id())
@@ -4,12 +4,50 @@ namespace Drupal\node\Controller;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Controller\EntityViewController;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a controller to render a single node.
*/
class NodeViewController extends EntityViewController {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* Creates an NodeViewController object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user. For backwards compatibility this is optional, however
* this will be removed before Drupal 9.0.0.
*/
public function __construct(EntityManagerInterface $entity_manager, RendererInterface $renderer, AccountInterface $current_user = NULL) {
parent::__construct($entity_manager, $renderer);
$this->currentUser = $current_user ?: \Drupal::currentUser();
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
$container->get('renderer'),
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
@@ -17,27 +55,44 @@ class NodeViewController extends EntityViewController {
$build = parent::view($node, $view_mode, $langcode);
foreach ($node->uriRelationships() as $rel) {
// Set the node path as the canonical URL to prevent duplicate content.
$build['#attached']['html_head_link'][] = array(
array(
'rel' => $rel,
'href' => $node->url($rel),
),
TRUE,
);
$url = $node->toUrl($rel);
// Add link relationships if the user is authenticated or if the anonymous
// user has access. Access checking must be done for anonymous users to
// avoid traffic to inaccessible pages from web crawlers. For
// authenticated users, showing the links in HTML head does not impact
// user experience or security, since the routes are access checked when
// visited and only visible via view source. This prevents doing
// potentially expensive and hard to cache access checks on every request.
// This means that the page will vary by user.permissions. We also rely on
// the access checking fallback to ensure the correct cacheability
// metadata if we have to check access.
if ($this->currentUser->isAuthenticated() || $url->access($this->currentUser)) {
// Set the node path as the canonical URL to prevent duplicate content.
$build['#attached']['html_head_link'][] = [
[
'rel' => $rel,
'href' => $url->toString(),
],
TRUE,
];
}
if ($rel == 'canonical') {
// Set the non-aliased canonical path as a default shortlink.
$build['#attached']['html_head_link'][] = array(
array(
$build['#attached']['html_head_link'][] = [
[
'rel' => 'shortlink',
'href' => $node->url($rel, array('alias' => TRUE)),
),
'href' => $url->setOption('alias', TRUE)->toString(),
],
TRUE,
);
];
}
}
// Given this varies by $this->currentUser->isAuthenticated(), add a cache
// context based on the anonymous role.
$build['#cache']['contexts'][] = 'user.roles:anonymous';
return $build;
}
+85 -60
View File
@@ -4,6 +4,7 @@ namespace Drupal\node\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityPublishedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
@@ -17,6 +18,7 @@ use Drupal\user\UserInterface;
* @ContentEntityType(
* id = "node",
* label = @Translation("Content"),
* label_collection = @Translation("Content"),
* label_singular = @Translation("content item"),
* label_plural = @Translation("content items"),
* label_count = @PluralTranslation(
@@ -45,6 +47,7 @@ use Drupal\user\UserInterface;
* data_table = "node_field_data",
* revision_table = "node_revision",
* revision_data_table = "node_field_revision",
* show_revision_ui = TRUE,
* translatable = TRUE,
* list_cache_contexts = { "user.node_grants:view" },
* entity_keys = {
@@ -55,6 +58,7 @@ use Drupal\user\UserInterface;
* "langcode" = "langcode",
* "uuid" = "uuid",
* "status" = "status",
* "published" = "status",
* "uid" = "uid",
* },
* bundle_entity_type = "node_type",
@@ -73,6 +77,7 @@ use Drupal\user\UserInterface;
class Node extends ContentEntityBase implements NodeInterface {
use EntityChangedTrait;
use EntityPublishedTrait;
/**
* Whether the node is being previewed or not.
@@ -102,8 +107,8 @@ class Node extends ContentEntityBase implements NodeInterface {
// If no revision author has been set explicitly, make the node owner the
// revision author.
if (!$this->getRevisionAuthor()) {
$this->setRevisionAuthorId($this->getOwnerId());
if (!$this->getRevisionUser()) {
$this->setRevisionUserId($this->getOwnerId());
}
}
@@ -178,13 +183,8 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
if ($operation == 'create') {
return parent::access($operation, $account, $return_as_object);
}
return \Drupal::entityManager()
->getAccessControlHandler($this->entityTypeId)
->access($this, $operation, $account, $return_as_object);
// This override exists to set the operation to the default value "view".
return parent::access($operation, $account, $return_as_object);
}
/**
@@ -229,7 +229,7 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function setPromoted($promoted) {
$this->set('promote', $promoted ? NODE_PROMOTED : NODE_NOT_PROMOTED);
$this->set('promote', $promoted ? NodeInterface::PROMOTED : NodeInterface::NOT_PROMOTED);
return $this;
}
@@ -244,21 +244,7 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function setSticky($sticky) {
$this->set('sticky', $sticky ? NODE_STICKY : NODE_NOT_STICKY);
return $this;
}
/**
* {@inheritdoc}
*/
public function isPublished() {
return (bool) $this->getEntityKey('status');
}
/**
* {@inheritdoc}
*/
public function setPublished($published) {
$this->set('status', $published ? NODE_PUBLISHED : NODE_NOT_PUBLISHED);
$this->set('sticky', $sticky ? NodeInterface::STICKY : NodeInterface::NOT_STICKY);
return $this;
}
@@ -311,6 +297,13 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function getRevisionAuthor() {
return $this->getRevisionUser();
}
/**
* {@inheritdoc}
*/
public function getRevisionUser() {
return $this->get('revision_uid')->entity;
}
@@ -318,7 +311,45 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function setRevisionAuthorId($uid) {
$this->set('revision_uid', $uid);
$this->setRevisionUserId($uid);
return $this;
}
/**
* {@inheritdoc}
*/
public function setRevisionUser(UserInterface $user) {
$this->set('revision_uid', $user);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRevisionUserId() {
return $this->get('revision_uid')->entity->id();
}
/**
* {@inheritdoc}
*/
public function setRevisionUserId($user_id) {
$this->set('revision_uid', $user_id);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRevisionLogMessage() {
return $this->get('revision_log')->value;
}
/**
* {@inheritdoc}
*/
public function setRevisionLogMessage($revision_log_message) {
$this->set('revision_log', $revision_log_message);
return $this;
}
@@ -327,6 +358,7 @@ class Node extends ContentEntityBase implements NodeInterface {
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
$fields += static::publishedBaseFieldDefinitions($entity_type);
$fields['title'] = BaseFieldDefinition::create('string')
->setLabel(t('Title'))
@@ -334,15 +366,15 @@ class Node extends ContentEntityBase implements NodeInterface {
->setTranslatable(TRUE)
->setRevisionable(TRUE)
->setSetting('max_length', 255)
->setDisplayOptions('view', array(
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => -5,
))
->setDisplayOptions('form', array(
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -5,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['uid'] = BaseFieldDefinition::create('entity_reference')
@@ -352,43 +384,36 @@ class Node extends ContentEntityBase implements NodeInterface {
->setSetting('target_type', 'user')
->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId')
->setTranslatable(TRUE)
->setDisplayOptions('view', array(
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'author',
'weight' => 0,
))
->setDisplayOptions('form', array(
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => array(
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'placeholder' => '',
),
))
],
])
->setDisplayConfigurable('form', TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the node is published.'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDefaultValue(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Authored on'))
->setDescription(t('The time that the node was created.'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDisplayOptions('view', array(
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'timestamp',
'weight' => 0,
))
->setDisplayOptions('form', array(
])
->setDisplayOptions('form', [
'type' => 'datetime_timestamp',
'weight' => 10,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['changed'] = BaseFieldDefinition::create('changed')
@@ -402,13 +427,13 @@ class Node extends ContentEntityBase implements NodeInterface {
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDefaultValue(TRUE)
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'settings' => array(
'settings' => [
'display_label' => TRUE,
),
],
'weight' => 15,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['sticky'] = BaseFieldDefinition::create('boolean')
@@ -416,13 +441,13 @@ class Node extends ContentEntityBase implements NodeInterface {
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDefaultValue(FALSE)
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'settings' => array(
'settings' => [
'display_label' => TRUE,
),
],
'weight' => 16,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['revision_timestamp'] = BaseFieldDefinition::create('created')
@@ -443,13 +468,13 @@ class Node extends ContentEntityBase implements NodeInterface {
->setDescription(t('Briefly describe the changes you have made.'))
->setRevisionable(TRUE)
->setDefaultValue('')
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'string_textarea',
'weight' => 25,
'settings' => array(
'settings' => [
'rows' => 4,
),
));
],
]);
$fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Revision translation affected'))
@@ -470,7 +495,7 @@ class Node extends ContentEntityBase implements NodeInterface {
* An array of default values.
*/
public static function getCurrentUserId() {
return array(\Drupal::currentUser()->id());
return [\Drupal::currentUser()->id()];
}
}
+10 -3
View File
@@ -83,7 +83,7 @@ class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface {
*
* @var bool
*/
protected $new_revision = FALSE;
protected $new_revision = TRUE;
/**
* The preview mode.
@@ -182,10 +182,10 @@ class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface {
drupal_set_message(\Drupal::translation()->formatPlural($update_count,
'Changed the content type of 1 post from %old-type to %type.',
'Changed the content type of @count posts from %old-type to %type.',
array(
[
'%old-type' => $this->getOriginalId(),
'%type' => $this->id(),
)));
]));
}
}
if ($update) {
@@ -205,4 +205,11 @@ class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface {
$storage->resetCache(array_keys($entities));
}
/**
* {@inheritdoc}
*/
public function shouldCreateNewRevision() {
return $this->isNewRevision();
}
}
@@ -20,7 +20,7 @@ class DeleteMultiple extends ConfirmFormBase {
*
* @var string[][]
*/
protected $nodeInfo = array();
protected $nodeInfo = [];
/**
* The tempstore factory.
@@ -130,10 +130,10 @@ class DeleteMultiple extends ConfirmFormBase {
}
}
$form['nodes'] = array(
$form['nodes'] = [
'#theme' => 'item_list',
'#items' => $items,
);
];
$form = parent::buildForm($form, $form_state);
return $form;
@@ -167,7 +167,7 @@ class DeleteMultiple extends ConfirmFormBase {
if ($delete_nodes) {
$this->storage->delete($delete_nodes);
$this->logger('content')->notice('Deleted @count posts.', array('@count' => count($delete_nodes)));
$this->logger('content')->notice('Deleted @count posts.', ['@count' => count($delete_nodes)]);
}
if ($delete_translations) {
@@ -182,7 +182,7 @@ class DeleteMultiple extends ConfirmFormBase {
}
if ($count) {
$total_count += $count;
$this->logger('content')->notice('Deleted @count content translations.', array('@count' => $count));
$this->logger('content')->notice('Deleted @count content translations.', ['@count' => $count]);
}
}
@@ -27,10 +27,10 @@ class NodeDeleteForm extends ContentEntityDeleteForm {
]);
}
return $this->t('The @type %title has been deleted.', array(
return $this->t('The @type %title has been deleted.', [
'@type' => $node_type,
'%title' => $this->getEntity()->label(),
));
]);
}
/**
+34 -20
View File
@@ -3,7 +3,6 @@
namespace Drupal\node\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\FormBase;
@@ -14,7 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Contains a form for switching the view mode of a node during preview.
*/
class NodePreviewForm extends FormBase implements ContainerInjectionInterface {
class NodePreviewForm extends FormBase {
/**
* The entity manager service.
@@ -73,42 +72,49 @@ class NodePreviewForm extends FormBase implements ContainerInjectionInterface {
public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $node = NULL) {
$view_mode = $node->preview_view_mode;
$query_options = $node->isNew() ? array('query' => array('uuid' => $node->uuid())) : array();
$form['backlink'] = array(
$query_options = ['query' => ['uuid' => $node->uuid()]];
$query = $this->getRequest()->query;
if ($query->has('destination')) {
$query_options['query']['destination'] = $query->get('destination');
}
$form['backlink'] = [
'#type' => 'link',
'#title' => $this->t('Back to content editing'),
'#url' => $node->isNew() ? Url::fromRoute('node.add', ['node_type' => $node->bundle()]) : $node->urlInfo('edit-form'),
'#options' => array('attributes' => array('class' => array('node-preview-backlink'))) + $query_options,
);
'#options' => ['attributes' => ['class' => ['node-preview-backlink']]] + $query_options,
];
$view_mode_options = $this->entityManager->getViewModeOptionsByBundle('node', $node->bundle());
// Always show full as an option, even if the display is not enabled.
$view_mode_options = ['full' => $this->t('Full')] + $this->entityManager->getViewModeOptionsByBundle('node', $node->bundle());
// Unset view modes that are not used in the front end.
unset($view_mode_options['default']);
unset($view_mode_options['rss']);
unset($view_mode_options['search_index']);
$form['uuid'] = array(
$form['uuid'] = [
'#type' => 'value',
'#value' => $node->uuid(),
);
];
$form['view_mode'] = array(
$form['view_mode'] = [
'#type' => 'select',
'#title' => $this->t('View mode'),
'#options' => $view_mode_options,
'#default_value' => $view_mode,
'#attributes' => array(
'#attributes' => [
'data-drupal-autosubmit' => TRUE,
)
);
]
];
$form['submit'] = array(
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Switch'),
'#attributes' => array(
'class' => array('js-hide'),
),
);
'#attributes' => [
'class' => ['js-hide'],
],
];
return $form;
}
@@ -117,10 +123,18 @@ class NodePreviewForm extends FormBase implements ContainerInjectionInterface {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->setRedirect('entity.node.preview', array(
$route_parameters = [
'node_preview' => $form_state->getValue('uuid'),
'view_mode_id' => $form_state->getValue('view_mode'),
));
];
$options = [];
$query = $this->getRequest()->query;
if ($query->has('destination')) {
$options['query']['destination'] = $query->get('destination');
$query->remove('destination');
}
$form_state->setRedirect('entity.node.preview', $route_parameters, $options);
}
}
@@ -81,14 +81,14 @@ class NodeRevisionDeleteForm extends ConfirmFormBase {
* {@inheritdoc}
*/
public function getQuestion() {
return t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($this->revision->getRevisionCreationTime())));
return t('Are you sure you want to delete the revision from %revision-date?', ['%revision-date' => format_date($this->revision->getRevisionCreationTime())]);
}
/**
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('entity.node.version_history', array('node' => $this->revision->id()));
return new Url('entity.node.version_history', ['node' => $this->revision->id()]);
}
/**
@@ -114,17 +114,17 @@ class NodeRevisionDeleteForm extends ConfirmFormBase {
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->nodeStorage->deleteRevision($this->revision->getRevisionId());
$this->logger('content')->notice('@type: deleted %title revision %revision.', array('@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()));
$this->logger('content')->notice('@type: deleted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
$node_type = $this->nodeTypeStorage->load($this->revision->bundle())->label();
drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()), '@type' => $node_type, '%title' => $this->revision->label())));
drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', ['%revision-date' => format_date($this->revision->getRevisionCreationTime()), '@type' => $node_type, '%title' => $this->revision->label()]));
$form_state->setRedirect(
'entity.node.canonical',
array('node' => $this->revision->id())
['node' => $this->revision->id()]
);
if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid', array(':nid' => $this->revision->id()))->fetchField() > 1) {
if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $this->revision->id()])->fetchField() > 1) {
$form_state->setRedirect(
'entity.node.version_history',
array('node' => $this->revision->id())
['node' => $this->revision->id()]
);
}
}
@@ -36,6 +36,13 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
*/
protected $dateFormatter;
/**
* The time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* Constructs a new NodeRevisionRevertForm.
*
@@ -47,6 +54,7 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter) {
$this->nodeStorage = $node_storage;
$this->dateFormatter = $date_formatter;
$this->time = \Drupal::service('datetime.time');
}
/**
@@ -77,7 +85,7 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('entity.node.version_history', array('node' => $this->revision->id()));
return new Url('entity.node.version_history', ['node' => $this->revision->id()]);
}
/**
@@ -114,13 +122,15 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
$this->revision = $this->prepareRevertedRevision($this->revision, $form_state);
$this->revision->revision_log = t('Copy of the revision from %date.', ['%date' => $this->dateFormatter->format($original_revision_timestamp)]);
$this->revision->setRevisionCreationTime($this->time->getRequestTime());
$this->revision->setChangedTime($this->time->getRequestTime());
$this->revision->save();
$this->logger('content')->notice('@type: reverted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
drupal_set_message(t('@type %title has been reverted to the revision from %revision-date.', ['@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => $this->dateFormatter->format($original_revision_timestamp)]));
$form_state->setRedirect(
'entity.node.version_history',
array('node' => $this->revision->id())
['node' => $this->revision->id()]
);
}
@@ -82,11 +82,11 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
$this->langcode = $langcode;
$form = parent::buildForm($form, $form_state, $node_revision);
$form['revert_untranslated_fields'] = array(
$form['revert_untranslated_fields'] = [
'#type' => 'checkbox',
'#title' => $this->t('Revert content shared among translations'),
'#default_value' => FALSE,
);
];
return $form;
}
@@ -2,54 +2,26 @@
namespace Drupal\node\Form;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Entity\EntityDeleteForm;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for content type deletion.
*/
class NodeTypeDeleteConfirm extends EntityDeleteForm {
/**
* The query factory to create entity queries.
*
* @var \Drupal\Core\Entity\Query\QueryFactory
*/
protected $queryFactory;
/**
* Constructs a new NodeTypeDeleteConfirm object.
*
* @param \Drupal\Core\Entity\Query\QueryFactory $query_factory
* The entity query object.
*/
public function __construct(QueryFactory $query_factory) {
$this->queryFactory = $query_factory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.query')
);
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$num_nodes = $this->queryFactory->get('node')
$num_nodes = $this->entityTypeManager->getStorage('node')->getQuery()
->condition('type', $this->entity->id())
->count()
->execute();
if ($num_nodes) {
$caption = '<p>' . $this->formatPlural($num_nodes, '%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', '%type is used by @count pieces of content on your site. You may not remove %type until you have removed all of the %type content.', array('%type' => $this->entity->label())) . '</p>';
$caption = '<p>' . $this->formatPlural($num_nodes, '%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', '%type is used by @count pieces of content on your site. You may not remove %type until you have removed all of the %type content.', ['%type' => $this->entity->label()]) . '</p>';
$form['#title'] = $this->getQuestion();
$form['description'] = array('#markup' => $caption);
$form['description'] = ['#markup' => $caption];
return $form;
}
@@ -62,17 +62,18 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
return $return_as_object ? $result : $result->isAllowed();
}
if (!$account->hasPermission('access content')) {
$result = AccessResult::forbidden()->cachePerPermissions();
$result = AccessResult::forbidden("The 'access content' permission is required.")->cachePerPermissions();
return $return_as_object ? $result : $result->isAllowed();
}
$result = parent::access($entity, $operation, $account, TRUE)->cachePerPermissions();
return $return_as_object ? $result : $result->isAllowed();
}
/**
* {@inheritdoc}
*/
public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = array(), $return_as_object = FALSE) {
public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) {
$account = $this->prepareUser($account);
if ($account->hasPermission('bypass node access')) {
@@ -120,13 +121,13 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
// Only users with the administer nodes permission can edit administrative
// fields.
$administrative_fields = array('uid', 'status', 'created', 'promote', 'sticky');
$administrative_fields = ['uid', 'status', 'created', 'promote', 'sticky'];
if ($operation == 'edit' && in_array($field_definition->getName(), $administrative_fields, TRUE)) {
return AccessResult::allowedIfHasPermission($account, 'administer nodes');
}
// No user can change read only fields.
$read_only_fields = array('revision_timestamp', 'revision_uid');
$read_only_fields = ['revision_timestamp', 'revision_uid'];
if ($operation == 'edit' && in_array($field_definition->getName(), $read_only_fields, TRUE)) {
return AccessResult::forbidden();
}
@@ -146,12 +147,12 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
* {@inheritdoc}
*/
public function acquireGrants(NodeInterface $node) {
$grants = $this->moduleHandler->invokeAll('node_access_records', array($node));
$grants = $this->moduleHandler->invokeAll('node_access_records', [$node]);
// Let modules alter the grants.
$this->moduleHandler->alter('node_access_records', $grants, $node);
// If no grants are set and the node is published, then use the default grant.
if (empty($grants) && $node->isPublished()) {
$grants[] = array('realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0);
$grants[] = ['realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0];
}
return $grants;
}
@@ -23,7 +23,7 @@ interface NodeAccessControlHandlerInterface {
* @param \Drupal\node\NodeInterface $node
* The $node to acquire grants for.
*
* @return array $grants
* @return array
* The access rules for the node.
*/
public function acquireGrants(NodeInterface $node);
@@ -74,7 +74,7 @@ interface NodeAccessControlHandlerInterface {
* A user object representing the user for whom the operation is to be
* performed.
*
* @return int.
* @return int
* Status of the access check.
*/
public function checkAllGrants(AccountInterface $account);
+66 -136
View File
@@ -2,8 +2,10 @@
namespace Drupal\node;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -21,20 +23,19 @@ class NodeForm extends ContentEntityForm {
protected $tempStoreFactory;
/**
* Whether this node has been previewed or not.
*/
protected $hasBeenPreviewed = FALSE;
/**
* Constructs a ContentEntityForm object.
* Constructs a NodeForm object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The entity type bundle service.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time service.
*/
public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory) {
parent::__construct($entity_manager);
public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) {
parent::__construct($entity_manager, $entity_type_bundle_info, $time);
$this->tempStoreFactory = $temp_store_factory;
}
@@ -44,128 +45,74 @@ class NodeForm extends ContentEntityForm {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
$container->get('user.private_tempstore')
$container->get('user.private_tempstore'),
$container->get('entity_type.bundle.info'),
$container->get('datetime.time')
);
}
/**
* {@inheritdoc}
*/
protected function prepareEntity() {
/** @var \Drupal\node\NodeInterface $node */
$node = $this->entity;
if (!$node->isNew()) {
// Remove the revision log message from the original node entity.
$node->revision_log = NULL;
}
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
// Try to restore from temp store, this must be done before calling
// parent::form().
$uuid = $this->entity->uuid();
$store = $this->tempStoreFactory->get('node_preview');
// If the user is creating a new node, the UUID is passed in the request.
if ($request_uuid = \Drupal::request()->query->get('uuid')) {
$uuid = $request_uuid;
}
if ($preview = $store->get($uuid)) {
// Attempt to load from preview when the uuid is present unless we are
// rebuilding the form.
$request_uuid = \Drupal::request()->query->get('uuid');
if (!$form_state->isRebuilding() && $request_uuid && $preview = $store->get($request_uuid)) {
/** @var $preview \Drupal\Core\Form\FormStateInterface */
foreach ($preview->getValues() as $name => $value) {
$form_state->setValue($name, $value);
}
$form_state->setStorage($preview->getStorage());
$form_state->setUserInput($preview->getUserInput());
// Rebuild the form.
$form_state->setRebuild();
// The combination of having user input and rebuilding the form means
// that it will attempt to cache the form state which will fail if it is
// a GET request.
$form_state->setRequestMethod('POST');
$this->entity = $preview->getFormObject()->getEntity();
$this->entity->in_preview = NULL;
// Remove the stale temp store entry for existing nodes.
if (!$this->entity->isNew()) {
$store->delete($uuid);
}
$this->hasBeenPreviewed = TRUE;
$form_state->set('has_been_previewed', TRUE);
}
/** @var \Drupal\node\NodeInterface $node */
$node = $this->entity;
if ($this->operation == 'edit') {
$form['#title'] = $this->t('<em>Edit @type</em> @title', array('@type' => node_get_type_label($node), '@title' => $node->label()));
$form['#title'] = $this->t('<em>Edit @type</em> @title', ['@type' => node_get_type_label($node), '@title' => $node->label()]);
}
$current_user = $this->currentUser();
// Changed must be sent to the client, for later overwrite error checking.
$form['changed'] = array(
$form['changed'] = [
'#type' => 'hidden',
'#default_value' => $node->getChangedTime(),
);
];
$form['advanced'] = array(
'#type' => 'vertical_tabs',
'#attributes' => array('class' => array('entity-meta')),
'#weight' => 99,
);
$form = parent::form($form, $form_state);
// Add a revision_log field if the "Create new revision" option is checked,
// or if the current user has the ability to check that option.
$form['revision_information'] = array(
'#type' => 'details',
'#group' => 'advanced',
'#title' => t('Revision information'),
// Open by default when "Create new revision" is checked.
'#open' => $node->isNewRevision(),
'#attributes' => array(
'class' => array('node-form-revision-information'),
),
'#attached' => array(
'library' => array('node/drupal.node'),
),
'#weight' => 20,
'#optional' => TRUE,
);
$form['revision'] = array(
'#type' => 'checkbox',
'#title' => t('Create new revision'),
'#default_value' => $node->type->entity->isNewRevision(),
'#access' => $current_user->hasPermission('administer nodes'),
'#group' => 'revision_information',
);
$form['revision_log'] += array(
'#states' => array(
'visible' => array(
':input[name="revision"]' => array('checked' => TRUE),
),
),
'#group' => 'revision_information',
);
$form['advanced']['#attributes']['class'][] = 'entity-meta';
// Node author information for administrators.
$form['author'] = array(
$form['author'] = [
'#type' => 'details',
'#title' => t('Authoring information'),
'#group' => 'advanced',
'#attributes' => array(
'class' => array('node-form-author'),
),
'#attached' => array(
'library' => array('node/drupal.node'),
),
'#attributes' => [
'class' => ['node-form-author'],
],
'#attached' => [
'library' => ['node/drupal.node'],
],
'#weight' => 90,
'#optional' => TRUE,
);
];
if (isset($form['uid'])) {
$form['uid']['#group'] = 'author';
@@ -176,19 +123,19 @@ class NodeForm extends ContentEntityForm {
}
// Node options for administrators.
$form['options'] = array(
$form['options'] = [
'#type' => 'details',
'#title' => t('Promotion options'),
'#group' => 'advanced',
'#attributes' => array(
'class' => array('node-form-options'),
),
'#attached' => array(
'library' => array('node/drupal.node'),
),
'#attributes' => [
'class' => ['node-form-options'],
],
'#attached' => [
'library' => ['node/drupal.node'],
],
'#weight' => 95,
'#optional' => TRUE,
);
];
if (isset($form['promote'])) {
$form['promote']['#group'] = 'options';
@@ -200,7 +147,7 @@ class NodeForm extends ContentEntityForm {
$form['#attached']['library'][] = 'node/form';
$form['#entity_builders']['update_status'] = [$this, 'updateStatus'];
$form['#entity_builders']['update_status'] = '::updateStatus';
return $form;
}
@@ -219,7 +166,7 @@ class NodeForm extends ContentEntityForm {
*
* @see \Drupal\node\NodeForm::form()
*/
function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) {
public function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) {
$element = $form_state->getTriggeringElement();
if (isset($element['#published_status'])) {
$node->setPublished($element['#published_status']);
@@ -234,7 +181,7 @@ class NodeForm extends ContentEntityForm {
$node = $this->entity;
$preview_mode = $node->type->entity->getPreviewMode();
$element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $this->hasBeenPreviewed;
$element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $form_state->get('has_been_previewed');
// If saving is an option, privileged users get dedicated form submit
// buttons to adjust the publishing status while saving in one go.
@@ -289,13 +236,13 @@ class NodeForm extends ContentEntityForm {
$element['submit']['#access'] = FALSE;
}
$element['preview'] = array(
$element['preview'] = [
'#type' => 'submit',
'#access' => $preview_mode != DRUPAL_DISABLED && ($node->access('create') || $node->access('update')),
'#value' => t('Preview'),
'#weight' => 20,
'#submit' => array('::submitForm', '::preview'),
);
'#submit' => ['::submitForm', '::preview'],
];
$element['delete']['#access'] = $node->access('delete');
$element['delete']['#weight'] = 100;
@@ -303,32 +250,6 @@ class NodeForm extends ContentEntityForm {
return $element;
}
/**
* {@inheritdoc}
*
* Updates the node object by processing the submitted values.
*
* This function can be called by a "Next" button of a wizard to update the
* form state's entity with the current step's values before proceeding to the
* next step.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Build the node object from the submitted values.
parent::submitForm($form, $form_state);
$node = $this->entity;
// Save as a new revision if requested to do so.
if (!$form_state->isValueEmpty('revision') && $form_state->getValue('revision') != FALSE) {
$node->setNewRevision();
// If a new revision is created, save the current user as revision author.
$node->setRevisionCreationTime(REQUEST_TIME);
$node->setRevisionAuthorId(\Drupal::currentUser()->id());
}
else {
$node->setNewRevision(FALSE);
}
}
/**
* Form submission handler for the 'preview' action.
*
@@ -341,10 +262,19 @@ class NodeForm extends ContentEntityForm {
$store = $this->tempStoreFactory->get('node_preview');
$this->entity->in_preview = TRUE;
$store->set($this->entity->uuid(), $form_state);
$form_state->setRedirect('entity.node.preview', array(
$route_parameters = [
'node_preview' => $this->entity->uuid(),
'view_mode_id' => 'default',
));
'view_mode_id' => 'full',
];
$options = [];
$query = $this->getRequest()->query;
if ($query->has('destination')) {
$options['query']['destination'] = $query->get('destination');
$query->remove('destination');
}
$form_state->setRedirect('entity.node.preview', $route_parameters, $options);
}
/**
@@ -355,8 +285,8 @@ class NodeForm extends ContentEntityForm {
$insert = $node->isNew();
$node->save();
$node_link = $node->link($this->t('View'));
$context = array('@type' => $node->getType(), '%title' => $node->label(), 'link' => $node_link);
$t_args = array('@type' => node_get_type_label($node), '%title' => $node->label());
$context = ['@type' => $node->getType(), '%title' => $node->label(), 'link' => $node_link];
$t_args = ['@type' => node_get_type_label($node), '%title' => $node->link($node->label())];
if ($insert) {
$this->logger('content')->notice('@type: added %title.', $context);
@@ -373,7 +303,7 @@ class NodeForm extends ContentEntityForm {
if ($node->access('view')) {
$form_state->setRedirect(
'entity.node.canonical',
array('node' => $node->id())
['node' => $node->id()]
);
}
else {
@@ -161,7 +161,7 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
if (!($table instanceof SelectInterface) && $table == $base_table) {
// Set the subquery.
$subquery = $this->database->select('node_access', 'na')
->fields('na', array('nid'));
->fields('na', ['nid']);
// If any grant exists for the specified user, then user has access to the
// node for the specified operation.
@@ -202,13 +202,13 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
if ($delete) {
$query = $this->database->delete('node_access')->condition('nid', $node->id());
if ($realm) {
$query->condition('realm', array($realm, 'all'), 'IN');
$query->condition('realm', [$realm, 'all'], 'IN');
}
$query->execute();
}
// Only perform work when node_access modules are active.
if (!empty($grants) && count($this->moduleHandler->getImplementations('node_grants'))) {
$query = $this->database->insert('node_access')->fields(array('nid', 'langcode', 'fallback', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete'));
$query = $this->database->insert('node_access')->fields(['nid', 'langcode', 'fallback', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete']);
// If we have defined a granted langcode, use it. But if not, add a grant
// for every language this node is translated to.
foreach ($grants as $grant) {
@@ -216,7 +216,7 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
continue;
}
if (isset($grant['langcode'])) {
$grant_languages = array($grant['langcode'] => $this->languageManager->getLanguage($grant['langcode']));
$grant_languages = [$grant['langcode'] => $this->languageManager->getLanguage($grant['langcode'])];
}
else {
$grant_languages = $node->getTranslationLanguages(TRUE);
@@ -253,14 +253,14 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
*/
public function writeDefault() {
$this->database->insert('node_access')
->fields(array(
->fields([
'nid' => 0,
'realm' => 'all',
'gid' => 0,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
))
])
->execute();
}
@@ -18,7 +18,7 @@ interface NodeGrantDatabaseStorageInterface {
* A user object representing the user for whom the operation is to be
* performed.
*
* @return int.
* @return int
* Status of the access check.
*/
public function checkAll(AccountInterface $account);
+39 -22
View File
@@ -2,6 +2,8 @@
namespace Drupal\node;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\RevisionLogInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\Core\Entity\ContentEntityInterface;
@@ -9,7 +11,37 @@ use Drupal\Core\Entity\ContentEntityInterface;
/**
* Provides an interface defining a node entity.
*/
interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, RevisionLogInterface, EntityPublishedInterface {
/**
* Denotes that the node is not published.
*/
const NOT_PUBLISHED = 0;
/**
* Denotes that the node is published.
*/
const PUBLISHED = 1;
/**
* Denotes that the node is not promoted to the front page.
*/
const NOT_PROMOTED = 0;
/**
* Denotes that the node is promoted to the front page.
*/
const PROMOTED = 1;
/**
* Denotes that the node is not sticky at the top of the page.
*/
const NOT_STICKY = 0;
/**
* Denotes that the node is sticky at the top of the page.
*/
const STICKY = 1;
/**
* Gets the node type.
@@ -95,27 +127,6 @@ interface NodeInterface extends ContentEntityInterface, EntityChangedInterface,
*/
public function setSticky($sticky);
/**
* Returns the node published status indicator.
*
* Unpublished nodes are only visible to their authors and to administrators.
*
* @return bool
* TRUE if the node is published.
*/
public function isPublished();
/**
* Sets the published status of a node..
*
* @param bool $published
* TRUE to set this node to published, FALSE to set it to unpublished.
*
* @return \Drupal\node\NodeInterface
* The called node entity.
*/
public function setPublished($published);
/**
* Gets the node revision creation timestamp.
*
@@ -140,6 +151,9 @@ interface NodeInterface extends ContentEntityInterface, EntityChangedInterface,
*
* @return \Drupal\user\UserInterface
* The user entity for the revision author.
*
* @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
* \Drupal\Core\Entity\RevisionLogInterface::getRevisionUser() instead.
*/
public function getRevisionAuthor();
@@ -151,6 +165,9 @@ interface NodeInterface extends ContentEntityInterface, EntityChangedInterface,
*
* @return \Drupal\node\NodeInterface
* The called node entity.
*
* @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
* \Drupal\Core\Entity\RevisionLogInterface::setRevisionUserId() instead.
*/
public function setRevisionAuthorId($uid);
+21 -21
View File
@@ -68,27 +68,27 @@ class NodeListBuilder extends EntityListBuilder {
*/
public function buildHeader() {
// Enable language column and filter if multiple languages are added.
$header = array(
$header = [
'title' => $this->t('Title'),
'type' => array(
'type' => [
'data' => $this->t('Content type'),
'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
),
'author' => array(
'class' => [RESPONSIVE_PRIORITY_MEDIUM],
],
'author' => [
'data' => $this->t('Author'),
'class' => array(RESPONSIVE_PRIORITY_LOW),
),
'class' => [RESPONSIVE_PRIORITY_LOW],
],
'status' => $this->t('Status'),
'changed' => array(
'changed' => [
'data' => $this->t('Updated'),
'class' => array(RESPONSIVE_PRIORITY_LOW),
),
);
'class' => [RESPONSIVE_PRIORITY_LOW],
],
];
if (\Drupal::languageManager()->isMultilingual()) {
$header['language_name'] = array(
$header['language_name'] = [
'data' => $this->t('Language'),
'class' => array(RESPONSIVE_PRIORITY_LOW),
);
'class' => [RESPONSIVE_PRIORITY_LOW],
];
}
return $header + parent::buildHeader();
}
@@ -98,26 +98,26 @@ class NodeListBuilder extends EntityListBuilder {
*/
public function buildRow(EntityInterface $entity) {
/** @var \Drupal\node\NodeInterface $entity */
$mark = array(
$mark = [
'#theme' => 'mark',
'#mark_type' => node_mark($entity->id(), $entity->getChangedTime()),
);
];
$langcode = $entity->language()->getId();
$uri = $entity->urlInfo();
$options = $uri->getOptions();
$options += ($langcode != LanguageInterface::LANGCODE_NOT_SPECIFIED && isset($languages[$langcode]) ? array('language' => $languages[$langcode]) : array());
$options += ($langcode != LanguageInterface::LANGCODE_NOT_SPECIFIED && isset($languages[$langcode]) ? ['language' => $languages[$langcode]] : []);
$uri->setOptions($options);
$row['title']['data'] = array(
$row['title']['data'] = [
'#type' => 'link',
'#title' => $entity->label(),
'#suffix' => ' ' . drupal_render($mark),
'#url' => $uri,
);
];
$row['type'] = node_get_type_label($entity);
$row['author']['data'] = array(
$row['author']['data'] = [
'#theme' => 'username',
'#account' => $entity->getOwner(),
);
];
$row['status'] = $entity->isPublished() ? $this->t('published') : $this->t('not published');
$row['changed'] = $this->dateFormatter->format($entity->getChangedTime(), 'short');
$language_manager = \Drupal::languageManager();
+20 -20
View File
@@ -22,7 +22,7 @@ class NodePermissions {
* @see \Drupal\user\PermissionHandlerInterface::getPermissions()
*/
public function nodeTypePermissions() {
$perms = array();
$perms = [];
// Generate node permissions for all node types.
foreach (NodeType::loadMultiple() as $type) {
$perms += $this->buildPermissions($type);
@@ -42,36 +42,36 @@ class NodePermissions {
*/
protected function buildPermissions(NodeType $type) {
$type_id = $type->id();
$type_params = array('%type_name' => $type->label());
$type_params = ['%type_name' => $type->label()];
return array(
"create $type_id content" => array(
return [
"create $type_id content" => [
'title' => $this->t('%type_name: Create new content', $type_params),
),
"edit own $type_id content" => array(
],
"edit own $type_id content" => [
'title' => $this->t('%type_name: Edit own content', $type_params),
),
"edit any $type_id content" => array(
],
"edit any $type_id content" => [
'title' => $this->t('%type_name: Edit any content', $type_params),
),
"delete own $type_id content" => array(
],
"delete own $type_id content" => [
'title' => $this->t('%type_name: Delete own content', $type_params),
),
"delete any $type_id content" => array(
],
"delete any $type_id content" => [
'title' => $this->t('%type_name: Delete any content', $type_params),
),
"view $type_id revisions" => array(
],
"view $type_id revisions" => [
'title' => $this->t('%type_name: View revisions', $type_params),
),
"revert $type_id revisions" => array(
],
"revert $type_id revisions" => [
'title' => $this->t('%type_name: Revert revisions', $type_params),
'description' => t('Role requires permission <em>view revisions</em> and <em>edit rights</em> for nodes in question, or <em>administer nodes</em>.'),
),
"delete $type_id revisions" => array(
],
"delete $type_id revisions" => [
'title' => $this->t('%type_name: Delete revisions', $type_params),
'description' => $this->t('Role requires permission to <em>view revisions</em> and <em>delete rights</em> for nodes in question, or <em>administer nodes</em>.'),
),
);
],
];
}
}
+5 -5
View File
@@ -20,7 +20,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
public function revisionIds(NodeInterface $node) {
return $this->database->query(
'SELECT vid FROM {node_revision} WHERE nid=:nid ORDER BY vid',
array(':nid' => $node->id())
[':nid' => $node->id()]
)->fetchCol();
}
@@ -30,7 +30,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
public function userRevisionIds(AccountInterface $account) {
return $this->database->query(
'SELECT vid FROM {node_field_revision} WHERE uid = :uid ORDER BY vid',
array(':uid' => $account->id())
[':uid' => $account->id()]
)->fetchCol();
}
@@ -38,7 +38,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
* {@inheritdoc}
*/
public function countDefaultLanguageRevisions(NodeInterface $node) {
return $this->database->query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', array(':nid' => $node->id()))->fetchField();
return $this->database->query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', [':nid' => $node->id()])->fetchField();
}
/**
@@ -46,7 +46,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
*/
public function updateType($old_type, $new_type) {
return $this->database->update('node')
->fields(array('type' => $new_type))
->fields(['type' => $new_type])
->condition('type', $old_type)
->execute();
}
@@ -56,7 +56,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
*/
public function clearRevisionsLanguage(LanguageInterface $language) {
return $this->database->update('node_revision')
->fields(array('langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED))
->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED])
->condition('langcode', $language->getId())
->execute();
}
@@ -14,7 +14,7 @@ interface NodeStorageInterface extends ContentEntityStorageInterface {
/**
* Gets a list of node revision IDs for a specific node.
*
* @param \Drupal\node\NodeInterface
* @param \Drupal\node\NodeInterface $node
* The node entity.
*
* @return int[]
@@ -36,7 +36,7 @@ interface NodeStorageInterface extends ContentEntityStorageInterface {
/**
* Counts the number of revisions in the default language.
*
* @param \Drupal\node\NodeInterface
* @param \Drupal\node\NodeInterface $node
* The node entity.
*
* @return int
+4 -5
View File
@@ -17,11 +17,10 @@ class NodeStorageSchema extends SqlContentEntityStorageSchema {
protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) {
$schema = parent::getEntitySchema($entity_type, $reset);
$schema['node_field_data']['indexes'] += array(
'node__frontpage' => array('promote', 'status', 'sticky', 'created'),
'node__status_type' => array('status', 'type', 'nid'),
'node__title_type' => array('title', array('type', 4)),
);
$schema['node_field_data']['indexes'] += [
'node__frontpage' => ['promote', 'status', 'sticky', 'created'],
'node__title_type' => ['title', ['type', 4]],
];
return $schema;
}
@@ -17,17 +17,7 @@ class NodeTranslationHandler extends ContentTranslationHandler {
public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) {
parent::entityFormAlter($form, $form_state, $entity);
// Move the translation fieldset to a vertical tab.
if (isset($form['content_translation'])) {
$form['content_translation'] += array(
'#group' => 'advanced',
'#attributes' => array(
'class' => array('node-translation-options'),
),
);
$form['content_translation']['#weight'] = 100;
// We do not need to show these values on node forms: they inherit the
// basic node property values.
$form['content_translation']['status']['#access'] = FALSE;
@@ -49,7 +39,7 @@ class NodeTranslationHandler extends ContentTranslationHandler {
}
}
if (isset($status_translatable)) {
foreach (array('publish', 'unpublish', 'submit') as $button) {
foreach (['publish', 'unpublish', 'submit'] as $button) {
if (isset($form['actions'][$button])) {
$form['actions'][$button]['#value'] .= ' ' . ($status_translatable ? t('(this translation)') : t('(all translations)'));
}
@@ -63,7 +53,7 @@ class NodeTranslationHandler extends ContentTranslationHandler {
*/
protected function entityFormTitle(EntityInterface $entity) {
$type_name = node_get_type_label($entity);
return t('<em>Edit @type</em> @title', array('@type' => $type_name, '@title' => $entity->label()));
return t('<em>Edit @type</em> @title', ['@type' => $type_name, '@title' => $entity->label()]);
}
/**
@@ -21,7 +21,6 @@ class NodeTypeAccessControlHandler extends EntityAccessControlHandler {
switch ($operation) {
case 'view':
return AccessResult::allowedIfHasPermission($account, 'access content');
break;
case 'delete':
if ($entity->isLocked()) {
@@ -34,7 +33,7 @@ class NodeTypeAccessControlHandler extends EntityAccessControlHandler {
default:
return parent::checkAccess($entity, $operation, $account);
break;
}
}
+53 -53
View File
@@ -54,134 +54,134 @@ class NodeTypeForm extends BundleEntityFormBase {
// get the default values for workflow settings.
// @todo Make it possible to get default values without an entity.
// https://www.drupal.org/node/2318187
$node = $this->entityManager->getStorage('node')->create(array('type' => $type->uuid()));
$node = $this->entityManager->getStorage('node')->create(['type' => $type->uuid()]);
}
else {
$form['#title'] = $this->t('Edit %label content type', array('%label' => $type->label()));
$form['#title'] = $this->t('Edit %label content type', ['%label' => $type->label()]);
$fields = $this->entityManager->getFieldDefinitions('node', $type->id());
// Create a node to get the current values for workflow settings fields.
$node = $this->entityManager->getStorage('node')->create(array('type' => $type->id()));
$node = $this->entityManager->getStorage('node')->create(['type' => $type->id()]);
}
$form['name'] = array(
$form['name'] = [
'#title' => t('Name'),
'#type' => 'textfield',
'#default_value' => $type->label(),
'#description' => t('The human-readable name of this content type. This text will be displayed as part of the list on the <em>Add content</em> page. This name must be unique.'),
'#required' => TRUE,
'#size' => 30,
);
];
$form['type'] = array(
$form['type'] = [
'#type' => 'machine_name',
'#default_value' => $type->id(),
'#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
'#disabled' => $type->isLocked(),
'#machine_name' => array(
'#machine_name' => [
'exists' => ['Drupal\node\Entity\NodeType', 'load'],
'source' => array('name'),
),
'#description' => t('A unique machine-readable name for this content type. It must only contain lowercase letters, numbers, and underscores. This name will be used for constructing the URL of the %node-add page, in which underscores will be converted into hyphens.', array(
'source' => ['name'],
],
'#description' => t('A unique machine-readable name for this content type. It must only contain lowercase letters, numbers, and underscores. This name will be used for constructing the URL of the %node-add page, in which underscores will be converted into hyphens.', [
'%node-add' => t('Add content'),
)),
);
]),
];
$form['description'] = array(
$form['description'] = [
'#title' => t('Description'),
'#type' => 'textarea',
'#default_value' => $type->getDescription(),
'#description' => t('This text will be displayed on the <em>Add new content</em> page.'),
);
];
$form['additional_settings'] = array(
$form['additional_settings'] = [
'#type' => 'vertical_tabs',
'#attached' => array(
'library' => array('node/drupal.content_types'),
),
);
'#attached' => [
'library' => ['node/drupal.content_types'],
],
];
$form['submission'] = array(
$form['submission'] = [
'#type' => 'details',
'#title' => t('Submission form settings'),
'#group' => 'additional_settings',
'#open' => TRUE,
);
$form['submission']['title_label'] = array(
];
$form['submission']['title_label'] = [
'#title' => t('Title field label'),
'#type' => 'textfield',
'#default_value' => $fields['title']->getLabel(),
'#required' => TRUE,
);
$form['submission']['preview_mode'] = array(
];
$form['submission']['preview_mode'] = [
'#type' => 'radios',
'#title' => t('Preview before submitting'),
'#default_value' => $type->getPreviewMode(),
'#options' => array(
'#options' => [
DRUPAL_DISABLED => t('Disabled'),
DRUPAL_OPTIONAL => t('Optional'),
DRUPAL_REQUIRED => t('Required'),
),
);
$form['submission']['help'] = array(
],
];
$form['submission']['help'] = [
'#type' => 'textarea',
'#title' => t('Explanation or submission guidelines'),
'#default_value' => $type->getHelp(),
'#description' => t('This text will be displayed at the top of the page when creating or editing content of this type.'),
);
$form['workflow'] = array(
];
$form['workflow'] = [
'#type' => 'details',
'#title' => t('Publishing options'),
'#group' => 'additional_settings',
);
$workflow_options = array(
];
$workflow_options = [
'status' => $node->status->value,
'promote' => $node->promote->value,
'sticky' => $node->sticky->value,
'revision' => $type->isNewRevision(),
);
];
// Prepare workflow options to be used for 'checkboxes' form element.
$keys = array_keys(array_filter($workflow_options));
$workflow_options = array_combine($keys, $keys);
$form['workflow']['options'] = array(
$form['workflow']['options'] = [
'#type' => 'checkboxes',
'#title' => t('Default options'),
'#default_value' => $workflow_options,
'#options' => array(
'#options' => [
'status' => t('Published'),
'promote' => t('Promoted to front page'),
'sticky' => t('Sticky at top of lists'),
'revision' => t('Create new revision'),
),
],
'#description' => t('Users with the <em>Administer content</em> permission will be able to override these options.'),
);
];
if ($this->moduleHandler->moduleExists('language')) {
$form['language'] = array(
$form['language'] = [
'#type' => 'details',
'#title' => t('Language settings'),
'#group' => 'additional_settings',
);
];
$language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('node', $type->id());
$form['language']['language_configuration'] = array(
$form['language']['language_configuration'] = [
'#type' => 'language_configuration',
'#entity_information' => array(
'#entity_information' => [
'entity_type' => 'node',
'bundle' => $type->id(),
),
],
'#default_value' => $language_configuration,
);
];
}
$form['display'] = array(
$form['display'] = [
'#type' => 'details',
'#title' => t('Display settings'),
'#group' => 'additional_settings',
);
$form['display']['display_submitted'] = array(
];
$form['display']['display_submitted'] = [
'#type' => 'checkbox',
'#title' => t('Display author and date information'),
'#default_value' => $type->displaySubmitted(),
'#description' => t('Author username and publish date will be displayed.'),
);
];
return $this->protectBundleIdElement($form);
}
@@ -205,7 +205,7 @@ class NodeTypeForm extends BundleEntityFormBase {
$id = trim($form_state->getValue('type'));
// '0' is invalid, since elsewhere we check it using empty().
if ($id == '0') {
$form_state->setErrorByName('type', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", array('%invalid' => $id)));
$form_state->setErrorByName('type', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", ['%invalid' => $id]));
}
}
@@ -214,13 +214,13 @@ class NodeTypeForm extends BundleEntityFormBase {
*/
public function save(array $form, FormStateInterface $form_state) {
$type = $this->entity;
$type->setNewRevision($form_state->getValue(array('options', 'revision')));
$type->setNewRevision($form_state->getValue(['options', 'revision']));
$type->set('type', trim($type->id()));
$type->set('name', trim($type->label()));
$status = $type->save();
$t_args = array('%name' => $type->label());
$t_args = ['%name' => $type->label()];
if ($status == SAVED_UPDATED) {
drupal_set_message(t('The content type %name has been updated.', $t_args));
@@ -228,7 +228,7 @@ class NodeTypeForm extends BundleEntityFormBase {
elseif ($status == SAVED_NEW) {
node_add_body_field($type);
drupal_set_message(t('The content type %name has been added.', $t_args));
$context = array_merge($t_args, array('link' => $type->link($this->t('View'), 'collection')));
$context = array_merge($t_args, ['link' => $type->link($this->t('View'), 'collection')]);
$this->logger('node')->notice('Added content type %name.', $context);
}
@@ -242,8 +242,8 @@ class NodeTypeForm extends BundleEntityFormBase {
// Update workflow options.
// @todo Make it possible to get default values without an entity.
// https://www.drupal.org/node/2318187
$node = $this->entityManager->getStorage('node')->create(array('type' => $type->id()));
foreach (array('status', 'promote', 'sticky') as $field_name) {
$node = $this->entityManager->getStorage('node')->create(['type' => $type->id()]);
foreach (['status', 'promote', 'sticky'] as $field_name) {
$value = (bool) $form_state->getValue(['options', $field_name]);
if ($node->$field_name->value != $value) {
$fields[$field_name]->getConfig($type->id())->setDefaultValue($value)->save();
+7 -2
View File
@@ -3,11 +3,12 @@
namespace Drupal\node;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\RevisionableEntityBundleInterface;
/**
* Provides an interface defining a node type entity.
*/
interface NodeTypeInterface extends ConfigEntityInterface {
interface NodeTypeInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface {
/**
* Determines whether the node type is locked.
@@ -22,13 +23,17 @@ interface NodeTypeInterface extends ConfigEntityInterface {
*
* @return bool
* TRUE if a new revision should be created by default.
*
* @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use
* Drupal\Core\Entity\RevisionableEntityBundleInterface::shouldCreateNewRevision()
* instead.
*/
public function isNewRevision();
/**
* Sets whether a new revision should be created by default.
*
* @param bool $new_revision_
* @param bool $new_revision
* TRUE if a new revision should be created by default.
*/
public function setNewRevision($new_revision);
@@ -18,10 +18,10 @@ class NodeTypeListBuilder extends ConfigEntityListBuilder {
*/
public function buildHeader() {
$header['title'] = t('Name');
$header['description'] = array(
$header['description'] = [
'data' => t('Description'),
'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
);
'class' => [RESPONSIVE_PRIORITY_MEDIUM],
];
return $header + parent::buildHeader();
}
@@ -29,10 +29,10 @@ class NodeTypeListBuilder extends ConfigEntityListBuilder {
* {@inheritdoc}
*/
public function buildRow(EntityInterface $entity) {
$row['title'] = array(
$row['title'] = [
'data' => $entity->label(),
'class' => array('menu-label'),
);
'class' => ['menu-label'],
];
$row['description']['data'] = ['#markup' => $entity->getDescription()];
return $row + parent::buildRow($entity);
}
+20 -20
View File
@@ -28,25 +28,25 @@ class NodeViewBuilder extends EntityViewBuilder {
$display = $displays[$bundle];
if ($display->getComponent('links')) {
$build[$id]['links'] = array(
$build[$id]['links'] = [
'#lazy_builder' => [get_called_class() . '::renderLinks', [
$entity->id(),
$view_mode,
$entity->language()->getId(),
!empty($entity->in_preview),
]],
);
];
}
// Add Language field text element to node render array.
if ($display->getComponent('langcode')) {
$build[$id]['langcode'] = array(
$build[$id]['langcode'] = [
'#type' => 'item',
'#title' => t('Language'),
'#markup' => $entity->language()->getName(),
'#prefix' => '<div id="field-language-display">',
'#suffix' => '</div>'
);
];
}
}
}
@@ -81,21 +81,21 @@ class NodeViewBuilder extends EntityViewBuilder {
* A renderable array representing the node links.
*/
public static function renderLinks($node_entity_id, $view_mode, $langcode, $is_in_preview) {
$links = array(
$links = [
'#theme' => 'links__node',
'#pre_render' => array('drupal_pre_render_links'),
'#attributes' => array('class' => array('links', 'inline')),
);
'#pre_render' => ['drupal_pre_render_links'],
'#attributes' => ['class' => ['links', 'inline']],
];
if (!$is_in_preview) {
$entity = Node::load($node_entity_id)->getTranslation($langcode);
$links['node'] = static::buildLinks($entity, $view_mode);
// Allow other modules to alter the node links.
$hook_context = array(
$hook_context = [
'view_mode' => $view_mode,
'langcode' => $langcode,
);
];
\Drupal::moduleHandler()->alter('node_links', $links, $entity, $hook_context);
}
return $links;
@@ -113,30 +113,30 @@ class NodeViewBuilder extends EntityViewBuilder {
* An array that can be processed by drupal_pre_render_links().
*/
protected static function buildLinks(NodeInterface $entity, $view_mode) {
$links = array();
$links = [];
// Always display a read more link on teasers because we have no way
// to know when a teaser view is different than a full view.
if ($view_mode == 'teaser') {
$node_title_stripped = strip_tags($entity->label());
$links['node-readmore'] = array(
'title' => t('Read more<span class="visually-hidden"> about @title</span>', array(
$links['node-readmore'] = [
'title' => t('Read more<span class="visually-hidden"> about @title</span>', [
'@title' => $node_title_stripped,
)),
]),
'url' => $entity->urlInfo(),
'language' => $entity->language(),
'attributes' => array(
'attributes' => [
'rel' => 'tag',
'title' => $node_title_stripped,
),
);
],
];
}
return array(
return [
'#theme' => 'links__node__node',
'#links' => $links,
'#attributes' => array('class' => array('links', 'inline')),
);
'#attributes' => ['class' => ['links', 'inline']],
];
}
/**
+114 -114
View File
@@ -39,15 +39,15 @@ class NodeViewsData extends EntityViewsData {
// Use status = 1 instead of status <> 0 in WHERE statement.
$data['node_field_data']['status']['filter']['use_equal'] = TRUE;
$data['node_field_data']['status_extra'] = array(
$data['node_field_data']['status_extra'] = [
'title' => $this->t('Published status or admin user'),
'help' => $this->t('Filters out unpublished content if the current user cannot view it.'),
'filter' => array(
'filter' => [
'field' => 'status',
'id' => 'node_status',
'label' => $this->t('Published status or admin user'),
),
);
],
];
$data['node_field_data']['promote']['help'] = $this->t('A boolean indicating whether the node is visible on the front page.');
$data['node_field_data']['promote']['filter']['label'] = $this->t('Promoted to front page status');
@@ -58,133 +58,133 @@ class NodeViewsData extends EntityViewsData {
$data['node_field_data']['sticky']['filter']['type'] = 'yes-no';
$data['node_field_data']['sticky']['sort']['help'] = $this->t('Whether or not the content is sticky. To list sticky content first, set this to descending.');
$data['node']['path'] = array(
'field' => array(
$data['node']['path'] = [
'field' => [
'title' => $this->t('Path'),
'help' => $this->t('The aliased path to this content.'),
'id' => 'node_path',
),
);
],
];
$data['node']['node_bulk_form'] = array(
$data['node']['node_bulk_form'] = [
'title' => $this->t('Node operations bulk form'),
'help' => $this->t('Add a form element that lets you run operations on multiple nodes.'),
'field' => array(
'field' => [
'id' => 'node_bulk_form',
),
);
],
];
// Bogus fields for aliasing purposes.
// @todo Add similar support to any date field
// @see https://www.drupal.org/node/2337507
$data['node_field_data']['created_fulldate'] = array(
$data['node_field_data']['created_fulldate'] = [
'title' => $this->t('Created date'),
'help' => $this->t('Date in the form of CCYYMMDD.'),
'argument' => array(
'argument' => [
'field' => 'created',
'id' => 'date_fulldate',
),
);
],
];
$data['node_field_data']['created_year_month'] = array(
$data['node_field_data']['created_year_month'] = [
'title' => $this->t('Created year + month'),
'help' => $this->t('Date in the form of YYYYMM.'),
'argument' => array(
'argument' => [
'field' => 'created',
'id' => 'date_year_month',
),
);
],
];
$data['node_field_data']['created_year'] = array(
$data['node_field_data']['created_year'] = [
'title' => $this->t('Created year'),
'help' => $this->t('Date in the form of YYYY.'),
'argument' => array(
'argument' => [
'field' => 'created',
'id' => 'date_year',
),
);
],
];
$data['node_field_data']['created_month'] = array(
$data['node_field_data']['created_month'] = [
'title' => $this->t('Created month'),
'help' => $this->t('Date in the form of MM (01 - 12).'),
'argument' => array(
'argument' => [
'field' => 'created',
'id' => 'date_month',
),
);
],
];
$data['node_field_data']['created_day'] = array(
$data['node_field_data']['created_day'] = [
'title' => $this->t('Created day'),
'help' => $this->t('Date in the form of DD (01 - 31).'),
'argument' => array(
'argument' => [
'field' => 'created',
'id' => 'date_day',
),
);
],
];
$data['node_field_data']['created_week'] = array(
$data['node_field_data']['created_week'] = [
'title' => $this->t('Created week'),
'help' => $this->t('Date in the form of WW (01 - 53).'),
'argument' => array(
'argument' => [
'field' => 'created',
'id' => 'date_week',
),
);
],
];
$data['node_field_data']['changed_fulldate'] = array(
$data['node_field_data']['changed_fulldate'] = [
'title' => $this->t('Updated date'),
'help' => $this->t('Date in the form of CCYYMMDD.'),
'argument' => array(
'argument' => [
'field' => 'changed',
'id' => 'date_fulldate',
),
);
],
];
$data['node_field_data']['changed_year_month'] = array(
$data['node_field_data']['changed_year_month'] = [
'title' => $this->t('Updated year + month'),
'help' => $this->t('Date in the form of YYYYMM.'),
'argument' => array(
'argument' => [
'field' => 'changed',
'id' => 'date_year_month',
),
);
],
];
$data['node_field_data']['changed_year'] = array(
$data['node_field_data']['changed_year'] = [
'title' => $this->t('Updated year'),
'help' => $this->t('Date in the form of YYYY.'),
'argument' => array(
'argument' => [
'field' => 'changed',
'id' => 'date_year',
),
);
],
];
$data['node_field_data']['changed_month'] = array(
$data['node_field_data']['changed_month'] = [
'title' => $this->t('Updated month'),
'help' => $this->t('Date in the form of MM (01 - 12).'),
'argument' => array(
'argument' => [
'field' => 'changed',
'id' => 'date_month',
),
);
],
];
$data['node_field_data']['changed_day'] = array(
$data['node_field_data']['changed_day'] = [
'title' => $this->t('Updated day'),
'help' => $this->t('Date in the form of DD (01 - 31).'),
'argument' => array(
'argument' => [
'field' => 'changed',
'id' => 'date_day',
),
);
],
];
$data['node_field_data']['changed_week'] = array(
$data['node_field_data']['changed_week'] = [
'title' => $this->t('Updated week'),
'help' => $this->t('Date in the form of WW (01 - 53).'),
'argument' => array(
'argument' => [
'field' => 'changed',
'id' => 'date_week',
),
);
],
];
$data['node_field_data']['uid']['help'] = $this->t('The user authoring the content. If you need more fields than the uid add the content: author relationship');
$data['node_field_data']['uid']['filter']['id'] = 'user_name';
@@ -192,13 +192,13 @@ class NodeViewsData extends EntityViewsData {
$data['node_field_data']['uid']['relationship']['help'] = $this->t('Relate content to the user who created it.');
$data['node_field_data']['uid']['relationship']['label'] = $this->t('author');
$data['node']['node_listing_empty'] = array(
$data['node']['node_listing_empty'] = [
'title' => $this->t('Empty Node Frontpage behavior'),
'help' => $this->t('Provides a link to the node add overview page.'),
'area' => array(
'area' => [
'id' => 'node_listing_empty',
),
);
],
];
$data['node_field_data']['uid_revision']['title'] = $this->t('User has a revision');
$data['node_field_data']['uid_revision']['help'] = $this->t('All nodes where a certain user has a revision');
@@ -225,19 +225,19 @@ class NodeViewsData extends EntityViewsData {
$data['node_field_revision']['nid']['relationship']['title'] = $this->t('Content');
$data['node_field_revision']['nid']['relationship']['label'] = $this->t('Get the actual content from a content revision.');
$data['node_field_revision']['vid'] = array(
'argument' => array(
$data['node_field_revision']['vid'] = [
'argument' => [
'id' => 'node_vid',
'numeric' => TRUE,
),
'relationship' => array(
],
'relationship' => [
'id' => 'standard',
'base' => 'node_field_data',
'base field' => 'vid',
'title' => $this->t('Content'),
'label' => $this->t('Get the actual content from a content revision.'),
),
) + $data['node_field_revision']['vid'];
],
] + $data['node_field_revision']['vid'];
$data['node_field_revision']['langcode']['help'] = $this->t('The language the original content is in.');
@@ -259,52 +259,52 @@ class NodeViewsData extends EntityViewsData {
$data['node_field_revision']['langcode']['help'] = $this->t('The language of the content or translation.');
$data['node_field_revision']['link_to_revision'] = array(
'field' => array(
$data['node_field_revision']['link_to_revision'] = [
'field' => [
'title' => $this->t('Link to revision'),
'help' => $this->t('Provide a simple link to the revision.'),
'id' => 'node_revision_link',
'click sortable' => FALSE,
),
);
],
];
$data['node_field_revision']['revert_revision'] = array(
'field' => array(
$data['node_field_revision']['revert_revision'] = [
'field' => [
'title' => $this->t('Link to revert revision'),
'help' => $this->t('Provide a simple link to revert to the revision.'),
'id' => 'node_revision_link_revert',
'click sortable' => FALSE,
),
);
],
];
$data['node_field_revision']['delete_revision'] = array(
'field' => array(
$data['node_field_revision']['delete_revision'] = [
'field' => [
'title' => $this->t('Link to delete revision'),
'help' => $this->t('Provide a simple link to delete the content revision.'),
'id' => 'node_revision_link_delete',
'click sortable' => FALSE,
),
);
],
];
// Define the base group of this table. Fields that don't have a group defined
// will go into this field by default.
$data['node_access']['table']['group'] = $this->t('Content access');
// For other base tables, explain how we join.
$data['node_access']['table']['join'] = array(
'node_field_data' => array(
$data['node_access']['table']['join'] = [
'node_field_data' => [
'left_field' => 'nid',
'field' => 'nid',
),
);
$data['node_access']['nid'] = array(
],
];
$data['node_access']['nid'] = [
'title' => $this->t('Access'),
'help' => $this->t('Filter by access.'),
'filter' => array(
'filter' => [
'id' => 'node_access',
'help' => $this->t('Filter for content by view access. <strong>Not necessary if you are using node as your base table.</strong>'),
),
);
],
];
// Add search table, fields, filters, etc., but only if a page using the
// node_search plugin is enabled.
@@ -324,61 +324,61 @@ class NodeViewsData extends EntityViewsData {
// Automatically join to the node table (or actually, node_field_data).
// Use a Views table alias to allow other modules to use this table too,
// if they use the search index.
$data['node_search_index']['table']['join'] = array(
'node_field_data' => array(
$data['node_search_index']['table']['join'] = [
'node_field_data' => [
'left_field' => 'nid',
'field' => 'sid',
'table' => 'search_index',
'extra' => "node_search_index.type = 'node_search' AND node_search_index.langcode = node_field_data.langcode",
)
);
]
];
$data['node_search_total']['table']['join'] = array(
'node_search_index' => array(
$data['node_search_total']['table']['join'] = [
'node_search_index' => [
'left_field' => 'word',
'field' => 'word',
),
);
],
];
$data['node_search_dataset']['table']['join'] = array(
'node_field_data' => array(
$data['node_search_dataset']['table']['join'] = [
'node_field_data' => [
'left_field' => 'sid',
'left_table' => 'node_search_index',
'field' => 'sid',
'table' => 'search_dataset',
'extra' => 'node_search_index.type = node_search_dataset.type AND node_search_index.langcode = node_search_dataset.langcode',
'type' => 'INNER',
),
);
],
];
$data['node_search_index']['score'] = array(
$data['node_search_index']['score'] = [
'title' => $this->t('Score'),
'help' => $this->t('The score of the search item. This will not be used if the search filter is not also present.'),
'field' => array(
'field' => [
'id' => 'search_score',
'float' => TRUE,
'no group by' => TRUE,
),
'sort' => array(
],
'sort' => [
'id' => 'search_score',
'no group by' => TRUE,
),
);
],
];
$data['node_search_index']['keys'] = array(
$data['node_search_index']['keys'] = [
'title' => $this->t('Search Keywords'),
'help' => $this->t('The keywords to search for.'),
'filter' => array(
'filter' => [
'id' => 'search_keywords',
'no group by' => TRUE,
'search_type' => 'node_search',
),
'argument' => array(
],
'argument' => [
'id' => 'search',
'no group by' => TRUE,
'search_type' => 'node_search',
),
);
],
];
}
}
@@ -67,9 +67,9 @@ class AssignOwnerNode extends ConfigurableActionBase implements ContainerFactory
* {@inheritdoc}
*/
public function defaultConfiguration() {
return array(
return [
'owner_uid' => '',
);
];
}
/**
@@ -81,34 +81,34 @@ class AssignOwnerNode extends ConfigurableActionBase implements ContainerFactory
// Use dropdown for fewer than 200 users; textbox for more than that.
if (intval($count) < 200) {
$options = array();
$options = [];
$result = $this->connection->query("SELECT uid, name FROM {users_field_data} WHERE uid > 0 AND default_langcode = 1 ORDER BY name");
foreach ($result as $data) {
$options[$data->uid] = $data->name;
}
$form['owner_uid'] = array(
$form['owner_uid'] = [
'#type' => 'select',
'#title' => t('Username'),
'#default_value' => $this->configuration['owner_uid'],
'#options' => $options,
'#description' => $description,
);
];
}
else {
$form['owner_uid'] = array(
$form['owner_uid'] = [
'#type' => 'entity_autocomplete',
'#title' => t('Username'),
'#target_type' => 'user',
'#selection_setttings' => array(
'#selection_setttings' => [
'include_anonymous' => FALSE,
),
],
'#default_value' => User::load($this->configuration['owner_uid']),
// Validation is done in static::validateConfigurationForm().
'#validate_reference' => FALSE,
'#size' => '6',
'#maxlength' => '60',
'#description' => $description,
);
];
}
return $form;
}
@@ -117,7 +117,7 @@ class AssignOwnerNode extends ConfigurableActionBase implements ContainerFactory
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$exists = (bool) $this->connection->queryRange('SELECT 1 FROM {users_field_data} WHERE uid = :uid AND default_langcode = 1', 0, 1, array(':uid' => $form_state->getValue('owner_uid')))->fetchField();
$exists = (bool) $this->connection->queryRange('SELECT 1 FROM {users_field_data} WHERE uid = :uid AND default_langcode = 1', 0, 1, [':uid' => $form_state->getValue('owner_uid')])->fetchField();
if (!$exists) {
$form_state->setErrorByName('owner_uid', t('Enter a valid username.'));
}
@@ -85,7 +85,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
* {@inheritdoc}
*/
public function execute($object = NULL) {
$this->executeMultiple(array($object));
$this->executeMultiple([$object]);
}
/**
@@ -20,8 +20,7 @@ class PublishNode extends ActionBase {
* {@inheritdoc}
*/
public function execute($entity = NULL) {
$entity->status = NODE_PUBLISHED;
$entity->save();
$entity->setPublished()->save();
}
/**
@@ -20,8 +20,7 @@ class StickyNode extends ActionBase {
* {@inheritdoc}
*/
public function execute($entity = NULL) {
$entity->sticky = NODE_STICKY;
$entity->save();
$entity->setSticky(TRUE)->save();
}
/**
@@ -36,21 +36,21 @@ class UnpublishByKeywordNode extends ConfigurableActionBase {
* {@inheritdoc}
*/
public function defaultConfiguration() {
return array(
'keywords' => array(),
);
return [
'keywords' => [],
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form['keywords'] = array(
$form['keywords'] = [
'#title' => t('Keywords'),
'#type' => 'textarea',
'#description' => t('The content will be unpublished if it contains any of the phrases above. Use a case-sensitive, comma-separated list of phrases. Example: funny, bungee jumping, "Company, Inc."'),
'#default_value' => Tags::implode($this->configuration['keywords']),
);
];
return $form;
}
@@ -20,8 +20,7 @@ class UnpublishNode extends ActionBase {
* {@inheritdoc}
*/
public function execute($entity = NULL) {
$entity->status = NODE_NOT_PUBLISHED;
$entity->save();
$entity->setUnpublished()->save();
}
/**
@@ -20,8 +20,7 @@ class UnstickyNode extends ActionBase {
* {@inheritdoc}
*/
public function execute($entity = NULL) {
$entity->sticky = NODE_NOT_STICKY;
$entity->save();
$entity->setSticky(FALSE)->save();
}
/**
@@ -21,9 +21,9 @@ class SyndicateBlock extends BlockBase {
* {@inheritdoc}
*/
public function defaultConfiguration() {
return array(
return [
'block_count' => 10,
);
];
}
/**
@@ -37,10 +37,10 @@ class SyndicateBlock extends BlockBase {
* {@inheritdoc}
*/
public function build() {
return array(
return [
'#theme' => 'feed_icon',
'#url' => 'rss.xml',
);
];
}
}
@@ -64,17 +64,17 @@ class NodeType extends ConditionPluginBase implements ContainerFactoryPluginInte
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$options = array();
$options = [];
$node_types = $this->entityStorage->loadMultiple();
foreach ($node_types as $type) {
$options[$type->id()] = $type->label();
}
$form['bundles'] = array(
$form['bundles'] = [
'#title' => $this->t('Node types'),
'#type' => 'checkboxes',
'#options' => $options,
'#default_value' => $this->configuration['bundles'],
);
];
return parent::buildConfigurationForm($form, $form_state);
}
@@ -94,10 +94,10 @@ class NodeType extends ConditionPluginBase implements ContainerFactoryPluginInte
$bundles = $this->configuration['bundles'];
$last = array_pop($bundles);
$bundles = implode(', ', $bundles);
return $this->t('The node bundle is @bundles or @last', array('@bundles' => $bundles, '@last' => $last));
return $this->t('The node bundle is @bundles or @last', ['@bundles' => $bundles, '@last' => $last]);
}
$bundle = reset($this->configuration['bundles']);
return $this->t('The node bundle is @bundle', array('@bundle' => $bundle));
return $this->t('The node bundle is @bundle', ['@bundle' => $bundle]);
}
/**
@@ -115,7 +115,7 @@ class NodeType extends ConditionPluginBase implements ContainerFactoryPluginInte
* {@inheritdoc}
*/
public function defaultConfiguration() {
return array('bundles' => array()) + parent::defaultConfiguration();
return ['bundles' => []] + parent::defaultConfiguration();
}
}
@@ -4,6 +4,7 @@ namespace Drupal\node\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeInterface;
/**
* Provides specific access control for the node entity type.
@@ -38,7 +39,7 @@ class NodeSelection extends DefaultSelection {
// modules in use on the site. As long as one access control module is there,
// it is supposed to handle this check.
if (!$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'))) {
$query->condition('status', NODE_PUBLISHED);
$query->condition('status', NodeInterface::PUBLISHED);
}
return $query;
}
@@ -102,12 +102,12 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
*
* @var array
*/
protected $advanced = array(
'type' => array('column' => 'n.type'),
'language' => array('column' => 'i.langcode'),
'author' => array('column' => 'n.uid'),
'term' => array('column' => 'ti.tid', 'join' => array('table' => 'taxonomy_index', 'alias' => 'ti', 'condition' => 'n.nid = ti.nid')),
);
protected $advanced = [
'type' => ['column' => 'n.type'],
'language' => ['column' => 'i.langcode'],
'author' => ['column' => 'n.uid'],
'term' => ['column' => 'ti.tid', 'join' => ['table' => 'taxonomy_index', 'alias' => 'ti', 'condition' => 'n.nid = ti.nid']],
];
/**
* A constant for setting and checking the query string.
@@ -207,7 +207,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
}
}
return array();
return [];
}
/**
@@ -225,7 +225,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
// Build matching conditions.
$query = $this->database
->select('search_index', 'i', array('target' => 'replica'))
->select('search_index', 'i', ['target' => 'replica'])
->extend('Drupal\search\SearchQuery')
->extend('Drupal\Core\Database\Query\PagerSelectExtender');
$query->join('node_field_data', 'n', 'n.nid = i.sid AND n.langcode = i.langcode');
@@ -242,7 +242,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
// the keywords string, and some of which are separate conditions.
$parameters = $this->getParameters();
if (!empty($parameters['f']) && is_array($parameters['f'])) {
$filters = array();
$filters = [];
// Match any query value that is an expected option and a value
// separated by ':' like 'term:27'.
$pattern = '/^(' . implode('|', array_keys($this->advanced)) . '):([^ ]*)/i';
@@ -277,7 +277,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
$find = $query
// Add the language code of the indexed item to the result of the query,
// since the node will be rendered using the respective language.
->fields('i', array('langcode'))
->fields('i', ['langcode'])
// And since SearchQuery makes these into GROUP BY queries, if we add
// a field, for PostgreSQL we also need to make it an aggregate or a
// GROUP BY. In this case, we want GROUP BY.
@@ -289,7 +289,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
$status = $query->getStatus();
if ($status & SearchQuery::EXPRESSIONS_IGNORED) {
drupal_set_message($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => $this->searchSettings->get('and_or_limit'))), 'warning');
drupal_set_message($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', ['@count' => $this->searchSettings->get('and_or_limit')]), 'warning');
}
if ($status & SearchQuery::LOWER_CASE_OR) {
@@ -313,7 +313,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
* Array of search result item render arrays (empty array if no results).
*/
protected function prepareResults(StatementInterface $found) {
$results = array();
$results = [];
$node_storage = $this->entityManager->getStorage('node');
$node_render = $this->entityManager->getViewBuilder('node');
@@ -329,7 +329,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
$type = $this->entityManager->getStorage('node_type')->load($node->bundle());
unset($build['#theme']);
$build['#pre_render'][] = array($this, 'removeSubmittedInfo');
$build['#pre_render'][] = [$this, 'removeSubmittedInfo'];
// Fetch comments for snippet.
$rendered = $this->renderer->renderPlain($build);
@@ -339,13 +339,13 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
$extra = $this->moduleHandler->invokeAll('node_search_result', [$node]);
$language = $this->languageManager->getLanguage($item->langcode);
$username = array(
$username = [
'#theme' => 'username',
'#account' => $node->getOwner(),
);
];
$result = array(
'link' => $node->url('canonical', array('absolute' => TRUE, 'language' => $language)),
$result = [
'link' => $node->url('canonical', ['absolute' => TRUE, 'language' => $language]),
'type' => $type->label(),
'title' => $node->label(),
'node' => $node,
@@ -353,7 +353,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
'score' => $item->calculated_score,
'snippet' => search_excerpt($keys, $rendered, $item->langcode),
'langcode' => $node->language()->getId(),
);
];
$this->addCacheableDependency($node);
@@ -364,10 +364,10 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
$this->addCacheableDependency($node->getOwner());
if ($type->displaySubmitted()) {
$result += array(
$result += [
'user' => $this->renderer->renderPlain($username),
'date' => $node->getChangedTime(),
);
];
}
$results[] = $result;
@@ -411,7 +411,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
if (isset($values['join']) && !isset($tables[$values['join']['alias']])) {
$query->addJoin($values['join']['type'], $values['join']['table'], $values['join']['alias'], $values['join']['on']);
}
$arguments = isset($values['arguments']) ? $values['arguments'] : array();
$arguments = isset($values['arguments']) ? $values['arguments'] : [];
$query->addScore($values['score'], $arguments, $node_rank);
}
}
@@ -426,15 +426,15 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
// per cron run.
$limit = (int) $this->searchSettings->get('index.cron_limit');
$query = db_select('node', 'n', array('target' => 'replica'));
$query = db_select('node', 'n', ['target' => 'replica']);
$query->addField('n', 'nid');
$query->leftJoin('search_dataset', 'sd', 'sd.sid = n.nid AND sd.type = :type', array(':type' => $this->getPluginId()));
$query->leftJoin('search_dataset', 'sd', 'sd.sid = n.nid AND sd.type = :type', [':type' => $this->getPluginId()]);
$query->addExpression('CASE MAX(sd.reindex) WHEN NULL THEN 0 ELSE 1 END', 'ex');
$query->addExpression('MAX(sd.reindex)', 'ex2');
$query->condition(
$query->orConditionGroup()
->where('sd.sid IS NULL')
->condition('sd.reindex', 0, '<>')
->where('sd.sid IS NULL')
->condition('sd.reindex', 0, '<>')
);
$query->orderBy('ex', 'DESC')
->orderBy('ex2')
@@ -513,9 +513,9 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
*/
public function indexStatus() {
$total = $this->database->query('SELECT COUNT(*) FROM {node}')->fetchField();
$remaining = $this->database->query("SELECT COUNT(DISTINCT n.nid) FROM {node} n LEFT JOIN {search_dataset} sd ON sd.sid = n.nid AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0", array(':type' => $this->getPluginId()))->fetchField();
$remaining = $this->database->query("SELECT COUNT(DISTINCT n.nid) FROM {node} n LEFT JOIN {search_dataset} sd ON sd.sid = n.nid AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0", [':type' => $this->getPluginId()])->fetchField();
return array('remaining' => $remaining, 'total' => $total);
return ['remaining' => $remaining, 'total' => $total];
}
/**
@@ -526,100 +526,100 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
$keys = $this->getKeywords();
$used_advanced = !empty($parameters[self::ADVANCED_FORM]);
if ($used_advanced) {
$f = isset($parameters['f']) ? (array) $parameters['f'] : array();
$f = isset($parameters['f']) ? (array) $parameters['f'] : [];
$defaults = $this->parseAdvancedDefaults($f, $keys);
}
else {
$defaults = array('keys' => $keys);
$defaults = ['keys' => $keys];
}
$form['basic']['keys']['#default_value'] = $defaults['keys'];
// Add advanced search keyword-related boxes.
$form['advanced'] = array(
$form['advanced'] = [
'#type' => 'details',
'#title' => t('Advanced search'),
'#attributes' => array('class' => array('search-advanced')),
'#attributes' => ['class' => ['search-advanced']],
'#access' => $this->account && $this->account->hasPermission('use advanced search'),
'#open' => $used_advanced,
);
$form['advanced']['keywords-fieldset'] = array(
];
$form['advanced']['keywords-fieldset'] = [
'#type' => 'fieldset',
'#title' => t('Keywords'),
);
];
$form['advanced']['keywords'] = array(
$form['advanced']['keywords'] = [
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
);
];
$form['advanced']['keywords-fieldset']['keywords']['or'] = array(
$form['advanced']['keywords-fieldset']['keywords']['or'] = [
'#type' => 'textfield',
'#title' => t('Containing any of the words'),
'#size' => 30,
'#maxlength' => 255,
'#default_value' => isset($defaults['or']) ? $defaults['or'] : '',
);
];
$form['advanced']['keywords-fieldset']['keywords']['phrase'] = array(
$form['advanced']['keywords-fieldset']['keywords']['phrase'] = [
'#type' => 'textfield',
'#title' => t('Containing the phrase'),
'#size' => 30,
'#maxlength' => 255,
'#default_value' => isset($defaults['phrase']) ? $defaults['phrase'] : '',
);
];
$form['advanced']['keywords-fieldset']['keywords']['negative'] = array(
$form['advanced']['keywords-fieldset']['keywords']['negative'] = [
'#type' => 'textfield',
'#title' => t('Containing none of the words'),
'#size' => 30,
'#maxlength' => 255,
'#default_value' => isset($defaults['negative']) ? $defaults['negative'] : '',
);
];
// Add node types.
$types = array_map(array('\Drupal\Component\Utility\Html', 'escape'), node_type_get_names());
$form['advanced']['types-fieldset'] = array(
$types = array_map(['\Drupal\Component\Utility\Html', 'escape'], node_type_get_names());
$form['advanced']['types-fieldset'] = [
'#type' => 'fieldset',
'#title' => t('Types'),
);
$form['advanced']['types-fieldset']['type'] = array(
];
$form['advanced']['types-fieldset']['type'] = [
'#type' => 'checkboxes',
'#title' => t('Only of the type(s)'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $types,
'#default_value' => isset($defaults['type']) ? $defaults['type'] : array(),
);
'#default_value' => isset($defaults['type']) ? $defaults['type'] : [],
];
$form['advanced']['submit'] = array(
$form['advanced']['submit'] = [
'#type' => 'submit',
'#value' => t('Advanced search'),
'#prefix' => '<div class="action">',
'#suffix' => '</div>',
'#weight' => 100,
);
];
// Add languages.
$language_options = array();
$language_options = [];
$language_list = $this->languageManager->getLanguages(LanguageInterface::STATE_ALL);
foreach ($language_list as $langcode => $language) {
// Make locked languages appear special in the list.
$language_options[$langcode] = $language->isLocked() ? t('- @name -', array('@name' => $language->getName())) : $language->getName();
$language_options[$langcode] = $language->isLocked() ? t('- @name -', ['@name' => $language->getName()]) : $language->getName();
}
if (count($language_options) > 1) {
$form['advanced']['lang-fieldset'] = array(
$form['advanced']['lang-fieldset'] = [
'#type' => 'fieldset',
'#title' => t('Languages'),
);
$form['advanced']['lang-fieldset']['language'] = array(
];
$form['advanced']['lang-fieldset']['language'] = [
'#type' => 'checkboxes',
'#title' => t('Languages'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $language_options,
'#default_value' => isset($defaults['language']) ? $defaults['language'] : array(),
);
'#default_value' => isset($defaults['language']) ? $defaults['language'] : [],
];
}
}
@@ -633,7 +633,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
$advanced = FALSE;
// Collect extra filters.
$filters = array();
$filters = [];
if ($form_state->hasValue('type') && is_array($form_state->getValue('type'))) {
// Retrieve selected types - Form API sets the value of unselected
// checkboxes to 0.
@@ -680,7 +680,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
// Put the keywords and advanced parameters into GET parameters. Make sure
// to put keywords into the query even if it is empty, because the page
// controller uses that to decide it's time to check for search results.
$query = array('keys' => $keys);
$query = ['keys' => $keys];
if ($filters) {
$query['f'] = $filters;
}
@@ -707,13 +707,13 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
* a modified 'keys' element for the bare search keywords.
*/
protected function parseAdvancedDefaults($f, $keys) {
$defaults = array();
$defaults = [];
// Split out the advanced search parameters.
foreach ($f as $advanced) {
list($key, $value) = explode(':', $advanced, 2);
if (!isset($defaults[$key])) {
$defaults[$key] = array();
$defaults[$key] = [];
}
$defaults[$key][] = $value;
}
@@ -721,7 +721,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
// Split out the negative, phrase, and OR parts of keywords.
// For phrases, the form only supports one phrase.
$matches = array();
$matches = [];
$keys = ' ' . $keys . ' ';
if (preg_match('/ "([^"]+)" /', $keys, $matches)) {
$keys = str_replace($matches[0], ' ', $keys);
@@ -764,9 +764,9 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
* {@inheritdoc}
*/
public function defaultConfiguration() {
$configuration = array(
'rankings' => array(),
);
$configuration = [
'rankings' => [],
];
return $configuration;
}
@@ -775,34 +775,34 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
// Output form for defining rank factor weights.
$form['content_ranking'] = array(
$form['content_ranking'] = [
'#type' => 'details',
'#title' => t('Content ranking'),
'#open' => TRUE,
);
$form['content_ranking']['info'] = array(
];
$form['content_ranking']['info'] = [
'#markup' => '<p><em>' . $this->t('Influence is a numeric multiplier used in ordering search results. A higher number means the corresponding factor has more influence on search results; zero means the factor is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '</em></p>'
);
];
// Prepare table.
$header = [$this->t('Factor'), $this->t('Influence')];
$form['content_ranking']['rankings'] = array(
$form['content_ranking']['rankings'] = [
'#type' => 'table',
'#header' => $header,
);
];
// Note: reversed to reflect that higher number = higher ranking.
$range = range(0, 10);
$options = array_combine($range, $range);
foreach ($this->getRankings() as $var => $values) {
$form['content_ranking']['rankings'][$var]['name'] = array(
$form['content_ranking']['rankings'][$var]['name'] = [
'#markup' => $values['title'],
);
$form['content_ranking']['rankings'][$var]['value'] = array(
];
$form['content_ranking']['rankings'][$var]['value'] = [
'#type' => 'select',
'#options' => $options,
'#attributes' => ['aria-label' => $this->t("Influence of '@title'", ['@title' => $values['title']])],
'#default_value' => isset($this->configuration['rankings'][$var]) ? $this->configuration['rankings'][$var] : 0,
);
];
}
return $form;
}
@@ -3,11 +3,13 @@
namespace Drupal\node\Plugin\migrate;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\Plugin\MigrationDeriverTrait;
use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -33,10 +35,24 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
/**
* The CCK plugin manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
* @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface
*/
protected $cckPluginManager;
/**
* Already-instantiated field plugins, keyed by ID.
*
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[]
*/
protected $fieldPluginCache;
/**
* The field plugin manager.
*
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
*/
protected $fieldPluginManager;
/**
* Whether or not to include translations.
*
@@ -49,14 +65,17 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
*
* @param string $base_plugin_id
* The base plugin ID for the plugin ID.
* @param \Drupal\Component\Plugin\PluginManagerInterface $cck_manager
* @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager
* The CCK plugin manager.
* @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager
* The field plugin manager.
* @param bool $translations
* Whether or not to include translations.
*/
public function __construct($base_plugin_id, PluginManagerInterface $cck_manager, $translations) {
public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager, $translations) {
$this->basePluginId = $base_plugin_id;
$this->cckPluginManager = $cck_manager;
$this->fieldPluginManager = $field_manager;
$this->includeTranslations = $translations;
}
@@ -68,6 +87,7 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
return new static(
$base_plugin_id,
$container->get('plugin.manager.migrate.cckfield'),
$container->get('plugin.manager.migrate.field'),
$container->get('module_handler')->moduleExists('content_translation')
);
}
@@ -89,8 +109,18 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
return $this->derivatives;
}
// Read all CCK field instance definitions in the source database.
$fields = array();
$node_types = static::getSourcePlugin('d6_node_type');
try {
$node_types->checkRequirements();
}
catch (RequirementsException $e) {
// If the d6_node_type requirements failed, that means we do not have a
// Drupal source database configured - there is nothing to generate.
return $this->derivatives;
}
// Read all field instance definitions in the source database.
$fields = [];
try {
$source_plugin = static::getSourcePlugin('d6_field_instance');
$source_plugin->checkRequirements();
@@ -101,12 +131,12 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
}
catch (RequirementsException $e) {
// If checkRequirements() failed then the content module did not exist and
// we do not have any CCK fields. Therefore, $fields will be empty and
// we do not have any fields. Therefore, $fields will be empty and
// below we'll create a migration just for the node properties.
}
try {
foreach (static::getSourcePlugin('d6_node_type') as $row) {
foreach ($node_types as $row) {
$node_type = $row->getSourceProperty('type');
$values = $base_plugin_definition;
@@ -124,19 +154,31 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
$values['migration_dependencies']['required'][] = 'd6_node:' . $node_type;
}
/** @var \Drupal\migrate\Plugin\Migration $migration */
$migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values);
if (isset($fields[$node_type])) {
foreach ($fields[$node_type] as $field_name => $info) {
$field_type = $info['type'];
if ($this->cckPluginManager->hasDefinition($info['type'])) {
if (!isset($this->cckPluginCache[$field_type])) {
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, ['core' => 6], $migration);
try {
$plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration);
if (!isset($this->fieldPluginCache[$field_type])) {
$this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 6], $migration);
}
$this->cckPluginCache[$field_type]
->processCckFieldValues($migration, $field_name, $info);
$this->fieldPluginCache[$field_type]
->processFieldValues($migration, $field_name, $info);
}
else {
$migration->setProcessOfProperty($field_name, $field_name);
catch (PluginNotFoundException $ex) {
try {
$plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration);
if (!isset($this->cckPluginCache[$field_type])) {
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 6], $migration);
}
$this->cckPluginCache[$field_type]
->processCckFieldValues($migration, $field_name, $info);
}
catch (PluginNotFoundException $ex) {
$migration->setProcessOfProperty($field_name, $field_name);
}
}
}
}
@@ -3,11 +3,13 @@
namespace Drupal\node\Plugin\migrate;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\Plugin\MigrationDeriverTrait;
use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface;
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -33,30 +35,60 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
/**
* The CCK plugin manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
* @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface
*/
protected $cckPluginManager;
/**
* Already-instantiated field plugins, keyed by ID.
*
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[]
*/
protected $fieldPluginCache;
/**
* The field plugin manager.
*
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
*/
protected $fieldPluginManager;
/**
* Whether or not to include translations.
*
* @var bool
*/
protected $includeTranslations;
/**
* D7NodeDeriver constructor.
*
* @param string $base_plugin_id
* The base plugin ID for the plugin ID.
* @param \Drupal\Component\Plugin\PluginManagerInterface $cck_manager
* @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager
* The CCK plugin manager.
* @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager
* The field plugin manager.
* @param bool $translations
* Whether or not to include translations.
*/
public function __construct($base_plugin_id, PluginManagerInterface $cck_manager) {
public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager, $translations) {
$this->basePluginId = $base_plugin_id;
$this->cckPluginManager = $cck_manager;
$this->fieldPluginManager = $field_manager;
$this->includeTranslations = $translations;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
// Translations don't make sense unless we have content_translation.
return new static(
$base_plugin_id,
$container->get('plugin.manager.migrate.cckfield')
$container->get('plugin.manager.migrate.cckfield'),
$container->get('plugin.manager.migrate.field'),
$container->get('module_handler')->moduleExists('content_translation')
);
}
@@ -64,6 +96,21 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
if (in_array('translation', $base_plugin_definition['migration_tags']) && !$this->includeTranslations) {
// Refuse to generate anything.
return $this->derivatives;
}
$node_types = static::getSourcePlugin('d7_node_type');
try {
$node_types->checkRequirements();
}
catch (RequirementsException $e) {
// If the d7_node_type requirements failed, that means we do not have a
// Drupal source database configured - there is nothing to generate.
return $this->derivatives;
}
$fields = [];
try {
$source_plugin = static::getSourcePlugin('d7_field_instance');
@@ -83,7 +130,7 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
}
try {
foreach (static::getSourcePlugin('d7_node_type') as $row) {
foreach ($node_types as $row) {
$node_type = $row->getSourceProperty('type');
$values = $base_plugin_definition;
@@ -94,19 +141,37 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
$values['source']['node_type'] = $node_type;
$values['destination']['default_bundle'] = $node_type;
// If this migration is based on the d7_node_revision migration or
// is for translations of nodes, it should explicitly depend on the
// corresponding d7_node variant.
if ($base_plugin_definition['id'] == ['d7_node_revision'] || in_array('translation', $base_plugin_definition['migration_tags'])) {
$values['migration_dependencies']['required'][] = 'd7_node:' . $node_type;
}
$migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values);
if (isset($fields[$node_type])) {
foreach ($fields[$node_type] as $field_name => $info) {
$field_type = $info['type'];
if ($this->cckPluginManager->hasDefinition($field_type)) {
if (!isset($this->cckPluginCache[$field_type])) {
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, ['core' => 7], $migration);
try {
$plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
if (!isset($this->fieldPluginCache[$field_type])) {
$this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
}
$this->cckPluginCache[$field_type]
->processCckFieldValues($migration, $field_name, $info);
$this->fieldPluginCache[$field_type]
->processFieldValues($migration, $field_name, $info);
}
else {
$migration->setProcessOfProperty($field_name, $field_name);
catch (PluginNotFoundException $ex) {
try {
$plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration);
if (!isset($this->cckPluginCache[$field_type])) {
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
}
$this->cckPluginCache[$field_type]
->processCckFieldValues($migration, $field_name, $info);
}
catch (PluginNotFoundException $ex) {
$migration->setProcessOfProperty($field_name, $field_name);
}
}
}
}
@@ -119,7 +184,6 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
// MigrationPluginManager gathers up the migration definitions but we do
// not actually have a Drupal 7 source database.
}
return $this->derivatives;
}
@@ -15,7 +15,7 @@ class EntityNodeType extends EntityConfigBase {
/**
* {@inheritdoc}
*/
public function import(Row $row, array $old_destination_id_values = array()) {
public function import(Row $row, array $old_destination_id_values = []) {
$entity_ids = parent::import($row, $old_destination_id_values);
if ($row->getDestinationProperty('create_body')) {
$node_type = $this->storage->load(reset($entity_ids));
@@ -22,7 +22,7 @@ class NodeUpdate7008 extends ProcessPluginBase {
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
if ($value === 'administer nodes') {
return array($value, 'access content overview');
return [$value, 'access content overview'];
}
return $value;
}
@@ -3,8 +3,13 @@
namespace Drupal\node\Plugin\migrate\source\d6;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Drupal 6 node source from database.
@@ -34,6 +39,36 @@ class Node extends DrupalSqlBase {
*/
protected $fieldInfo;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandler
*/
protected $moduleHandler;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager, ModuleHandler $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager);
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$migration,
$container->get('state'),
$container->get('entity.manager'),
$container->get('module_handler')
);
}
/**
* {@inheritdoc}
*/
@@ -42,7 +77,7 @@ class Node extends DrupalSqlBase {
$query->innerJoin('node', 'n', static::JOIN);
$this->handleTranslations($query);
$query->fields('n', array(
$query->fields('n', [
'nid',
'type',
'language',
@@ -55,8 +90,8 @@ class Node extends DrupalSqlBase {
'sticky',
'tnid',
'translate',
))
->fields('nr', array(
])
->fields('nr', [
'title',
'body',
'teaser',
@@ -64,10 +99,17 @@ class Node extends DrupalSqlBase {
'timestamp',
'format',
'vid',
));
]);
$query->addField('n', 'uid', 'node_uid');
$query->addField('nr', 'uid', 'revision_uid');
// If the content_translation module is enabled, get the source langcode
// to fill the content_translation_source field.
if ($this->moduleHandler->moduleExists('content_translation')) {
$query->leftJoin('node', 'nt', 'n.tnid = nt.nid');
$query->addField('nt', 'language', 'source_langcode');
}
if (isset($this->configuration['node_type'])) {
$query->condition('n.type', $this->configuration['node_type']);
}
@@ -87,7 +129,7 @@ class Node extends DrupalSqlBase {
* {@inheritdoc}
*/
public function fields() {
$fields = array(
$fields = [
'nid' => $this->t('Node ID'),
'type' => $this->t('Type'),
'title' => $this->t('Title'),
@@ -105,7 +147,7 @@ class Node extends DrupalSqlBase {
'language' => $this->t('Language (fr, en, ...)'),
'tnid' => $this->t('The translation set id for this node'),
'timestamp' => $this->t('The timestamp the latest revision of this node was created.'),
);
];
return $fields;
}
@@ -261,7 +303,7 @@ class Node extends DrupalSqlBase {
/**
* Adapt our query for translations.
*
* @param \Drupal\Core\Database\Query\SelectInterface
* @param \Drupal\Core\Database\Query\SelectInterface $query
* The generated query.
*/
protected function handleTranslations(SelectInterface $query) {
@@ -22,11 +22,11 @@ class NodeRevision extends Node {
*/
public function fields() {
// Use all the node fields plus the vid that identifies the version.
return parent::fields() + array(
return parent::fields() + [
'vid' => t('The primary identifier for this version.'),
'log' => $this->t('Revision Log message'),
'timestamp' => $this->t('Revision timestamp'),
);
];
}
/**
@@ -40,7 +40,7 @@ class NodeType extends DrupalSqlBase {
*/
public function query() {
return $this->select('node_type', 't')
->fields('t', array(
->fields('t', [
'type',
'name',
'module',
@@ -54,7 +54,7 @@ class NodeType extends DrupalSqlBase {
'modified',
'locked',
'orig_type',
))
])
->orderBy('t.type');
}
@@ -62,7 +62,7 @@ class NodeType extends DrupalSqlBase {
* {@inheritdoc}
*/
public function fields() {
return array(
return [
'type' => $this->t('Machine name of the node type.'),
'name' => $this->t('Human name of the node type.'),
'module' => $this->t('The module providing the node type.'),
@@ -77,7 +77,7 @@ class NodeType extends DrupalSqlBase {
'locked' => $this->t('Flag.'),
'orig_type' => $this->t('The original type.'),
'teaser_length' => $this->t('Teaser length'),
);
];
}
/**
@@ -86,7 +86,7 @@ class NodeType extends DrupalSqlBase {
protected function initializeIterator() {
$this->teaserLength = $this->variableGet('teaser_length', 600);
$this->nodePreview = $this->variableGet('node_preview', 0);
$this->themeSettings = $this->variableGet('theme_settings', array());
$this->themeSettings = $this->variableGet('theme_settings', []);
return parent::initializeIterator();
}
@@ -98,15 +98,19 @@ class NodeType extends DrupalSqlBase {
$row->setSourceProperty('node_preview', $this->nodePreview);
$type = $row->getSourceProperty('type');
$source_options = $this->variableGet('node_options_' . $type, array('promote', 'sticky'));
$options = array();
foreach (array('promote', 'sticky', 'status', 'revision') as $item) {
$source_options = $this->variableGet('node_options_' . $type, ['promote', 'sticky']);
$options = [];
foreach (['promote', 'sticky', 'status', 'revision'] as $item) {
$options[$item] = in_array($item, $source_options);
}
$row->setSourceProperty('options', $options);
$submitted = isset($this->themeSettings['toggle_node_info_' . $type]) ? $this->themeSettings['toggle_node_info_' . $type] : FALSE;
$row->setSourceProperty('display_submitted', $submitted);
if ($default_node_menu = $this->variableGet('menu_default_node_menu', NULL)) {
$row->setSourceProperty('available_menus', [$default_node_menu]);
$row->setSourceProperty('parent', $default_node_menu . ':');
}
return parent::prepareRow($row);
}
@@ -16,12 +16,15 @@ class ViewMode extends ViewModeBase {
* {@inheritdoc}
*/
protected function initializeIterator() {
$rows = array();
$rows = [];
$result = $this->prepareQuery()->execute();
while ($field_row = $result->fetchAssoc()) {
$field_row['display_settings'] = unserialize($field_row['display_settings']);
foreach ($this->getViewModes() as $view_mode) {
if (isset($field_row['display_settings'][$view_mode]) && empty($field_row['display_settings'][$view_mode]['exclude'])) {
// Append to the return value if the row has display settings for this
// view mode and the view mode is neither hidden nor excluded.
// @see \Drupal\field\Plugin\migrate\source\d6\FieldInstancePerViewMode::initializeIterator()
if (isset($field_row['display_settings'][$view_mode]) && $field_row['display_settings'][$view_mode]['format'] != 'hidden' && empty($field_row['display_settings'][$view_mode]['exclude'])) {
if (!isset($rows[$view_mode])) {
$rows[$view_mode]['entity_type'] = 'node';
$rows[$view_mode]['view_mode'] = $view_mode;
@@ -38,9 +41,9 @@ class ViewMode extends ViewModeBase {
*/
public function query() {
$query = $this->select('content_node_field_instance', 'cnfi')
->fields('cnfi', array(
->fields('cnfi', [
'display_settings',
));
]);
return $query;
}
@@ -49,9 +52,9 @@ class ViewMode extends ViewModeBase {
* {@inheritdoc}
*/
public function fields() {
return array(
return [
'display_settings' => $this->t('Serialize data with display settings.'),
);
];
}
/**
@@ -33,7 +33,7 @@ abstract class ViewModeBase extends DrupalSqlBase {
* The view mode names.
*/
public function getViewModes() {
return array(
return [
0,
1,
2,
@@ -42,7 +42,7 @@ abstract class ViewModeBase extends DrupalSqlBase {
5,
'teaser',
'full',
);
];
}
}
@@ -2,8 +2,15 @@
namespace Drupal\node\Plugin\migrate\source\d7;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Drupal 7 node source from database.
@@ -14,6 +21,35 @@ use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
* )
*/
class Node extends FieldableEntity {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager);
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$migration,
$container->get('state'),
$container->get('entity.manager'),
$container->get('module_handler')
);
}
/**
* The join options between the node and the node_revisions table.
@@ -26,7 +62,7 @@ class Node extends FieldableEntity {
public function query() {
// Select node in its last revision.
$query = $this->select('node_revision', 'nr')
->fields('n', array(
->fields('n', [
'nid',
'type',
'language',
@@ -38,17 +74,25 @@ class Node extends FieldableEntity {
'sticky',
'tnid',
'translate',
))
->fields('nr', array(
])
->fields('nr', [
'vid',
'title',
'log',
'timestamp',
));
]);
$query->addField('n', 'uid', 'node_uid');
$query->addField('nr', 'uid', 'revision_uid');
$query->innerJoin('node', 'n', static::JOIN);
// If the content_translation module is enabled, get the source langcode
// to fill the content_translation_source field.
if ($this->moduleHandler->moduleExists('content_translation')) {
$query->leftJoin('node', 'nt', 'n.tnid = nt.nid');
$query->addField('nt', 'language', 'source_langcode');
}
$this->handleTranslations($query);
if (isset($this->configuration['node_type'])) {
$query->condition('n.type', $this->configuration['node_type']);
}
@@ -66,6 +110,11 @@ class Node extends FieldableEntity {
$vid = $row->getSourceProperty('vid');
$row->setSourceProperty($field, $this->getFieldValues('node', $field, $nid, $vid));
}
// Make sure we always have a translation set.
if ($row->getSourceProperty('tnid') == 0) {
$row->setSourceProperty('tnid', $row->getSourceProperty('nid'));
}
return parent::prepareRow($row);
}
@@ -73,7 +122,7 @@ class Node extends FieldableEntity {
* {@inheritdoc}
*/
public function fields() {
$fields = array(
$fields = [
'nid' => $this->t('Node ID'),
'type' => $this->t('Type'),
'title' => $this->t('Title'),
@@ -88,7 +137,7 @@ class Node extends FieldableEntity {
'language' => $this->t('Language (fr, en, ...)'),
'tnid' => $this->t('The translation set id for this node'),
'timestamp' => $this->t('The timestamp the latest revision of this node was created.'),
);
];
return $fields;
}
@@ -101,4 +150,22 @@ class Node extends FieldableEntity {
return $ids;
}
/**
* Adapt our query for translations.
*
* @param \Drupal\Core\Database\Query\SelectInterface $query
* The generated query.
*/
protected function handleTranslations(SelectInterface $query) {
// Check whether or not we want translations.
if (empty($this->configuration['translations'])) {
// No translations: Yield untranslated nodes, or default translations.
$query->where('n.tnid = 0 OR n.tnid = n.nid');
}
else {
// Translations: Yield only non-default translations.
$query->where('n.tnid <> 0 AND n.tnid <> n.nid');
}
}
}
@@ -22,11 +22,11 @@ class NodeRevision extends Node {
*/
public function fields() {
// Use all the node fields plus the vid that identifies the version.
return parent::fields() + array(
return parent::fields() + [
'vid' => t('The primary identifier for this version.'),
'log' => $this->t('Revision Log message'),
'timestamp' => $this->t('Revision timestamp'),
);
];
}
/**
@@ -40,7 +40,7 @@ class NodeType extends DrupalSqlBase {
* {@inheritdoc}
*/
public function fields() {
return array(
return [
'type' => $this->t('Machine name of the node type.'),
'name' => $this->t('Human name of the node type.'),
'description' => $this->t('Description of the node type.'),
@@ -53,7 +53,7 @@ class NodeType extends DrupalSqlBase {
'locked' => $this->t('Flag.'),
'orig_type' => $this->t('The original type.'),
'teaser_length' => $this->t('Teaser length'),
);
];
}
/**
@@ -73,9 +73,9 @@ class NodeType extends DrupalSqlBase {
$row->setSourceProperty('node_preview', $this->nodePreview);
$type = $row->getSourceProperty('type');
$source_options = $this->variableGet('node_options_' . $type, array('promote', 'sticky'));
$options = array();
foreach (array('promote', 'sticky', 'status', 'revision') as $item) {
$source_options = $this->variableGet('node_options_' . $type, ['promote', 'sticky']);
$options = [];
foreach (['promote', 'sticky', 'status', 'revision'] as $item) {
$options[$item] = in_array($item, $source_options);
}
$row->setSourceProperty('options', $options);
@@ -86,7 +86,7 @@ class NodeType extends DrupalSqlBase {
if ($this->moduleExists('field')) {
// Find body field for this node type.
$body = $this->select('field_config_instance', 'fci')
->fields('fci', array('data'))
->fields('fci', ['data'])
->condition('entity_type', 'node')
->condition('bundle', $row->getSourceProperty('type'))
->condition('field_name', 'body')
@@ -101,6 +101,12 @@ class NodeType extends DrupalSqlBase {
$row->setSourceProperty('display_submitted', $this->variableGet('node_submitted_' . $type, TRUE));
if ($menu_options = $this->variableGet('menu_options_' . $type, NULL)) {
$row->setSourceProperty('available_menus', $menu_options);
}
if ($parent = $this->variableGet('menu_parent_' . $type, NULL)) {
$row->setSourceProperty('parent', $parent . ':');
}
return parent::prepareRow($row);
}
@@ -59,19 +59,19 @@ class ListingEmpty extends AreaPluginBase {
public function render($empty = FALSE) {
$account = \Drupal::currentUser();
if (!$empty || !empty($this->options['empty'])) {
$element = array(
$element = [
'#theme' => 'links',
'#links' => array(
array(
'#links' => [
[
'url' => Url::fromRoute('node.add_page'),
'title' => $this->t('Add content'),
),
),
'#access' => $this->accessManager->checkNamedRoute('node.add_page', array(), $account),
);
],
],
'#access' => $this->accessManager->checkNamedRoute('node.add_page', [], $account),
];
return $element;
}
return array();
return [];
}
}
@@ -52,7 +52,7 @@ class Nid extends NumericArgument {
* Override the behavior of title(). Get the title of the node.
*/
public function titleQuery() {
$titles = array();
$titles = [];
$nodes = $this->nodeStorage->loadMultiple($this->value);
foreach ($nodes as $node) {
@@ -63,11 +63,11 @@ class Type extends StringArgument {
* Override the behavior of title(). Get the user friendly version of the
* node type.
*/
function title() {
public function title() {
return $this->node_type($this->argument);
}
function node_type($type_name) {
public function node_type($type_name) {
$type = $this->nodeTypeStorage->load($type_name);
$output = $type ? $type->label() : $this->t('Unknown content type');
return $output;
@@ -15,7 +15,7 @@ class UidRevision extends Uid {
public function query($group_by = FALSE) {
$this->ensureMyTable();
$placeholder = $this->placeholder();
$this->query->addWhereExpression(0, "$this->tableAlias.revision_uid = $placeholder OR ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nfr.revision_uid = $placeholder AND nr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $this->argument));
$this->query->addWhereExpression(0, "$this->tableAlias.uid = $placeholder OR ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nr.revision_uid = $placeholder AND nr.nid = $this->tableAlias.nid) > 0)", [$placeholder => $this->argument]);
}
}
@@ -39,7 +39,7 @@ class Vid extends NumericArgument {
* The plugin implementation definition.
* @param \Drupal\Core\Database\Connection $database
* Database Service Object.
* @param \Drupal\node\NodeStorageInterface
* @param \Drupal\node\NodeStorageInterface $node_storage
* The node storage.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, NodeStorageInterface $node_storage) {
@@ -66,10 +66,10 @@ class Vid extends NumericArgument {
* Override the behavior of title(). Get the title of the revision.
*/
public function titleQuery() {
$titles = array();
$titles = [];
$results = $this->database->query('SELECT nr.vid, nr.nid, npr.title FROM {node_revision} nr WHERE nr.vid IN ( :vids[] )', array(':vids[]' => $this->value))->fetchAllAssoc('vid', PDO::FETCH_ASSOC);
$nids = array();
$results = $this->database->query('SELECT nr.vid, nr.nid, npr.title FROM {node_revision} nr WHERE nr.vid IN ( :vids[] )', [':vids[]' => $this->value])->fetchAllAssoc('vid', PDO::FETCH_ASSOC);
$nids = [];
foreach ($results as $result) {
$nids[] = $result['nid'];
}
@@ -28,7 +28,7 @@ class Node extends FieldPluginBase {
// Don't add the additional fields to groupby
if (!empty($this->options['link_to_node'])) {
$this->additional_fields['nid'] = array('table' => 'node_field_data', 'field' => 'nid');
$this->additional_fields['nid'] = ['table' => 'node_field_data', 'field' => 'nid'];
}
}
@@ -37,7 +37,7 @@ class Node extends FieldPluginBase {
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['link_to_node'] = array('default' => isset($this->definition['link_to_node default']) ? $this->definition['link_to_node default'] : FALSE);
$options['link_to_node'] = ['default' => isset($this->definition['link_to_node default']) ? $this->definition['link_to_node default'] : FALSE];
return $options;
}
@@ -45,12 +45,12 @@ class Node extends FieldPluginBase {
* Provide link to node option
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
$form['link_to_node'] = array(
$form['link_to_node'] = [
'#title' => $this->t('Link this field to the original piece of content'),
'#description' => $this->t("Enable to override this field's links."),
'#type' => 'checkbox',
'#default_value' => !empty($this->options['link_to_node']),
);
];
parent::buildOptionsForm($form, $form_state);
}
@@ -31,7 +31,7 @@ class Path extends FieldPluginBase {
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['absolute'] = array('default' => FALSE);
$options['absolute'] = ['default' => FALSE];
return $options;
}
@@ -41,13 +41,13 @@ class Path extends FieldPluginBase {
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['absolute'] = array(
$form['absolute'] = [
'#type' => 'checkbox',
'#title' => $this->t('Use absolute link (begins with "http://")'),
'#default_value' => $this->options['absolute'],
'#description' => $this->t('Enable this option to output an absolute link. Required if you want to use the path as a link destination (as in "output this field as a link" above).'),
'#fieldset' => 'alter',
);
];
}
/**
@@ -63,9 +63,9 @@ class Path extends FieldPluginBase {
*/
public function render(ResultRow $values) {
$nid = $this->getValue($values, 'nid');
return array(
return [
'#markup' => \Drupal::url('entity.node.canonical', ['node' => $nid], ['absolute' => $this->options['absolute']]),
);
];
}
}
@@ -25,7 +25,7 @@ class Access extends FilterPluginBase {
*/
public function query() {
$account = $this->view->getUser();
if (!$account->hasPermission('administer nodes')) {
if (!$account->hasPermission('bypass node access')) {
$table = $this->ensureMyTable();
$grants = db_or();
foreach (node_access_grants('view', $account) as $realm => $gids) {
@@ -21,7 +21,7 @@ class UidRevision extends Name {
$args = array_values($this->value);
$this->query->addWhereExpression($this->options['group'], "$this->tableAlias.uid IN($placeholder) OR
((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nr.revision_uid IN ($placeholder) AND nr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $args),
((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nr.revision_uid IN ($placeholder) AND nr.nid = $this->tableAlias.nid) > 0)", [$placeholder => $args],
$args);
}
+16 -16
View File
@@ -27,7 +27,7 @@ class Rss extends RssPluginBase {
public $base_field = 'nid';
// Stores the nodes loaded with preRender.
public $nodes = array();
public $nodes = [];
/**
* {@inheritdoc}
@@ -74,7 +74,7 @@ class Rss extends RssPluginBase {
}
public function preRender($values) {
$nids = array();
$nids = [];
foreach ($values as $row) {
$nids[] = $row->{$this->field_alias};
}
@@ -103,23 +103,23 @@ class Rss extends RssPluginBase {
return;
}
$node->link = $node->url('canonical', array('absolute' => TRUE));
$node->rss_namespaces = array();
$node->rss_elements = array(
array(
$node->link = $node->url('canonical', ['absolute' => TRUE]);
$node->rss_namespaces = [];
$node->rss_elements = [
[
'key' => 'pubDate',
'value' => gmdate('r', $node->getCreatedTime()),
),
array(
],
[
'key' => 'dc:creator',
'value' => $node->getOwner()->getDisplayName(),
),
array(
],
[
'key' => 'guid',
'value' => $node->id() . ' at ' . $base_url,
'attributes' => array('isPermaLink' => 'false'),
),
);
'attributes' => ['isPermaLink' => 'false'],
],
];
// The node gets built and modules add to or modify $node->rss_elements
// and $node->rss_namespaces.
@@ -135,7 +135,7 @@ class Rss extends RssPluginBase {
elseif (function_exists('rdf_get_namespaces')) {
// Merge RDF namespaces in the XML namespaces in case they are used
// further in the RSS content.
$xml_rdf_namespaces = array();
$xml_rdf_namespaces = [];
foreach (rdf_get_namespaces() as $prefix => $uri) {
$xml_rdf_namespaces['xmlns:' . $prefix] = $uri;
}
@@ -153,12 +153,12 @@ class Rss extends RssPluginBase {
// template_preprocess_views_view_row_rss() can still access it.
$item->elements = &$node->rss_elements;
$item->nid = $node->id();
$build = array(
$build = [
'#theme' => $this->themeFunctions(),
'#view' => $this->view,
'#options' => $this->options,
'#row' => $item,
);
];
return $build;
}
@@ -28,16 +28,16 @@ class Node extends WizardPluginBase {
/**
* Set default values for the filters.
*/
protected $filters = array(
'status' => array(
protected $filters = [
'status' => [
'value' => TRUE,
'table' => 'node_field_data',
'field' => 'status',
'plugin_id' => 'boolean',
'entity_type' => 'node',
'entity_field' => 'status',
)
);
]
];
/**
* Overrides Drupal\views\Plugin\views\wizard\WizardPluginBase::getAvailableSorts().
@@ -48,16 +48,16 @@ class Node extends WizardPluginBase {
*/
public function getAvailableSorts() {
// You can't execute functions in properties, so override the method
return array(
'node_field_data-title:DESC' => $this->t('Title')
);
return [
'node_field_data-title:ASC' => $this->t('Title')
];
}
/**
* {@inheritdoc}
*/
protected function rowStyleOptions() {
$options = array();
$options = [];
$options['teasers'] = $this->t('teasers');
$options['full_posts'] = $this->t('full posts');
$options['titles'] = $this->t('titles');
@@ -110,22 +110,22 @@ class Node extends WizardPluginBase {
protected function defaultDisplayFiltersUser(array $form, FormStateInterface $form_state) {
$filters = parent::defaultDisplayFiltersUser($form, $form_state);
$tids = array();
if ($values = $form_state->getValue(array('show', 'tagged_with'))) {
$tids = [];
if ($values = $form_state->getValue(['show', 'tagged_with'])) {
foreach ($values as $value) {
$tids[] = $value['target_id'];
}
}
if (!empty($tids)) {
$vid = reset($form['displays']['show']['tagged_with']['#selection_settings']['target_bundles']);
$filters['tid'] = array(
$filters['tid'] = [
'id' => 'tid',
'table' => 'taxonomy_index',
'field' => 'tid',
'value' => $tids,
'vid' => $vid,
'plugin_id' => 'taxonomy_index_tid',
);
];
// If the user entered more than one valid term in the autocomplete
// field, they probably intended both of them to be applied.
if (count($tids) > 1) {
@@ -144,8 +144,8 @@ class Node extends WizardPluginBase {
*/
protected function pageDisplayOptions(array $form, FormStateInterface $form_state) {
$display_options = parent::pageDisplayOptions($form, $form_state);
$row_plugin = $form_state->getValue(array('page', 'style', 'row_plugin'));
$row_options = $form_state->getValue(array('page', 'style', 'row_options'), array());
$row_plugin = $form_state->getValue(['page', 'style', 'row_plugin']);
$row_options = $form_state->getValue(['page', 'style', 'row_options'], []);
$this->display_options_row($display_options, $row_plugin, $row_options);
return $display_options;
}
@@ -155,8 +155,8 @@ class Node extends WizardPluginBase {
*/
protected function blockDisplayOptions(array $form, FormStateInterface $form_state) {
$display_options = parent::blockDisplayOptions($form, $form_state);
$row_plugin = $form_state->getValue(array('block', 'style', 'row_plugin'));
$row_options = $form_state->getValue(array('block', 'style', 'row_options'), array());
$row_plugin = $form_state->getValue(['block', 'style', 'row_plugin']);
$row_options = $form_state->getValue(['block', 'style', 'row_options'], []);
$this->display_options_row($display_options, $row_plugin, $row_options);
return $display_options;
}
@@ -195,7 +195,7 @@ class Node extends WizardPluginBase {
parent::buildFilters($form, $form_state);
if (isset($form['displays']['show']['type'])) {
$selected_bundle = static::getSelected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
$selected_bundle = static::getSelected($form_state, ['show', 'type'], 'all', $form['displays']['show']['type']);
}
// Add the "tagged with" filter to the view.
@@ -217,13 +217,13 @@ class Node extends WizardPluginBase {
// entities. If a particular entity type (i.e., bundle) has been
// selected above, then we only search for taxonomy fields associated
// with that bundle. Otherwise, we use all bundles.
$bundles = array_keys(entity_get_bundles($this->entityTypeId));
$bundles = array_keys($this->bundleInfoService->getBundleInfo($this->entityTypeId));
// Double check that this is a real bundle before using it (since above
// we added a dummy option 'all' to the bundle list on the form).
if (isset($selected_bundle) && in_array($selected_bundle, $bundles)) {
$bundles = array($selected_bundle);
$bundles = [$selected_bundle];
}
$tag_fields = array();
$tag_fields = [];
foreach ($bundles as $bundle) {
$display = entity_get_form_display($this->entityTypeId, $bundle, 'default');
$taxonomy_fields = array_filter(\Drupal::entityManager()->getFieldDefinitions($this->entityTypeId, $bundle), function ($field_definition) {
@@ -253,7 +253,7 @@ class Node extends WizardPluginBase {
}
// Add the autocomplete textfield to the wizard.
$target_bundles = $tag_fields[$tag_field_name]->getSetting('handler_settings')['target_bundles'];
$form['displays']['show']['tagged_with'] = array(
$form['displays']['show']['tagged_with'] = [
'#type' => 'entity_autocomplete',
'#title' => $this->t('tagged with'),
'#target_type' => 'taxonomy_term',
@@ -261,7 +261,7 @@ class Node extends WizardPluginBase {
'#tags' => TRUE,
'#size' => 30,
'#maxlength' => 1024,
);
];
}
}
@@ -27,16 +27,16 @@ class NodeRevision extends WizardPluginBase {
/**
* Set default values for the filters.
*/
protected $filters = array(
'status' => array(
protected $filters = [
'status' => [
'value' => TRUE,
'table' => 'node_field_revision',
'field' => 'status',
'plugin_id' => 'boolean',
'entity_type' => 'node',
'entity_field' => 'status',
)
);
]
];
/**
* Overrides Drupal\views\Plugin\views\wizard\WizardPluginBase::rowStyleOptions().
@@ -19,13 +19,13 @@ class RouteSubscriber extends RouteSubscriberBase {
// a node listing instead of the path's child links.
$route = $collection->get('system.admin_content');
if ($route) {
$route->setDefaults(array(
$route->setDefaults([
'_title' => 'Content',
'_entity_list' => 'node',
));
$route->setRequirements(array(
]);
$route->setRequirements([
'_permission' => 'access content overview',
));
]);
}
}
@@ -2,8 +2,13 @@
namespace Drupal\node\Tests;
@trigger_error('\Drupal\Tests\node\Functional\AssertButtonsTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\node\Functional\AssertButtonsTrait', E_USER_DEPRECATED);
/**
* Asserts that buttons are present on a page.
*
* @deprecated Scheduled for removal before Drupal 9.0.0.
* Use \Drupal\Tests\node\Functional\AssertButtonsTrait instead.
*/
trait AssertButtonsTrait {
@@ -47,26 +47,26 @@ class NodeRevisionsTest extends NodeTestBase {
ConfigurableLanguage::createFromLangcode('de')->save();
ConfigurableLanguage::createFromLangcode('it')->save();
$field_storage_definition = array(
$field_storage_definition = [
'field_name' => 'untranslatable_string_field',
'entity_type' => 'node',
'type' => 'string',
'cardinality' => 1,
'translatable' => FALSE,
);
];
$field_storage = FieldStorageConfig::create($field_storage_definition);
$field_storage->save();
$field_definition = array(
$field_definition = [
'field_storage' => $field_storage,
'bundle' => 'page',
);
];
$field = FieldConfig::create($field_definition);
$field->save();
// Create and log in user.
$web_user = $this->drupalCreateUser(
array(
[
'view page revisions',
'revert page revisions',
'delete page revisions',
@@ -75,7 +75,7 @@ class NodeRevisionsTest extends NodeTestBase {
'access contextual links',
'translate any entity',
'administer content types',
)
]
);
$this->drupalLogin($web_user);
@@ -86,8 +86,8 @@ class NodeRevisionsTest extends NodeTestBase {
$settings['revision'] = 1;
$settings['isDefaultRevision'] = TRUE;
$nodes = array();
$logs = array();
$nodes = [];
$logs = [];
// Get original node.
$nodes[] = clone $node;
@@ -99,20 +99,20 @@ class NodeRevisionsTest extends NodeTestBase {
// Create revision with a random title and body and update variables.
$node->title = $this->randomMachineName();
$node->body = array(
$node->body = [
'value' => $this->randomMachineName(32),
'format' => filter_default_format(),
);
];
$node->untranslatable_string_field->value = $this->randomString();
$node->setNewRevision();
// Edit the 2nd revision with a different user.
if ($i == 1) {
$editor = $this->drupalCreateUser();
$node->setRevisionAuthorId($editor->id());
$node->setRevisionUserId($editor->id());
}
else {
$node->setRevisionAuthorId($web_user->id());
$node->setRevisionUserId($web_user->id());
}
$node->save();
@@ -128,7 +128,7 @@ class NodeRevisionsTest extends NodeTestBase {
/**
* Checks node revision related operations.
*/
function testRevisions() {
public function testRevisions() {
$node_storage = $this->container->get('entity.manager')->getStorage('node');
$nodes = $this->nodes;
$logs = $this->revisionLogs;
@@ -167,11 +167,11 @@ class NodeRevisionsTest extends NodeTestBase {
// Confirm that revisions revert properly.
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionid() . "/revert", array(), t('Revert'));
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionid() . "/revert", [], t('Revert'));
$this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.',
array('@type' => 'Basic page', '%title' => $nodes[1]->label(),
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime()))), 'Revision reverted.');
$node_storage->resetCache(array($node->id()));
['@type' => 'Basic page', '%title' => $nodes[1]->label(),
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime())]), 'Revision reverted.');
$node_storage->resetCache([$node->id()]);
$reverted_node = $node_storage->load($node->id());
$this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.');
@@ -190,27 +190,28 @@ class NodeRevisionsTest extends NodeTestBase {
// Confirm revisions delete properly.
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", array(), t('Delete'));
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", [], t('Delete'));
$this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.',
array('%revision-date' => format_date($nodes[1]->getRevisionCreationTime()),
'@type' => 'Basic page', '%title' => $nodes[1]->label())), 'Revision deleted.');
$this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0, 'Revision not found.');
['%revision-date' => format_date($nodes[1]->getRevisionCreationTime()),
'@type' => 'Basic page', '%title' => $nodes[1]->label()]), 'Revision deleted.');
$this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Revision not found.');
$this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Field revision not found.');
// Set the revision timestamp to an older date to make sure that the
// confirmation message correctly displays the stored revision date.
$old_revision_date = REQUEST_TIME - 86400;
db_update('node_revision')
->condition('vid', $nodes[2]->getRevisionId())
->fields(array(
->fields([
'revision_timestamp' => $old_revision_date,
))
])
->execute();
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", array(), t('Revert'));
$this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', array(
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", [], t('Revert'));
$this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', [
'@type' => 'Basic page',
'%title' => $nodes[2]->label(),
'%revision-date' => format_date($old_revision_date),
)));
]));
// Make a new revision and set it to not be default.
// This will create a new revision that is not "front facing".
@@ -232,7 +233,7 @@ class NodeRevisionsTest extends NodeTestBase {
// Verify that the non-default revision vid is greater than the default
// revision vid.
$default_revision = db_select('node', 'n')
->fields('n', array('vid'))
->fields('n', ['vid'])
->condition('nid', $node->id())
->execute()
->fetchCol();
@@ -297,11 +298,11 @@ class NodeRevisionsTest extends NodeTestBase {
/**
* Checks that revisions are correctly saved without log messages.
*/
function testNodeRevisionWithoutLogMessage() {
public function testNodeRevisionWithoutLogMessage() {
$node_storage = $this->container->get('entity.manager')->getStorage('node');
// Create a node with an initial log message.
$revision_log = $this->randomMachineName(10);
$node = $this->drupalCreateNode(array('revision_log' => $revision_log));
$node = $this->drupalCreateNode(['revision_log' => $revision_log]);
// Save over the same revision and explicitly provide an empty log message
// (for example, to mimic the case of a node form submitted with no text in
@@ -317,12 +318,12 @@ class NodeRevisionsTest extends NodeTestBase {
$node->save();
$this->drupalGet('node/' . $node->id());
$this->assertText($new_title, 'New node title appears on the page.');
$node_storage->resetCache(array($node->id()));
$node_storage->resetCache([$node->id()]);
$node_revision = $node_storage->load($node->id());
$this->assertEqual($node_revision->revision_log->value, $revision_log, 'After an existing node revision is re-saved without a log message, the original log message is preserved.');
// Create another node with an initial revision log message.
$node = $this->drupalCreateNode(array('revision_log' => $revision_log));
$node = $this->drupalCreateNode(['revision_log' => $revision_log]);
// Save a new node revision without providing a log message, and check that
// this revision has an empty log message.
@@ -336,7 +337,7 @@ class NodeRevisionsTest extends NodeTestBase {
$node->save();
$this->drupalGet('node/' . $node->id());
$this->assertText($new_title, 'New node title appears on the page.');
$node_storage->resetCache(array($node->id()));
$node_storage->resetCache([$node->id()]);
$node_revision = $node_storage->load($node->id());
$this->assertTrue(empty($node_revision->revision_log->value), 'After a new node revision is saved with an empty log message, the log message for the node is empty.');
}
@@ -353,7 +354,7 @@ class NodeRevisionsTest extends NodeTestBase {
* The decoded JSON response body.
*/
protected function renderContextualLinks(array $ids, $current_path) {
$post = array();
$post = [];
for ($i = 0; $i < count($ids); $i++) {
$post['ids[' . $i . ']'] = $ids[$i];
}
+14 -11
View File
@@ -8,6 +8,9 @@ use Drupal\simpletest\WebTestBase;
/**
* Sets up page and article content types.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use \Drupal\Tests\node\Functional\NodeTestBase instead.
*/
abstract class NodeTestBase extends WebTestBase {
@@ -16,7 +19,7 @@ abstract class NodeTestBase extends WebTestBase {
*
* @var array
*/
public static $modules = array('node', 'datetime');
public static $modules = ['node', 'datetime'];
/**
* The node access control handler.
@@ -33,12 +36,12 @@ abstract class NodeTestBase extends WebTestBase {
// Create Basic page and Article node types.
if ($this->profile != 'standard') {
$this->drupalCreateContentType(array(
$this->drupalCreateContentType([
'type' => 'page',
'name' => 'Basic page',
'display_submitted' => FALSE,
));
$this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
]);
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
}
$this->accessHandler = \Drupal::entityManager()->getAccessControlHandler('node');
}
@@ -56,7 +59,7 @@ abstract class NodeTestBase extends WebTestBase {
* @param \Drupal\Core\Session\AccountInterface $account
* The user account for which to check access.
*/
function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) {
public function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) {
foreach ($ops as $op => $result) {
$this->assertEqual($result, $this->accessHandler->access($node, $op, $account), $this->nodeAccessAssertMessage($op, $result, $node->language()->getId()));
}
@@ -75,10 +78,10 @@ abstract class NodeTestBase extends WebTestBase {
* (optional) The language code indicating which translation of the node
* to check. If NULL, the untranslated (fallback) access is checked.
*/
function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) {
$this->assertEqual($result, $this->accessHandler->createAccess($bundle, $account, array(
public function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) {
$this->assertEqual($result, $this->accessHandler->createAccess($bundle, $account, [
'langcode' => $langcode,
)), $this->nodeAccessAssertMessage('create', $result, $langcode));
]), $this->nodeAccessAssertMessage('create', $result, $langcode));
}
/**
@@ -96,14 +99,14 @@ abstract class NodeTestBase extends WebTestBase {
* An assert message string which contains information in plain English
* about the node access permission test that was performed.
*/
function nodeAccessAssertMessage($operation, $result, $langcode = NULL) {
public function nodeAccessAssertMessage($operation, $result, $langcode = NULL) {
return format_string(
'Node access returns @result with operation %op, language code %langcode.',
array(
[
'@result' => $result ? 'true' : 'false',
'%op' => $operation,
'%langcode' => !empty($langcode) ? $langcode : 'empty'
)
]
);
}
+37 -26
View File
@@ -5,6 +5,7 @@ namespace Drupal\node\Tests;
use Drupal\field\Entity\FieldConfig;
use Drupal\node\Entity\NodeType;
use Drupal\Core\Url;
use Drupal\system\Tests\Menu\AssertBreadcrumbTrait;
/**
* Ensures that node type functions work correctly.
@@ -13,19 +14,21 @@ use Drupal\Core\Url;
*/
class NodeTypeTest extends NodeTestBase {
use AssertBreadcrumbTrait;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['field_ui'];
public static $modules = ['field_ui', 'block'];
/**
* Ensures that node type functions (node_type_get_*) work correctly.
*
* Load available node types and validate the returned data.
*/
function testNodeTypeGetFunctions() {
public function testNodeTypeGetFunctions() {
$node_types = NodeType::loadMultiple();
$node_names = node_type_get_names();
@@ -42,7 +45,7 @@ class NodeTypeTest extends NodeTestBase {
/**
* Tests creating a content type programmatically and via a form.
*/
function testNodeTypeCreation() {
public function testNodeTypeCreation() {
// Create a content type programmatically.
$type = $this->drupalCreateContentType();
@@ -50,14 +53,14 @@ class NodeTypeTest extends NodeTestBase {
$this->assertTrue($type_exists, 'The new content type has been created in the database.');
// Log in a test user.
$web_user = $this->drupalCreateUser(array('create ' . $type->label() . ' content'));
$web_user = $this->drupalCreateUser(['create ' . $type->label() . ' content']);
$this->drupalLogin($web_user);
$this->drupalGet('node/add/' . $type->id());
$this->assertResponse(200, 'The new content type can be accessed at node/add.');
// Create a content type via the user interface.
$web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types'));
$web_user = $this->drupalCreateUser(['bypass node access', 'administer content types']);
$this->drupalLogin($web_user);
$this->drupalGet('node/add');
@@ -66,11 +69,11 @@ class NodeTypeTest extends NodeTestBase {
$elements = $this->cssSelect('dl.node-type-list dt');
$this->assertEqual(3, count($elements));
$edit = array(
$edit = [
'name' => 'foo',
'title_label' => 'title for foo',
'type' => 'foo',
);
];
$this->drupalPostForm('admin/structure/types/add', $edit, t('Save and manage fields'));
$type_exists = (bool) NodeType::load('foo');
$this->assertTrue($type_exists, 'The new content type has been created in the database.');
@@ -83,8 +86,9 @@ class NodeTypeTest extends NodeTestBase {
/**
* Tests editing a node type using the UI.
*/
function testNodeTypeEditing() {
$web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types', 'administer node fields'));
public function testNodeTypeEditing() {
$this->drupalPlaceBlock('system_breadcrumb_block');
$web_user = $this->drupalCreateUser(['bypass node access', 'administer content types', 'administer node fields']);
$this->drupalLogin($web_user);
$field = FieldConfig::loadByName('node', 'page', 'body');
@@ -96,9 +100,9 @@ class NodeTypeTest extends NodeTestBase {
$this->assertRaw('Body', 'Body field was found.');
// Rename the title field.
$edit = array(
$edit = [
'title_label' => 'Foo',
);
];
$this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
$this->drupalGet('node/add/page');
@@ -106,10 +110,10 @@ class NodeTypeTest extends NodeTestBase {
$this->assertNoRaw('Title', 'Old title label was not displayed.');
// Change the name and the description.
$edit = array(
$edit = [
'name' => 'Bar',
'description' => 'Lorem ipsum.',
);
];
$this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
$this->drupalGet('node/add');
@@ -131,9 +135,15 @@ class NodeTypeTest extends NodeTestBase {
$this->assertEqual($node_bundles['page']['label'], 'NewBar', 'Node type bundle cache is updated');
// Remove the body field.
$this->drupalPostForm('admin/structure/types/manage/page/fields/node.page.body/delete', array(), t('Delete'));
$this->drupalPostForm('admin/structure/types/manage/page/fields/node.page.body/delete', [], t('Delete'));
// Resave the settings for this type.
$this->drupalPostForm('admin/structure/types/manage/page', array(), t('Save content type'));
$this->drupalPostForm('admin/structure/types/manage/page', [], t('Save content type'));
$front_page_path = Url::fromRoute('<front>')->toString();
$this->assertBreadcrumb('admin/structure/types/manage/page/fields', [
$front_page_path => 'Home',
'admin/structure/types' => 'Content types',
'admin/structure/types/manage/page' => 'NewBar',
]);
// Check that the body field doesn't exist.
$this->drupalGet('node/add/page');
$this->assertNoRaw('Body', 'Body field was not found.');
@@ -142,23 +152,24 @@ class NodeTypeTest extends NodeTestBase {
/**
* Tests deleting a content type that still has content.
*/
function testNodeTypeDeletion() {
public function testNodeTypeDeletion() {
$this->drupalPlaceBlock('page_title_block');
// Create a content type programmatically.
$type = $this->drupalCreateContentType();
// Log in a test user.
$web_user = $this->drupalCreateUser(array(
$web_user = $this->drupalCreateUser([
'bypass node access',
'administer content types',
));
]);
$this->drupalLogin($web_user);
// Add a new node of this type.
$node = $this->drupalCreateNode(array('type' => $type->id()));
$node = $this->drupalCreateNode(['type' => $type->id()]);
// Attempt to delete the content type, which should not be allowed.
$this->drupalGet('admin/structure/types/manage/' . $type->label() . '/delete');
$this->assertRaw(
t('%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', array('%type' => $type->label())),
t('%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', ['%type' => $type->label()]),
'The content type will not be deleted until all nodes of that type are removed.'
);
$this->assertNoText(t('This action cannot be undone.'), 'The node type deletion confirmation form is not available.');
@@ -168,13 +179,13 @@ class NodeTypeTest extends NodeTestBase {
// Attempt to delete the content type, which should now be allowed.
$this->drupalGet('admin/structure/types/manage/' . $type->label() . '/delete');
$this->assertRaw(
t('Are you sure you want to delete the content type %type?', array('%type' => $type->label())),
t('Are you sure you want to delete the content type %type?', ['%type' => $type->label()]),
'The content type is available for deletion.'
);
$this->assertText(t('This action cannot be undone.'), 'The node type deletion confirmation form is available.');
// Test that a locked node type could not be deleted.
$this->container->get('module_installer')->install(array('node_test_config'));
$this->container->get('module_installer')->install(['node_test_config']);
// Lock the default node type.
$locked = \Drupal::state()->get('node.type.locked');
$locked['default'] = 'default';
@@ -186,14 +197,14 @@ class NodeTypeTest extends NodeTestBase {
$this->assertNoLink(t('Delete'));
$this->drupalGet('admin/structure/types/manage/default/delete');
$this->assertResponse(403);
$this->container->get('module_installer')->uninstall(array('node_test_config'));
$this->container->get('module_installer')->uninstall(['node_test_config']);
$this->container = \Drupal::getContainer();
unset($locked['default']);
\Drupal::state()->set('node.type.locked', $locked);
$this->drupalGet('admin/structure/types/manage/default');
$this->clickLink(t('Delete'));
$this->assertResponse(200);
$this->drupalPostForm(NULL, array(), t('Delete'));
$this->drupalPostForm(NULL, [], t('Delete'));
$this->assertFalse((bool) NodeType::load('default'), 'Node type with machine default deleted.');
}
@@ -202,7 +213,7 @@ class NodeTypeTest extends NodeTestBase {
*/
public function testNodeTypeFieldUiPermissions() {
// Create an admin user who can only manage node fields.
$admin_user_1 = $this->drupalCreateUser(array('administer content types', 'administer node fields'));
$admin_user_1 = $this->drupalCreateUser(['administer content types', 'administer node fields']);
$this->drupalLogin($admin_user_1);
// Test that the user only sees the actions available to him.
@@ -211,7 +222,7 @@ class NodeTypeTest extends NodeTestBase {
$this->assertNoLinkByHref('admin/structure/types/manage/article/display');
// Create another admin user who can manage node fields display.
$admin_user_2 = $this->drupalCreateUser(array('administer content types', 'administer node display'));
$admin_user_2 = $this->drupalCreateUser(['administer content types', 'administer node display']);
$this->drupalLogin($admin_user_2);
// Test that the user only sees the actions available to him.
+167 -38
View File
@@ -6,6 +6,7 @@ use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Url;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
@@ -28,7 +29,7 @@ class PagePreviewTest extends NodeTestBase {
*
* @var array
*/
public static $modules = array('node', 'taxonomy', 'comment', 'image', 'file');
public static $modules = ['node', 'taxonomy', 'comment', 'image', 'file', 'text', 'node_test', 'menu_ui'];
/**
* The name of the created field.
@@ -41,7 +42,7 @@ class PagePreviewTest extends NodeTestBase {
parent::setUp();
$this->addDefaultCommentField('node', 'page');
$web_user = $this->drupalCreateUser(array('edit own page content', 'create page content'));
$web_user = $this->drupalCreateUser(['edit own page content', 'create page content', 'administer menu']);
$this->drupalLogin($web_user);
// Add a vocabulary so we can test different view modes.
@@ -88,54 +89,82 @@ class PagePreviewTest extends NodeTestBase {
// Create a field.
$this->fieldName = Unicode::strtolower($this->randomMachineName());
$handler_settings = array(
'target_bundles' => array(
$handler_settings = [
'target_bundles' => [
$this->vocabulary->id() => $this->vocabulary->id(),
),
],
'auto_create' => TRUE,
);
];
$this->createEntityReferenceField('node', 'page', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
entity_get_form_display('node', 'page', 'default')
->setComponent($this->fieldName, array(
->setComponent($this->fieldName, [
'type' => 'entity_reference_autocomplete_tags',
))
])
->save();
// Show on default display and teaser.
entity_get_display('node', 'page', 'default')
->setComponent($this->fieldName, array(
->setComponent($this->fieldName, [
'type' => 'entity_reference_label',
))
])
->save();
entity_get_display('node', 'page', 'teaser')
->setComponent($this->fieldName, array(
->setComponent($this->fieldName, [
'type' => 'entity_reference_label',
))
])
->save();
entity_get_form_display('node', 'page', 'default')
->setComponent('field_image', array(
->setComponent('field_image', [
'type' => 'image_image',
'settings' => [],
))
])
->save();
entity_get_display('node', 'page', 'default')
->setComponent('field_image')
->save();
// Create a multi-value text field.
$field_storage = FieldStorageConfig::create([
'field_name' => 'field_test_multi',
'entity_type' => 'node',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
'type' => 'text',
'settings' => [
'max_length' => 50,
]
]);
$field_storage->save();
FieldConfig::create([
'field_storage' => $field_storage,
'bundle' => 'page',
])->save();
entity_get_form_display('node', 'page', 'default')
->setComponent('field_test_multi', [
'type' => 'text_textfield',
])
->save();
entity_get_display('node', 'page', 'default')
->setComponent('field_test_multi', [
'type' => 'string',
])
->save();
}
/**
* Checks the node preview functionality.
*/
function testPagePreview() {
public function testPagePreview() {
$title_key = 'title[0][value]';
$body_key = 'body[0][value]';
$term_key = $this->fieldName . '[target_id]';
// Fill in node creation form and preview node.
$edit = array();
$edit = [];
$edit[$title_key] = '<em>' . $this->randomMachineName(8) . '</em>';
$edit[$body_key] = $this->randomMachineName(16);
$edit[$term_key] = $this->term->getName();
@@ -149,7 +178,7 @@ class PagePreviewTest extends NodeTestBase {
$this->drupalPostForm(NULL, ['field_image[0][alt]' => 'Picture of llamas'], t('Preview'));
// Check that the preview is displaying the title, body and term.
$this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.');
$this->assertTitle(t('@title | Drupal', ['@title' => $edit[$title_key]]), 'Basic page title is preview.');
$this->assertEscaped($edit[$title_key], 'Title displayed and escaped.');
$this->assertText($edit[$body_key], 'Body displayed.');
$this->assertText($edit[$term_key], 'Term displayed.');
@@ -166,8 +195,8 @@ class PagePreviewTest extends NodeTestBase {
->removeComponent('body')
->save();
$view_mode_edit = array('view_mode' => 'teaser');
$this->drupalPostForm('node/preview/' . $uuid . '/default', $view_mode_edit, t('Switch'));
$view_mode_edit = ['view_mode' => 'teaser'];
$this->drupalPostForm('node/preview/' . $uuid . '/full', $view_mode_edit, t('Switch'));
$this->assertRaw('view-mode-teaser', 'View mode teaser class found.');
$this->assertNoText($edit[$body_key], 'Body not displayed.');
@@ -176,22 +205,25 @@ class PagePreviewTest extends NodeTestBase {
$this->clickLink(t('Back to content editing'));
$this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.');
$this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.');
$this->assertFieldByName($term_key, $edit[$term_key] . ' (' . $this->term->id() . ')', 'Term field displayed.');
$this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.');
$this->assertFieldByName('field_image[0][alt]', 'Picture of llamas');
$this->drupalPostAjaxForm(NULL, [], ['field_test_multi_add_more' => t('Add another item')], NULL, [], [], 'node-page-form');
$this->assertFieldByName('field_test_multi[0][value]');
$this->assertFieldByName('field_test_multi[1][value]');
// Return to page preview to check everything is as expected.
$this->drupalPostForm(NULL, array(), t('Preview'));
$this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.');
$this->drupalPostForm(NULL, [], t('Preview'));
$this->assertTitle(t('@title | Drupal', ['@title' => $edit[$title_key]]), 'Basic page title is preview.');
$this->assertEscaped($edit[$title_key], 'Title displayed and escaped.');
$this->assertText($edit[$body_key], 'Body displayed.');
$this->assertText($edit[$term_key], 'Term displayed.');
$this->assertLink(t('Back to content editing'));
// Assert the content is kept when reloading the page.
$this->drupalGet('node/add/page', array('query' => array('uuid' => $uuid)));
$this->drupalGet('node/add/page', ['query' => ['uuid' => $uuid]]);
$this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.');
$this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.');
$this->assertFieldByName($term_key, $edit[$term_key] . ' (' . $this->term->id() . ')', 'Term field displayed.');
$this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.');
// Save the node - this is a new POST, so we need to upload the image.
$this->drupalPostForm('node/add/page', $edit, t('Upload'));
@@ -208,7 +240,7 @@ class PagePreviewTest extends NodeTestBase {
// Check with two new terms on the edit form, additionally to the existing
// one.
$edit = array();
$edit = [];
$newterm1 = $this->randomMachineName(8);
$newterm2 = $this->randomMachineName(8);
$edit[$term_key] = $this->term->getName() . ', ' . $newterm1 . ', ' . $newterm2;
@@ -224,7 +256,7 @@ class PagePreviewTest extends NodeTestBase {
// Check with one more new term, keeping old terms, removing the existing
// one.
$edit = array();
$edit = [];
$newterm3 = $this->randomMachineName(8);
$edit[$term_key] = $newterm1 . ', ' . $newterm3 . ', ' . $newterm2;
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview'));
@@ -238,9 +270,9 @@ class PagePreviewTest extends NodeTestBase {
// Check that editing an existing node after it has been previewed and not
// saved doesn't remember the previous changes.
$edit = array(
$edit = [
$title_key => $this->randomMachineName(8),
);
];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview'));
$this->assertText($edit[$title_key], 'New title displayed.');
$this->clickLink(t('Back to content editing'));
@@ -257,15 +289,112 @@ class PagePreviewTest extends NodeTestBase {
$node_type->save();
$this->drupalGet('node/add/page');
$this->assertNoRaw('edit-submit');
$this->drupalPostForm('node/add/page', array($title_key => 'Preview'), t('Preview'));
$this->drupalPostForm('node/add/page', [$title_key => 'Preview'], t('Preview'));
$this->clickLink(t('Back to content editing'));
$this->assertRaw('edit-submit');
// Check that destination is remembered when clicking on preview. When going
// back to the edit form and clicking save, we should go back to the
// original destination, if set.
$destination = 'node';
$this->drupalPostForm($node->toUrl('edit-form'), [], t('Preview'), ['query' => ['destination' => $destination]]);
$parameters = ['node_preview' => $node->uuid(), 'view_mode_id' => 'full'];
$options = ['absolute' => TRUE, 'query' => ['destination' => $destination]];
$this->assertUrl(Url::fromRoute('entity.node.preview', $parameters, $options));
$this->drupalPostForm(NULL, ['view_mode' => 'teaser'], t('Switch'));
$this->clickLink(t('Back to content editing'));
$this->drupalPostForm(NULL, [], t('Save'));
$this->assertUrl($destination);
// Check that preview page works as expected without a destination set.
$this->drupalPostForm($node->toUrl('edit-form'), [], t('Preview'));
$parameters = ['node_preview' => $node->uuid(), 'view_mode_id' => 'full'];
$this->assertUrl(Url::fromRoute('entity.node.preview', $parameters, ['absolute' => TRUE]));
$this->drupalPostForm(NULL, ['view_mode' => 'teaser'], t('Switch'));
$this->clickLink(t('Back to content editing'));
$this->drupalPostForm(NULL, [], t('Save'));
$this->assertUrl($node->toUrl());
$this->assertResponse(200);
// Assert multiple items can be added and are not lost when previewing.
$test_image_1 = current($this->drupalGetTestFiles('image', 39325));
$edit_image_1['files[field_image_0][]'] = drupal_realpath($test_image_1->uri);
$test_image_2 = current($this->drupalGetTestFiles('image', 39325));
$edit_image_2['files[field_image_1][]'] = drupal_realpath($test_image_2->uri);
$edit['field_image[0][alt]'] = 'Alt 1';
$this->drupalPostForm('node/add/page', $edit_image_1, t('Upload'));
$this->drupalPostForm(NULL, $edit, t('Preview'));
$this->clickLink(t('Back to content editing'));
$this->assertFieldByName('files[field_image_1][]');
$this->drupalPostForm(NULL, $edit_image_2, t('Upload'));
$this->assertNoFieldByName('files[field_image_1][]');
$title = 'node_test_title';
$example_text_1 = 'example_text_preview_1';
$example_text_2 = 'example_text_preview_2';
$example_text_3 = 'example_text_preview_3';
$this->drupalGet('node/add/page');
$edit = [
'title[0][value]' => $title,
'field_test_multi[0][value]' => $example_text_1,
];
$this->assertRaw('Storage is not set');
$this->drupalPostForm(NULL, $edit, t('Preview'));
$this->clickLink(t('Back to content editing'));
$this->assertRaw('Storage is set');
$this->assertFieldByName('field_test_multi[0][value]');
$this->drupalPostForm(NULL, [], t('Save'));
$this->assertText('Basic page ' . $title . ' has been created.');
$node = $this->drupalGetNodeByTitle($title);
$this->drupalGet('node/' . $node->id() . '/edit');
$this->drupalPostAjaxForm(NULL, [], ['field_test_multi_add_more' => t('Add another item')]);
$this->drupalPostAjaxForm(NULL, [], ['field_test_multi_add_more' => t('Add another item')]);
$edit = [
'field_test_multi[1][value]' => $example_text_2,
'field_test_multi[2][value]' => $example_text_3,
];
$this->drupalPostForm(NULL, $edit, t('Preview'));
$this->clickLink(t('Back to content editing'));
$this->drupalPostForm(NULL, $edit, t('Preview'));
$this->clickLink(t('Back to content editing'));
$this->assertFieldByName('field_test_multi[0][value]', $example_text_1);
$this->assertFieldByName('field_test_multi[1][value]', $example_text_2);
$this->assertFieldByName('field_test_multi[2][value]', $example_text_3);
// Now save the node and make sure all values got saved.
$this->drupalPostForm(NULL, [], t('Save'));
$this->assertText($example_text_1);
$this->assertText($example_text_2);
$this->assertText($example_text_3);
// Edit again, change the menu_ui settings and click on preview.
$this->drupalGet('node/' . $node->id() . '/edit');
$edit = [
'menu[enabled]' => TRUE,
'menu[title]' => 'Changed title',
];
$this->drupalPostForm(NULL, $edit, t('Preview'));
$this->clickLink(t('Back to content editing'));
$this->assertFieldChecked('edit-menu-enabled', 'Menu option is still checked');
$this->assertFieldByName('menu[title]', 'Changed title', 'Menu link title is correct after preview');
// Save, change the title while saving and make sure that it is correctly
// saved.
$edit = [
'menu[enabled]' => TRUE,
'menu[title]' => 'Second title change',
];
$this->drupalPostForm(NULL, $edit, t('Save'));
$this->drupalGet('node/' . $node->id() . '/edit');
$this->assertFieldByName('menu[title]', 'Second title change', 'Menu link title is correct after saving');
}
/**
* Checks the node preview functionality, when using revisions.
*/
function testPagePreviewWithRevisions() {
public function testPagePreviewWithRevisions() {
$title_key = 'title[0][value]';
$body_key = 'body[0][value]';
$term_key = $this->fieldName . '[target_id]';
@@ -275,7 +404,7 @@ class PagePreviewTest extends NodeTestBase {
$node_type->save();
// Fill in node creation form and preview node.
$edit = array();
$edit = [];
$edit[$title_key] = $this->randomMachineName(8);
$edit[$body_key] = $this->randomMachineName(16);
$edit[$term_key] = $this->term->id();
@@ -283,7 +412,7 @@ class PagePreviewTest extends NodeTestBase {
$this->drupalPostForm('node/add/page', $edit, t('Preview'));
// Check that the preview is displaying the title, body and term.
$this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.');
$this->assertTitle(t('@title | Drupal', ['@title' => $edit[$title_key]]), 'Basic page title is preview.');
$this->assertText($edit[$title_key], 'Title displayed.');
$this->assertText($edit[$body_key], 'Body displayed.');
$this->assertText($edit[$term_key], 'Term displayed.');
@@ -313,7 +442,7 @@ class PagePreviewTest extends NodeTestBase {
/** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
$controller_resolver = \Drupal::service('controller_resolver');
$node_preview_controller = $controller_resolver->getControllerFromDefinition('\Drupal\node\Controller\NodePreviewController::view');
$node_preview_controller($node, 'default');
$node_preview_controller($node, 'full');
}
/**
@@ -321,20 +450,20 @@ class PagePreviewTest extends NodeTestBase {
*/
public function testSimultaneousPreview() {
$title_key = 'title[0][value]';
$node = $this->drupalCreateNode(array());
$node = $this->drupalCreateNode([]);
$edit = array($title_key => 'New page title');
$edit = [$title_key => 'New page title'];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview'));
$this->assertText($edit[$title_key]);
$user2 = $this->drupalCreateUser(array('edit any page content'));
$user2 = $this->drupalCreateUser(['edit any page content']);
$this->drupalLogin($user2);
$this->drupalGet('node/' . $node->id() . '/edit');
$this->assertFieldByName($title_key, $node->label(), 'No title leaked from previous user.');
$edit2 = array($title_key => 'Another page title');
$edit2 = [$title_key => 'Another page title'];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit2, t('Preview'));
$this->assertUrl(\Drupal::url('entity.node.preview', ['node_preview' => $node->uuid(), 'view_mode_id' => 'default'], ['absolute' => TRUE]));
$this->assertUrl(\Drupal::url('entity.node.preview', ['node_preview' => $node->uuid(), 'view_mode_id' => 'full'], ['absolute' => TRUE]));
$this->assertText($edit2[$title_key]);
}
@@ -0,0 +1,41 @@
<?php
namespace Drupal\node\Tests\Update;
use Drupal\system\Tests\Update\UpdatePathTestBase;
/**
* Tests that node settings are properly updated during database updates.
*
* @group node
*/
class NodeUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz',
];
}
/**
* Tests that the node entity type has a 'published' entity key.
*
* @see node_update_8301()
*/
public function testPublishedEntityKey() {
// Check that the 'published' entity key does not exist prior to the update.
$entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node');
$this->assertFalse($entity_type->getKey('published'));
// Run updates.
$this->runUpdates();
// Check that the entity key exists and it has the correct value.
$entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node');
$this->assertEqual('status', $entity_type->getKey('published'));
}
}
@@ -17,27 +17,27 @@ class NodeContextualLinksTest extends NodeTestBase {
*
* @var array
*/
public static $modules = array('contextual');
public static $modules = ['contextual'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_contextual_links');
public static $testViews = ['test_contextual_links'];
/**
* Tests contextual links.
*/
public function testNodeContextualLinks() {
$this->drupalCreateContentType(array('type' => 'page'));
$this->drupalCreateNode(array('promote' => 1));
$this->drupalCreateContentType(['type' => 'page']);
$this->drupalCreateNode(['promote' => 1]);
$this->drupalGet('node');
$user = $this->drupalCreateUser(array('administer nodes', 'access contextual links'));
$user = $this->drupalCreateUser(['administer nodes', 'access contextual links']);
$this->drupalLogin($user);
$response = $this->renderContextualLinks(array('node:node=1:'), 'node');
$response = $this->renderContextualLinks(['node:node=1:'], 'node');
$this->assertResponse(200);
$json = Json::decode($response);
$this->setRawContent($json['node:node=1:']);
@@ -63,7 +63,7 @@ class NodeContextualLinksTest extends NodeTestBase {
*/
protected function renderContextualLinks($ids, $current_path) {
// Build POST values.
$post = array();
$post = [];
for ($i = 0; $i < count($ids); $i++) {
$post['ids[' . $i . ']'] = $ids[$i];
}
@@ -78,15 +78,15 @@ class NodeContextualLinksTest extends NodeTestBase {
$post = implode('&', $post);
// Perform HTTP request.
return $this->curlExec(array(
CURLOPT_URL => \Drupal::url('contextual.render', [], ['absolute' => TRUE, 'query' => array('destination' => $current_path)]),
return $this->curlExec([
CURLOPT_URL => \Drupal::url('contextual.render', [], ['absolute' => TRUE, 'query' => ['destination' => $current_path]]),
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $post,
CURLOPT_HTTPHEADER => array(
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/x-www-form-urlencoded',
),
));
],
]);
}
/**
@@ -108,8 +108,8 @@ class NodeContextualLinksTest extends NodeTestBase {
$admin_user->pass_raw = 'new_password';
$admin_user->save();
$this->drupalCreateContentType(array('type' => 'page'));
$this->drupalCreateNode(array('promote' => 1));
$this->drupalCreateContentType(['type' => 'page']);
$this->drupalCreateNode(['promote' => 1]);
$this->drupalLogin($admin_user);
$this->drupalGet('node');
@@ -2,11 +2,16 @@
namespace Drupal\node\Tests\Views;
@trigger_error('\Drupal\node\Tests\Views\NodeTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\node\Functional\Views\NodeTestBase', E_USER_DEPRECATED);
use Drupal\views\Tests\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
* Base class for all node tests.
*
* @deprecated Scheduled for removal before Drupal 9.0.0.
* Use \Drupal\Tests\node\Functional\Views\NodeTestBase instead.
*/
abstract class NodeTestBase extends ViewTestBase {
@@ -15,13 +20,13 @@ abstract class NodeTestBase extends ViewTestBase {
*
* @var array
*/
public static $modules = array('node_test_views');
public static $modules = ['node_test_views'];
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
if ($import_test_views) {
ViewTestData::createTestViews(get_class($this), array('node_test_views'));
ViewTestData::createTestViews(get_class($this), ['node_test_views']);
}
}