/**
  * {@inheritdoc}
  */
 public function build(RouteMatchInterface $route_match)
 {
     $breadcrumb = new Breadcrumb();
     $links[] = Link::createFromRoute(t('Home'), '<front>');
     // Articles page is a view.
     $links[] = Link::createFromRoute(t('Articles'), 'view.articles.page_1');
     $links[] = Link::createFromRoute($this->node->label(), '<none>');
     $breadcrumb->setLinks($links);
     return $breadcrumb;
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  */
 public function form(array $form, FormStateInterface $form_state)
 {
     $form['#title'] = $this->entity->label();
     if (!isset($this->entity->book)) {
         // The node is not part of any book yet - set default options.
         $this->entity->book = $this->bookManager->getLinkDefaults($this->entity->id());
     } else {
         $this->entity->book['original_bid'] = $this->entity->book['bid'];
     }
     // Find the depth limit for the parent select.
     if (!isset($this->entity->book['parent_depth_limit'])) {
         $this->entity->book['parent_depth_limit'] = $this->bookManager->getParentDepthLimit($this->entity->book);
     }
     $form = $this->bookManager->addFormElements($form, $form_state, $this->entity, $this->currentUser(), FALSE);
     return $form;
 }
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state, NodeInterface $node = NULL)
 {
     $form['#title'] = $node->label();
     $form['#node'] = $node;
     $this->bookAdminTable($node, $form);
     $form['save'] = array('#type' => 'submit', '#value' => $this->t('Save book pages'));
     return $form;
 }
 /**
  * Verifies that you can disable individual search plugins.
  */
 function testSearchModuleDisabling()
 {
     // Array of search plugins to test: 'keys' are the keywords to search for,
     // and 'text' is the text to assert is on the results page.
     $plugin_info = array('node_search' => array('keys' => 'pizza', 'text' => $this->searchNode->label()), 'user_search' => array('keys' => $this->searchUser->getUsername(), 'text' => $this->searchUser->getEmail()), 'dummy_search_type' => array('keys' => 'foo', 'text' => 'Dummy search snippet to display'));
     $plugins = array_keys($plugin_info);
     /** @var $entities \Drupal\search\SearchPageInterface[] */
     $entities = entity_load_multiple('search_page');
     // Disable all of the search pages.
     foreach ($entities as $entity) {
         $entity->disable()->save();
     }
     // Test each plugin if it's enabled as the only search plugin.
     foreach ($entities as $entity_id => $entity) {
         // Set this as default.
         $this->drupalGet("admin/config/search/pages/manage/{$entity_id}/set-default");
         // Run a search from the correct search URL.
         $info = $plugin_info[$entity_id];
         $this->drupalGet('search/' . $entity->getPath(), array('query' => array('keys' => $info['keys'])));
         $this->assertResponse(200);
         $this->assertNoText('no results', $entity->label() . ' search found results');
         $this->assertText($info['text'], 'Correct search text found');
         // Verify that other plugin search tab labels are not visible.
         foreach ($plugins as $other) {
             if ($other != $entity_id) {
                 $label = $entities[$other]->label();
                 $this->assertNoText($label, $label . ' search tab is not shown');
             }
         }
         // Run a search from the search block on the node page. Verify you get
         // to this plugin's search results page.
         $terms = array('keys' => $info['keys']);
         $this->submitGetForm('node', $terms, t('Search'));
         $current = $this->getURL();
         $expected = \Drupal::url('search.view_' . $entity->id(), array(), array('query' => array('keys' => $info['keys']), 'absolute' => TRUE));
         $this->assertEqual($current, $expected, 'Block redirected to right search page');
         // Try an invalid search path, which should 404.
         $this->drupalGet('search/not_a_plugin_path');
         $this->assertResponse(404);
         $entity->disable()->save();
     }
     // Test with all search plugins enabled. When you go to the search
     // page or run search, all plugins should be shown.
     foreach ($entities as $entity) {
         $entity->enable()->save();
     }
     // Set the node search as default.
     $this->drupalGet('admin/config/search/pages/manage/node_search/set-default');
     $paths = array(array('path' => 'search/node', 'options' => array('query' => array('keys' => 'pizza'))), array('path' => 'search/node', 'options' => array()));
     foreach ($paths as $item) {
         $this->drupalGet($item['path'], $item['options']);
         foreach ($plugins as $entity_id) {
             $label = $entities[$entity_id]->label();
             $this->assertText($label, format_string('%label search tab is shown', array('%label' => $label)));
         }
     }
 }
 /**
  * Generates HTML for export when invoked by book_export().
  *
  * The given node is embedded to its absolute depth in a top level section. For
  * example, a child node with depth 2 in the hierarchy is contained in
  * (otherwise empty) <div> elements corresponding to depth 0 and depth 1.
  * This is intended to support WYSIWYG output - e.g., level 3 sections always
  * look like level 3 sections, no matter their depth relative to the node
  * selected to be exported as printer-friendly HTML.
  *
  * @param \Drupal\node\NodeInterface $node
  *   The node to export.
  *
  * @throws \Exception
  *   Thrown when the node was not attached to a book.
  *
  * @return array
  *   A render array representing the HTML for a node and its children in the
  *   book hierarchy.
  */
 public function bookExportHtml(NodeInterface $node)
 {
     if (!isset($node->book)) {
         throw new \Exception();
     }
     $tree = $this->bookManager->bookSubtreeData($node->book);
     $contents = $this->exportTraverse($tree, array($this, 'bookNodeExport'));
     return array('#theme' => 'book_export_html', '#title' => $node->label(), '#contents' => $contents, '#depth' => $node->book['depth'], '#cache' => ['tags' => $node->getEntityType()->getListCacheTags()]);
 }
Esempio n. 6
0
 public function nodeGreeting(NodeInterface $node)
 {
     if ($node->isPublished()) {
         $formatted = $node->body->processed;
         foreach ($node->field_tags as $tag) {
             $terms[] = $tag->entity->label();
         }
         return ['#theme' => 'greeting_node', '#title' => $node->label() . ' (' . $node->bundle() . ')', '#body' => $formatted, '#name' => $node->getOwner()->label(), '#terms' => $terms];
     }
     return ['#markup' => $this->t('Not published')];
 }
 /**
  * {@inheritdoc}
  */
 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()));
     $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())));
     $form_state->setRedirect('entity.node.canonical', array('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) {
         $form_state->setRedirect('entity.node.version_history', array('node' => $this->revision->id()));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, array &$form_state)
 {
     $this->nodeStorage->deleteRevision($this->revision->getRevisionId());
     watchdog('content', '@type: deleted %title revision %revision.', array('@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())));
     $form_state['redirect_route'] = array('route_name' => 'node.view', 'route_parameters' => array('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) {
         $form_state['redirect_route']['route_name'] = 'node.revision_overview';
     }
 }
Esempio n. 9
0
 /**
  * Tests the administrative listing of all book pages in a book.
  */
 public function testAdminBookNodeListing()
 {
     // Create a new book.
     $this->createBook();
     $this->drupalLogin($this->adminUser);
     // Load the book page list and assert the created book title is displayed
     // and action links are shown on list items.
     $this->drupalGet('admin/structure/book/' . $this->book->id());
     $this->assertText($this->book->label(), 'The book title is displayed on the administrative book listing page.');
     $elements = $this->xpath('//table//ul[@class="dropbutton"]/li/a');
     $this->assertEqual((string) $elements[0], 'View', 'View link is found from the list.');
 }
Esempio n. 10
0
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     // The revision timestamp will be updated when the revision is saved. Keep
     // the original one for the confirmation message.
     $original_revision_timestamp = $this->revision->getRevisionCreationTime();
     $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->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()));
 }
Esempio n. 11
0
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, array &$form_state)
 {
     $this->revision->setNewRevision();
     // Make this the new default revision for the node.
     $this->revision->isDefaultRevision(TRUE);
     // The revision timestamp will be updated when the revision is saved. Keep the
     // original one for the confirmation message.
     $original_revision_timestamp = $this->revision->getRevisionCreationTime();
     $this->revision->revision_log = t('Copy of the revision from %date.', array('%date' => format_date($original_revision_timestamp)));
     $this->revision->save();
     watchdog('content', '@type: reverted %title revision %revision.', array('@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()));
     drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => format_date($original_revision_timestamp))));
     $form_state['redirect_route'] = array('route_name' => 'node.revision_overview', 'route_parameters' => array('node' => $this->revision->id()));
 }
Esempio n. 12
0
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     $this->revision->setNewRevision();
     // Make this the new default revision for the node.
     $this->revision->isDefaultRevision(TRUE);
     // The revision timestamp will be updated when the revision is saved. Keep the
     // original one for the confirmation message.
     $original_revision_timestamp = $this->revision->getRevisionCreationTime();
     $this->revision->revision_log = t('Copy of the revision from %date.', array('%date' => format_date($original_revision_timestamp)));
     $this->revision->save();
     $this->logger('content')->notice('@type: reverted %title revision %revision.', array('@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.', array('@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => format_date($original_revision_timestamp))));
     $form_state->setRedirect('entity.node.version_history', array('node' => $this->revision->id()));
 }
Esempio n. 13
0
 /**
  * Tests that the embedded form appears and can be submitted.
  */
 function testEmbeddedForm()
 {
     // First verify we can submit the form from the module's page.
     $this->drupalPostForm('search_embedded_form', array('name' => 'John'), t('Send away'));
     $this->assertText(t('Test form was submitted'), 'Form message appears');
     $count = \Drupal::state()->get('search_embedded_form.submit_count');
     $this->assertEqual($this->submitCount + 1, $count, 'Form submission count is correct');
     $this->submitCount = $count;
     // Now verify that we can see and submit the form from the search results.
     $this->drupalGet('search/node', array('query' => array('keys' => $this->node->label())));
     $this->assertText(t('Your name'), 'Form is visible');
     $this->drupalPostForm(NULL, array('name' => 'John'), t('Send away'));
     $this->assertText(t('Test form was submitted'), 'Form message appears');
     $count = \Drupal::state()->get('search_embedded_form.submit_count');
     $this->assertEqual($this->submitCount + 1, $count, 'Form submission count is correct');
     $this->submitCount = $count;
     // Now verify that if we submit the search form, it doesn't count as
     // our form being submitted.
     $this->drupalPostForm('search', array('keys' => 'foo'), t('Search'));
     $this->assertNoText(t('Test form was submitted'), 'Form message does not appear');
     $count = \Drupal::state()->get('search_embedded_form.submit_count');
     $this->assertEqual($this->submitCount, $count, 'Form submission count is correct');
     $this->submitCount = $count;
 }
  /**
   * Test the flag relationship on another relationship.
   */
  public function doContentView() {
    $this->drupalLogin($this->userA);
    $this->drupalGet('flag-followers/content');
    $this->assertText($this->nodeB->label());
    $this->assertNoText($this->nodeC->label());

    $this->drupalLogin($this->userB);
    $this->drupalGet('flag-followers/content');
    $this->assertText($this->nodeA->label());
    $this->assertText($this->nodeC->label());

    $this->drupalLogin($this->userC);
    $this->drupalGet('flag-followers/content');
    $this->assertNoText($this->nodeA->label());
    $this->assertNoText($this->nodeB->label());
  }
Esempio n. 15
0
 /**
  * Tests the book navigation block when book is unpublished.
  *
  * There was a fatal error with "Show block only on book pages" block mode.
  */
 public function testBookNavigationBlockOnUnpublishedBook()
 {
     // Create a new book.
     $this->createBook();
     // Create administrator user.
     $administratorUser = $this->drupalCreateUser(['administer blocks', 'administer nodes', 'bypass node access']);
     $this->drupalLogin($administratorUser);
     // Enable the block with "Show block only on book pages" mode.
     $this->drupalPlaceBlock('book_navigation', ['block_mode' => 'book pages']);
     // Unpublish book node.
     $edit = [];
     $this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save and unpublish'));
     // Test node page.
     $this->drupalGet('node/' . $this->book->id());
     $this->assertText($this->book->label(), 'Unpublished book with "Show block only on book pages" book navigation settings.');
 }
Esempio n. 16
0
 public function nodeHug(NodeInterface $node)
 {
     if ($node->isPublished()) {
         // These are the same!
         $body = $node->body->value;
         $body = $node->body[0]->value;
         // But we really want...
         $formatted = $node->body->processed;
         $terms = [];
         foreach ($node->field_tags as $tag) {
             $terms[] = $tag->entity->label();
         }
         $message = $this->t('Everyone hug @name because @reasons!', ['@name' => $node->getOwner()->label(), '@reasons' => implode(', ', $terms)]);
         return ['#title' => $node->label() . ' (' . $node->bundle() . ')', '#markup' => $message . $formatted];
     }
     return $this->t('Not published');
 }
Esempio n. 17
0
 /**
  * Update search index and search for comment.
  */
 function assertCommentAccess($assume_access, $message)
 {
     // Invoke search index update.
     search_mark_for_reindex('node_search', $this->node->id());
     $this->cronRun();
     // Search for the comment subject.
     $edit = array('keys' => "'" . $this->commentSubject . "'");
     $this->drupalPostForm('search/node', $edit, t('Search'));
     if ($assume_access) {
         $expected_node_result = $this->assertText($this->node->label());
         $expected_comment_result = $this->assertText($this->commentSubject);
     } else {
         $expected_node_result = $this->assertText(t('Your search yielded no results.'));
         $expected_comment_result = $this->assertText(t('Your search yielded no results.'));
     }
     $this->assertTrue($expected_node_result && $expected_comment_result, $message);
 }
 /**
  * Discussed at 47:00 in https://www.youtube.com/watch?v=8vwC_01KFLo
  * @param NodeInterface $node
  * @return type
  */
 public function nodeMyHug(NodeInterface $node)
 {
     if ($node->isPublished()) {
         // These are the same!  BUT DO NOT USE! (See below)
         $body = $node->body->value;
         // works even when body is multi-valued (gets the first one)
         $body = $node->body[0]->value;
         // works even when body is single-valued (gets the only one)
         // But we really want the processed value, which has been run through drupal's filters
         $formatted = $node->body->processed;
         $terms = [];
         foreach ($node->field_tags as $tag) {
             $terms[] = $tag->entity->label();
         }
         $message = $this->t('Everyone give @name a my_hug because @reasons!', ['@name' => $node->getOwner()->label(), '@reasons' => implode(', ', $terms)]);
         return ['#title' => $node->label() . ' (' . $node->bundle() . ')', '#markup' => $message . $formatted];
     }
     return $this->t('Not published');
 }
 /**
  * Tests advanced search by node type.
  */
 function testNodeType()
 {
     // Verify some properties of the node that was created.
     $this->assertTrue($this->node->getType() == 'page', 'Node type is Basic page.');
     $dummy_title = 'Lorem ipsum';
     $this->assertNotEqual($dummy_title, $this->node->label(), "Dummy title doesn't equal node title.");
     // Search for the dummy title with a GET query.
     $this->drupalGet('search/node', array('query' => array('keys' => $dummy_title)));
     $this->assertNoText($this->node->label(), 'Basic page node is not found with dummy title.');
     // Search for the title of the node with a GET query.
     $this->drupalGet('search/node', array('query' => array('keys' => $this->node->label())));
     $this->assertText($this->node->label(), 'Basic page node is found with GET query.');
     // Search for the title of the node with a POST query.
     $edit = array('or' => $this->node->label());
     $this->drupalPostForm('search/node', $edit, t('Advanced search'));
     $this->assertText($this->node->label(), 'Basic page node is found with POST query.');
     // Search by node type.
     $this->drupalPostForm('search/node', array_merge($edit, array('type[page]' => 'page')), t('Advanced search'));
     $this->assertText($this->node->label(), 'Basic page node is found with POST query and type:page.');
     $this->drupalPostForm('search/node', array_merge($edit, array('type[article]' => 'article')), t('Advanced search'));
     $this->assertText('search yielded no results', 'Article node is not found with POST query and type:article.');
 }
Esempio n. 20
0
 /**
  * Tests that user only has access to the their own nodes.
  *
  * @param \Drupal\node\Entity\Node $host_node
  *   The node of the type of ief_simple_single
  * @param int $child_count
  *   The number of entity reference values in the "single" field.
  */
 protected function checkEditAccess(NodeInterface $host_node, $child_count, $cardinality)
 {
     $other_user = $this->createUser(['edit own ief_test_custom content', 'edit any ief_simple_single content']);
     /** @var  \Drupal\node\Entity\Node $first_child_node */
     $first_child_node = $host_node->single[0]->entity;
     $first_child_node->setOwner($other_user);
     $first_child_node->save();
     $this->drupalGet("node/{$host_node->id()}/edit");
     $this->assertText($first_child_node->label());
     $this->assertNoFieldByName('single[0][inline_entity_form][title][0][value]', NULL, 'Form of child node with no edit access is not found.');
     // Check that the forms for other child nodes(if any) appear on the form.
     $delta = 1;
     while ($delta < $child_count) {
         /** @var \Drupal\node\Entity\Node $child_node */
         $child_node = $host_node->single[$delta]->entity;
         $this->assertFieldByName("single[{$delta}][inline_entity_form][title][0][value]", $child_node->label(), 'Form of child node with edit access is found.');
         $delta++;
     }
     // Check that there is NOT an extra "add" form when editing.
     $unexpected_item_number = $child_count;
     $this->assertNoFieldByName("single[{$unexpected_item_number}][inline_entity_form][title][0][value]", NULL, 'No empty "add" entity form is found on edit.');
     if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
         $next_item_number = $child_count;
         $this->drupalPostAjaxForm(NULL, [], 'single_add_more');
         $this->assertFieldByName("single[{$next_item_number}][inline_entity_form][title][0][value]", NULL, "Item {$next_item_number} does appear after 'Add More' clicked");
         // Make sure only 1 item is added.
         $unexpected_item_number = $next_item_number + 1;
         $this->assertNoFieldByName("single[{$unexpected_item_number}][inline_entity_form][title][0][value]", NULL, "Extra Item {$unexpected_item_number} is not added after 'Add More' clicked");
     }
     // Now that we have confirmed the correct fields appear, lets update the
     // values and save them. We do not have access to form for delta 0 because
     // it is owned by another user.
     $delta = 1;
     $new_titles = [];
     $edit = [];
     // Loop through an update all child node titles.
     while ($delta < $child_count) {
         /** @var \Drupal\node\Entity\Node $child_node */
         $child_node = $host_node->single[$delta]->entity;
         $new_titles[$delta] = $child_node->label() . ' - updated';
         $edit["single[{$delta}][inline_entity_form][title][0][value]"] = $new_titles[$delta];
         $delta++;
     }
     // If CARDINALITY_UNLIMITED then we should have 1 extra form open.
     if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
         $new_titles[$delta] = 'Title for new child';
         $edit["single[{$delta}][inline_entity_form][title][0][value]"] = $new_titles[$delta];
     }
     $this->drupalPostForm(NULL, $edit, t('Save'));
     $this->assertText("IEF single simple {$host_node->label()} has been updated.");
     // Reset cache for nodes.
     $node_ids = [$host_node->id()];
     foreach ($host_node->single as $item) {
         $node_ids[] = $item->entity->id();
     }
     $this->nodeStorage->resetCache($node_ids);
     $host_node = $this->nodeStorage->load($host_node->id());
     // Check that titles were updated.
     foreach ($new_titles as $delta => $new_title) {
         $child_node = $host_node->single[$delta]->entity;
         $this->assertEqual($child_node->label(), $new_title, "Child {$delta} node title updated");
     }
 }
 /**
  * Build the default links (Read more) for a node.
  *
  * @param \Drupal\node\NodeInterface $entity
  *   The node object.
  * @param string $view_mode
  *   A view mode identifier.
  *
  * @return array
  *   An array that can be processed by drupal_pre_render_links().
  */
 protected static function buildLinks(NodeInterface $entity, $view_mode)
 {
     $links = array();
     // 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('@title' => $node_title_stripped)), 'url' => $entity->urlInfo(), 'language' => $entity->language(), 'html' => TRUE, 'attributes' => array('rel' => 'tag', 'title' => $node_title_stripped));
     }
     return array('#theme' => 'links__node__node', '#links' => $links, '#attributes' => array('class' => array('links', 'inline')));
 }
Esempio n. 22
0
 /**
  * {@inheritdoc}
  */
 public function addFormElements(array $form, FormStateInterface $form_state, NodeInterface $node, AccountInterface $account, $collapsed = TRUE)
 {
     // If the form is being processed during the Ajax callback of our book bid
     // dropdown, then $form_state will hold the value that was selected.
     if ($form_state->hasValue('book')) {
         $node->book = $form_state->getValue('book');
     }
     $form['book'] = array('#type' => 'details', '#title' => $this->t('Book outline'), '#weight' => 10, '#open' => !$collapsed, '#group' => 'advanced', '#attributes' => array('class' => array('book-outline-form')), '#attached' => array('library' => array('book/drupal.book')), '#tree' => TRUE);
     foreach (array('nid', 'has_children', 'original_bid', 'parent_depth_limit') as $key) {
         $form['book'][$key] = array('#type' => 'value', '#value' => $node->book[$key]);
     }
     $form['book']['pid'] = $this->addParentSelectFormElements($node->book);
     // @see \Drupal\book\Form\BookAdminEditForm::bookAdminTableTree(). The
     // weight may be larger than 15.
     $form['book']['weight'] = array('#type' => 'weight', '#title' => $this->t('Weight'), '#default_value' => $node->book['weight'], '#delta' => max(15, abs($node->book['weight'])), '#weight' => 5, '#description' => $this->t('Pages at a given level are ordered first by weight and then by title.'));
     $options = array();
     $nid = !$node->isNew() ? $node->id() : 'new';
     if ($node->id() && $nid == $node->book['original_bid'] && $node->book['parent_depth_limit'] == 0) {
         // This is the top level node in a maximum depth book and thus cannot be
         // moved.
         $options[$node->id()] = $node->label();
     } else {
         foreach ($this->getAllBooks() as $book) {
             $options[$book['nid']] = $book['title'];
         }
     }
     if ($account->hasPermission('create new books') && ($nid == 'new' || $nid != $node->book['original_bid'])) {
         // The node can become a new book, if it is not one already.
         $options = array($nid => $this->t('- Create a new book -')) + $options;
     }
     if (!$node->book['bid']) {
         // The node is not currently in the hierarchy.
         $options = array(0 => $this->t('- None -')) + $options;
     }
     // Add a drop-down to select the destination book.
     $form['book']['bid'] = array('#type' => 'select', '#title' => $this->t('Book'), '#default_value' => $node->book['bid'], '#options' => $options, '#access' => (bool) $options, '#description' => $this->t('Your page will be a part of the selected book.'), '#weight' => -5, '#attributes' => array('class' => array('book-title-select')), '#ajax' => array('callback' => 'book_form_update', 'wrapper' => 'edit-book-plid-wrapper', 'effect' => 'fade', 'speed' => 'fast'));
     return $form;
 }
Esempio n. 23
0
 /**
  * Generates an overview table of older revisions of a node.
  *
  * @param \Drupal\node\NodeInterface $node
  *   A node object.
  *
  * @return array
  *   An array as expected by drupal_render().
  */
 public function revisionOverview(NodeInterface $node)
 {
     $account = $this->currentUser();
     $node_storage = $this->entityManager()->getStorage('node');
     $type = $node->getType();
     $build = array();
     $build['#title'] = $this->t('Revisions for %title', array('%title' => $node->label()));
     $header = array($this->t('Revision'), $this->t('Operations'));
     $revert_permission = ($account->hasPermission("revert {$type} revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update');
     $delete_permission = ($account->hasPermission("delete {$type} revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete');
     $rows = array();
     $vids = $node_storage->revisionIds($node);
     foreach (array_reverse($vids) as $vid) {
         if ($revision = $node_storage->loadRevision($vid)) {
             $row = array();
             $revision_author = $revision->uid->entity;
             if ($vid == $node->getRevisionId()) {
                 $username = array('#theme' => 'username', '#account' => $revision_author);
                 $row[] = array('data' => $this->t('!date by !username', array('!date' => $node->link($this->dateFormatter->format($revision->revision_timestamp->value, 'short')), '!username' => drupal_render($username))) . ($revision->revision_log->value != '' ? '<p class="revision-log">' . Xss::filter($revision->revision_log->value) . '</p>' : ''), 'class' => array('revision-current'));
                 $row[] = array('data' => SafeMarkup::placeholder($this->t('current revision')), 'class' => array('revision-current'));
             } else {
                 $username = array('#theme' => 'username', '#account' => $revision_author);
                 $row[] = $this->t('!date by !username', array('!date' => $this->l($this->dateFormatter->format($revision->revision_timestamp->value, 'short'), new Url('entity.node.revision', array('node' => $node->id(), 'node_revision' => $vid))), '!username' => drupal_render($username))) . ($revision->revision_log->value != '' ? '<p class="revision-log">' . Xss::filter($revision->revision_log->value) . '</p>' : '');
                 if ($revert_permission) {
                     $links['revert'] = array('title' => $this->t('Revert'), 'url' => Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]));
                 }
                 if ($delete_permission) {
                     $links['delete'] = array('title' => $this->t('Delete'), 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]));
                 }
                 $row[] = array('data' => array('#type' => 'operations', '#links' => $links));
             }
             $rows[] = $row;
         }
     }
     $build['node_revisions_table'] = array('#theme' => 'table', '#rows' => $rows, '#header' => $header, '#attached' => array('library' => array('node/drupal.node.admin')));
     return $build;
 }
Esempio n. 24
0
 public function testEntityLanguage(NodeInterface $node)
 {
     return ['#markup' => $node->label()];
 }
 /**
  * Tests a simple site export import case.
  */
 public function testExportImport()
 {
     // After installation there is no snapshot and nothing to import.
     $this->drupalGet('admin/config/development/configuration');
     $this->assertNoText(t('Warning message'));
     $this->assertText(t('There are no configuration changes to import.'));
     $this->originalSlogan = $this->config('system.site')->get('slogan');
     $this->newSlogan = $this->randomString(16);
     $this->assertNotEqual($this->newSlogan, $this->originalSlogan);
     $this->config('system.site')->set('slogan', $this->newSlogan)->save();
     $this->assertEqual($this->config('system.site')->get('slogan'), $this->newSlogan);
     // Create a content type.
     $this->contentType = $this->drupalCreateContentType();
     // Create a field.
     $this->fieldName = Unicode::strtolower($this->randomMachineName());
     $this->fieldStorage = entity_create('field_storage_config', array('field_name' => $this->fieldName, 'entity_type' => 'node', 'type' => 'text'));
     $this->fieldStorage->save();
     entity_create('field_config', array('field_storage' => $this->fieldStorage, 'bundle' => $this->contentType->id()))->save();
     // Update the displays so that configuration does not change unexpectedly on
     // import.
     entity_get_form_display('node', $this->contentType->id(), 'default')->setComponent($this->fieldName, array('type' => 'text_textfield'))->save();
     entity_get_display('node', $this->contentType->id(), 'full')->setComponent($this->fieldName)->save();
     entity_get_display('node', $this->contentType->id(), 'default')->setComponent($this->fieldName)->save();
     entity_get_display('node', $this->contentType->id(), 'teaser')->removeComponent($this->fieldName)->save();
     $this->drupalGet('node/add/' . $this->contentType->id());
     $this->assertFieldByName("{$this->fieldName}[0][value]", '', 'Widget is displayed');
     // Export the configuration.
     $this->drupalPostForm('admin/config/development/configuration/full/export', array(), 'Export');
     $this->tarball = $this->getRawContent();
     $this->config('system.site')->set('slogan', $this->originalSlogan)->save();
     $this->assertEqual($this->config('system.site')->get('slogan'), $this->originalSlogan);
     // Delete the custom field.
     $fields = FieldConfig::loadMultiple();
     foreach ($fields as $field) {
         if ($field->getName() == $this->fieldName) {
             $field->delete();
         }
     }
     $field_storages = FieldStorageConfig::loadMultiple();
     foreach ($field_storages as $field_storage) {
         if ($field_storage->getName() == $this->fieldName) {
             $field_storage->delete();
         }
     }
     $this->drupalGet('node/add/' . $this->contentType->id());
     $this->assertNoFieldByName("{$this->fieldName}[0][value]", '', 'Widget is not displayed');
     // Import the configuration.
     $filename = 'temporary://' . $this->randomMachineName();
     file_put_contents($filename, $this->tarball);
     $this->drupalPostForm('admin/config/development/configuration/full/import', array('files[import_tarball]' => $filename), 'Upload');
     // There is no snapshot yet because an import has never run.
     $this->assertNoText(t('Warning message'));
     $this->assertNoText(t('There are no configuration changes to import.'));
     $this->assertText($this->contentType->label());
     $this->drupalPostForm(NULL, array(), 'Import all');
     // After importing the snapshot has been updated an there are no warnings.
     $this->assertNoText(t('Warning message'));
     $this->assertText(t('There are no configuration changes to import.'));
     $this->assertEqual($this->config('system.site')->get('slogan'), $this->newSlogan);
     $this->drupalGet('node/add');
     $this->assertFieldByName("{$this->fieldName}[0][value]", '', 'Widget is displayed');
     $this->config('system.site')->set('slogan', $this->originalSlogan)->save();
     $this->drupalGet('admin/config/development/configuration');
     $this->assertText(t('Warning message'));
     $this->assertText('The following items in your active configuration have changes since the last import that may be lost on the next import.');
     // Ensure the item is displayed as part of a list (to avoid false matches
     // on the rest of the page) and that the list markup is not escaped.
     $this->assertRaw('<li>system.site</li>');
     // Remove everything from staging. The warning about differences between the
     // active and snapshot should no longer exist.
     \Drupal::service('config.storage.staging')->deleteAll();
     $this->drupalGet('admin/config/development/configuration');
     $this->assertNoText(t('Warning message'));
     $this->assertNoText('The following items in your active configuration have changes since the last import that may be lost on the next import.');
     $this->assertText(t('There are no configuration changes to import.'));
     // Write a file to staging. The warning about differences between the
     // active and snapshot should now exist.
     /** @var \Drupal\Core\Config\StorageInterface $staging */
     $staging = $this->container->get('config.storage.staging');
     $data = $this->config('system.site')->get();
     $data['slogan'] = 'in the face';
     $this->copyConfig($this->container->get('config.storage'), $staging);
     $staging->write('system.site', $data);
     $this->drupalGet('admin/config/development/configuration');
     $this->assertText(t('Warning message'));
     $this->assertText('The following items in your active configuration have changes since the last import that may be lost on the next import.');
     // Ensure the item is displayed as part of a list (to avoid false matches
     // on the rest of the page) and that the list markup is not escaped.
     $this->assertRaw('<li>system.site</li>');
 }
 /**
  * Generates an overview table of older revisions of a node.
  *
  * @param \Drupal\node\NodeInterface $node
  *   A node object.
  *
  * @return array
  *   An array as expected by drupal_render().
  */
 public function revisionOverview(NodeInterface $node)
 {
     $account = $this->currentUser();
     $node_storage = $this->entityManager()->getStorage('node');
     $type = $node->getType();
     $build = array();
     $build['#title'] = $this->t('Revisions for %title', array('%title' => $node->label()));
     $header = array($this->t('Revision'), $this->t('Operations'));
     $revert_permission = ($account->hasPermission("revert {$type} revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update');
     $delete_permission = ($account->hasPermission("delete {$type} revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete');
     $rows = array();
     $vids = $node_storage->revisionIds($node);
     foreach (array_reverse($vids) as $vid) {
         $revision = $node_storage->loadRevision($vid);
         $username = ['#theme' => 'username', '#account' => $revision->uid->entity];
         // Use revision link to link to revisions that are not active.
         $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
         if ($vid != $node->getRevisionId()) {
             $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]));
         } else {
             $link = $node->link($date);
         }
         $row = [];
         $column = ['data' => ['#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => ['date' => $link, 'username' => $this->renderer->renderPlain($username), 'message' => Xss::filter($revision->revision_log->value)]]];
         // @todo Simplify once https://www.drupal.org/node/2334319 lands.
         $this->renderer->addCacheableDependency($column['data'], $username);
         $row[] = $column;
         if ($vid == $node->getRevisionId()) {
             $row[0]['class'] = ['revision-current'];
             $row[] = ['data' => SafeMarkup::placeholder($this->t('current revision')), 'class' => ['revision-current']];
         } else {
             $links = [];
             if ($revert_permission) {
                 $links['revert'] = ['title' => $this->t('Revert'), 'url' => Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid])];
             }
             if ($delete_permission) {
                 $links['delete'] = ['title' => $this->t('Delete'), 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid])];
             }
             $row[] = ['data' => ['#type' => 'operations', '#links' => $links]];
         }
         $rows[] = $row;
     }
     $build['node_revisions_table'] = array('#theme' => 'table', '#rows' => $rows, '#header' => $header, '#attached' => array('library' => array('node/drupal.node.admin')));
     return $build;
 }
Esempio n. 27
0
 public function testEntityLanguage(NodeInterface $node)
 {
     $build = ['#markup' => $node->label()];
     \Drupal::service('renderer')->addCacheableDependency($build, $node);
     return $build;
 }
Esempio n. 28
0
 /**
  * {@inheritdoc}
  */
 public function getQuestion()
 {
     return $this->t('Are you sure you want to remove %title from the book hierarchy?', array('%title' => $this->node->label()));
 }
Esempio n. 29
0
 /**
  * Generates an overview table of older revisions of a node.
  *
  * @param \Drupal\node\NodeInterface $node
  *   A node object.
  *
  * @return array
  *   An array as expected by drupal_render().
  */
 public function revisionOverview(NodeInterface $node)
 {
     $account = $this->currentUser();
     $langcode = $node->language()->getId();
     $langname = $node->language()->getName();
     $languages = $node->getTranslationLanguages();
     $has_translations = count($languages) > 1;
     $node_storage = $this->entityManager()->getStorage('node');
     $type = $node->getType();
     $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]);
     $header = array($this->t('Revision'), $this->t('Operations'));
     $revert_permission = ($account->hasPermission("revert {$type} revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update');
     $delete_permission = ($account->hasPermission("delete {$type} revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete');
     $rows = array();
     $vids = $node_storage->revisionIds($node);
     $latest_revision = TRUE;
     foreach (array_reverse($vids) as $vid) {
         /** @var \Drupal\node\NodeInterface $revision */
         $revision = $node_storage->loadRevision($vid);
         // Only show revisions that are affected by the language that is being
         // displayed.
         if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
             $username = ['#theme' => 'username', '#account' => $revision->getRevisionAuthor()];
             // Use revision link to link to revisions that are not active.
             $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
             if ($vid != $node->getRevisionId()) {
                 $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]));
             } else {
                 $link = $node->link($date);
             }
             $row = [];
             $column = ['data' => ['#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => ['date' => $link, 'username' => $this->renderer->renderPlain($username), 'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()]]]];
             // @todo Simplify once https://www.drupal.org/node/2334319 lands.
             $this->renderer->addCacheableDependency($column['data'], $username);
             $row[] = $column;
             if ($latest_revision) {
                 $row[] = ['data' => ['#prefix' => '<em>', '#markup' => $this->t('Current revision'), '#suffix' => '</em>']];
                 foreach ($row as &$current) {
                     $current['class'] = ['revision-current'];
                 }
                 $latest_revision = FALSE;
             } else {
                 $links = [];
                 if ($revert_permission) {
                     $links['revert'] = ['title' => $this->t('Revert'), 'url' => $has_translations ? Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) : Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid])];
                 }
                 if ($delete_permission) {
                     $links['delete'] = ['title' => $this->t('Delete'), 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid])];
                 }
                 $row[] = ['data' => ['#type' => 'operations', '#links' => $links]];
             }
             $rows[] = $row;
         }
     }
     $build['node_revisions_table'] = array('#theme' => 'table', '#rows' => $rows, '#header' => $header, '#attached' => array('library' => array('node/drupal.node.admin')));
     return $build;
 }
 /**
  * Tests a simple site export import case.
  */
 public function testExportImport()
 {
     // After installation there is no snapshot and nothing to import.
     $this->drupalGet('admin/config/development/configuration');
     $this->assertNoText(t('Warning message'));
     $this->assertText(t('There are no configuration changes to import.'));
     $this->originalSlogan = $this->config('system.site')->get('slogan');
     $this->newSlogan = $this->randomString(16);
     $this->assertNotEqual($this->newSlogan, $this->originalSlogan);
     $this->config('system.site')->set('slogan', $this->newSlogan)->save();
     $this->assertEqual($this->config('system.site')->get('slogan'), $this->newSlogan);
     // Create a content type.
     $this->contentType = $this->drupalCreateContentType();
     // Create a field.
     $this->fieldName = Unicode::strtolower($this->randomMachineName());
     $this->fieldStorage = entity_create('field_storage_config', array('field_name' => $this->fieldName, 'entity_type' => 'node', 'type' => 'text'));
     $this->fieldStorage->save();
     entity_create('field_config', array('field_storage' => $this->fieldStorage, 'bundle' => $this->contentType->id()))->save();
     // Update the displays so that configuration does not change unexpectedly on
     // import.
     entity_get_form_display('node', $this->contentType->id(), 'default')->setComponent($this->fieldName, array('type' => 'text_textfield'))->save();
     entity_get_display('node', $this->contentType->id(), 'full')->setComponent($this->fieldName)->save();
     entity_get_display('node', $this->contentType->id(), 'default')->setComponent($this->fieldName)->save();
     entity_get_display('node', $this->contentType->id(), 'teaser')->removeComponent($this->fieldName)->save();
     $this->drupalGet('node/add/' . $this->contentType->id());
     $this->assertFieldByName("{$this->fieldName}[0][value]", '', 'Widget is displayed');
     // Export the configuration.
     $this->drupalPostForm('admin/config/development/configuration/full/export', array(), 'Export');
     $this->tarball = $this->getRawContent();
     $this->config('system.site')->set('slogan', $this->originalSlogan)->save();
     $this->assertEqual($this->config('system.site')->get('slogan'), $this->originalSlogan);
     // Delete the custom field.
     $fields = FieldConfig::loadMultiple();
     foreach ($fields as $field) {
         if ($field->field_name == $this->fieldName) {
             $field->delete();
         }
     }
     $field_storages = FieldStorageConfig::loadMultiple();
     foreach ($field_storages as $field_storage) {
         if ($field_storage->getName() == $this->fieldName) {
             $field_storage->delete();
         }
     }
     $this->drupalGet('node/add/' . $this->contentType->id());
     $this->assertNoFieldByName("{$this->fieldName}[0][value]", '', 'Widget is not displayed');
     // Import the configuration.
     $filename = 'temporary://' . $this->randomMachineName();
     file_put_contents($filename, $this->tarball);
     $this->drupalPostForm('admin/config/development/configuration/full/import', array('files[import_tarball]' => $filename), 'Upload');
     // There is no snapshot yet because an import has never run.
     $this->assertNoText(t('Warning message'));
     $this->assertNoText(t('There are no configuration changes to import.'));
     $this->assertText($this->contentType->label());
     $this->drupalPostForm(NULL, array(), 'Import all');
     // After importing the snapshot has been updated an there are no warnings.
     $this->assertNoText(t('Warning message'));
     $this->assertText(t('There are no configuration changes to import.'));
     $this->assertEqual($this->config('system.site')->get('slogan'), $this->newSlogan);
     $this->drupalGet('node/add');
     $this->assertFieldByName("{$this->fieldName}[0][value]", '', 'Widget is displayed');
     $this->config('system.site')->set('slogan', $this->originalSlogan)->save();
     $this->drupalGet('admin/config/development/configuration');
     $this->assertText(t('Warning message'));
     $this->assertText('Your current configuration has changed. Changes to these configuration items will be lost on the next synchronization: system.site');
     // Remove everything from staging. The warning about differences between the
     // active and snapshot should still exist.
     \Drupal::service('config.storage.staging')->deleteAll();
     $this->drupalGet('admin/config/development/configuration');
     $this->assertText(t('Warning message'));
     $this->assertText('Your current configuration has changed. Changes to these configuration items will be lost on the next synchronization: system.site');
     $this->assertText(t('There are no configuration changes to import.'));
 }