Commit 438f9e28 authored by alexpott's avatar alexpott

Issue #1853524 by frob, jibran, eriknewby, olli, vijaycs85, xjm, dawehner:...

Issue #1853524 by frob, jibran, eriknewby, olli, vijaycs85, xjm, dawehner: Reintroduce Views integration for Book
parent 36a23b3c
<?php
/**
* @file
* Provide views data for book.module.
*
* @ingroup views_module_handlers
*/
/**
* Implements hook_views_data().
*/
function book_views_data() {
$data = [];
$data['book'] = [];
$data['book']['table'] = [];
$data['book']['table']['group'] = t('Book');
$data['book']['table']['join'] = [
'node_field_data' => [
'left_field' => 'nid',
'field' => 'nid',
],
];
$data['book']['nid'] = [
'title' => t('Page'),
'help' => t('The book page node.'),
'relationship' => [
'base' => 'node_field_data',
'id' => 'standard',
'label' => t('Book Page'),
],
];
$data['book']['bid'] = [
'title' => t('Top level book'),
'help' => t('The book the node is in.'),
'relationship' => [
'base' => 'node_field_data',
'id' => 'standard',
'label' => t('Book'),
],
];
$data['book']['pid'] = [
'title' => t('Parent'),
'help' => t('The parent book node.'),
'relationship' => [
'base' => 'node_field_data',
'id' => 'standard',
'label' => t('Book Parent'),
],
];
$data['book']['has_children'] = [
'title' => t('Page has Children'),
'help' => t('Flag indicating whether this book page has children'),
'field' => [
'id' => 'boolean',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'boolean',
'label' => t('Has Children'),
],
'argument' => [
'id' => 'numeric',
],
];
$data['book']['weight'] = [
'title' => t('Weight'),
'help' => t('The weight of the book page.'),
'field' => [
'id' => 'numeric',
],
'sort' => [
'id' => 'standard',
],
];
$data['book']['depth'] = [
'title' => t('Depth'),
'help' => t('The depth of the book page in the hierarchy; top level books have a depth of 1.'),
'field' => [
'id' => 'numeric',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'numeric',
],
'argument' => [
'id' => 'standard',
],
];
$parents = [
1 => t('1st parent'),
2 => t('2nd parent'),
3 => t('3rd parent'),
4 => t('4th parent'),
5 => t('5th parent'),
6 => t('6th parent'),
7 => t('7th parent'),
8 => t('8th parent'),
9 => t('9th parent'),
];
foreach ($parents as $i => $parent_label) {
$data['book']["p$i"] = [
'title' => $parent_label,
'help' => t('The @parent of book node.', ['@parent' => $parent_label]),
'relationship' => [
'base' => 'node_field_data',
'id' => 'standard',
'label' => t('Book @parent', ['@parent' => $parent_label]),
],
];
}
return $data;
}
# Schema for the views plugins of the Book module.
views.argument_default.top_level_book:
type: sequence
label: 'Top Level Book from current node'
sequence:
type: string
label: 'Nid'
<?php
namespace Drupal\book\Plugin\views\argument_default;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\node\NodeStorageInterface;
use Drupal\node\Plugin\views\argument_default\Node;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Default argument plugin to get the current node's top level book.
*
* @ViewsArgumentDefault(
* id = "top_level_book",
* title = @Translation("Top Level Book from current node")
* )
*/
class TopLevelBook extends Node {
/**
* The node storage controller.
*
* @var \Drupal\node\NodeStorageInterface
*/
protected $nodeStorage;
/**
* Constructs a Drupal\book\Plugin\views\argument_default\TopLevelBook object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param array $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match.
* @param \Drupal\node\NodeStorageInterface $node_storage
* The node storage controller.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, RouteMatchInterface $route_match, NodeStorageInterface $node_storage) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $route_match);
$this->nodeStorage = $node_storage;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_route_match'),
$container->get('entity.manager')->getStorage('node')
);
}
/**
* {@inheritdoc}
*/
public function getArgument() {
// Use the argument_default_node plugin to get the nid argument.
$nid = parent::getArgument();
if (!empty($nid)) {
$node = $this->nodeStorage->load($nid);
if (isset($node->book['bid'])) {
return $node->book['bid'];
}
}
}
}
<?php
namespace Drupal\book\Tests\Views;
use Drupal\views\Tests\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
* Tests entity reference relationship data.
*
* @group book
*
* @see book_views_data()
*/
class BookRelationshipTest extends ViewTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_book_view');
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('book_test_views', 'book', 'views');
/**
* A book node.
*
* @var object
*/
protected $book;
/**
* A user with permission to create and edit books.
*
* @var object
*/
protected $bookAuthor;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create users.
$this->bookAuthor = $this->drupalCreateUser(
array(
'create new books',
'create book content',
'edit own book content',
'add content to books',
)
);
ViewTestData::createTestViews(get_class($this), array('book_test_views'));
}
/**
* Creates a new book with a page hierarchy.
*/
protected function createBook() {
// Create new book.
$this->drupalLogin($this->bookAuthor);
$this->book = $this->createBookNode('new');
$book = $this->book;
$nodes = array();
// Node 0.
$nodes[] = $this->createBookNode($book->id());
// Node 1.
$nodes[] = $this->createBookNode($book->id(), $nodes[0]->book['nid']);
// Node 2.
$nodes[] = $this->createBookNode($book->id(), $nodes[1]->book['nid']);
// Node 3.
$nodes[] = $this->createBookNode($book->id(), $nodes[2]->book['nid']);
// Node 4.
$nodes[] = $this->createBookNode($book->id(), $nodes[3]->book['nid']);
// Node 5.
$nodes[] = $this->createBookNode($book->id(), $nodes[4]->book['nid']);
// Node 6.
$nodes[] = $this->createBookNode($book->id(), $nodes[5]->book['nid']);
// Node 7.
$nodes[] = $this->createBookNode($book->id(), $nodes[6]->book['nid']);
$this->drupalLogout();
return $nodes;
}
/**
* Creates a book node.
*
* @param int|string $book_nid
* A book node ID or set to 'new' to create a new book.
* @param int|null $parent
* (optional) Parent book reference ID. Defaults to NULL.
*
* @return \Drupal\node\NodeInterface
* The book node.
*/
protected function createBookNode($book_nid, $parent = NULL) {
// $number does not use drupal_static as it should not be reset
// since it uniquely identifies each call to createBookNode().
// Used to ensure that when sorted nodes stay in same order.
static $number = 0;
$edit = array();
$edit['title[0][value]'] = $number . ' - SimpleTest test node ' . $this->randomMachineName(10);
$edit['body[0][value]'] = 'SimpleTest test body ' . $this->randomMachineName(32) . ' ' . $this->randomMachineName(32);
$edit['book[bid]'] = $book_nid;
if ($parent !== NULL) {
$this->drupalPostForm('node/add/book', $edit, t('Change book (update list of parents)'));
$edit['book[pid]'] = $parent;
$this->drupalPostForm(NULL, $edit, t('Save'));
// Make sure the parent was flagged as having children.
$parent_node = \Drupal::entityManager()->getStorage('node')->loadUnchanged($parent);
$this->assertFalse(empty($parent_node->book['has_children']), 'Parent node is marked as having children');
}
else {
$this->drupalPostForm('node/add/book', $edit, t('Save'));
}
// Check to make sure the book node was created.
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
$this->assertNotNull(($node === FALSE ? NULL : $node), 'Book node found in database.');
$number++;
return $node;
}
/**
* Tests using the views relationship.
*/
public function testRelationship() {
// Create new book.
// @var \Drupal\node\NodeInterface[] $nodes
$nodes = $this->createBook();
for ($i = 0; $i < 8; $i++) {
$this->drupalGet('test-book/' . $nodes[$i]->id());
for ($j = 0; $j < $i; $j++) {
$this->assertLink($nodes[$j]->label());
}
}
}
}
name: 'Book test views'
type: module
description: 'Provides default views for views book tests.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- book
- views
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment