1<?php 2 3namespace Drupal\book; 4 5use Drupal\Core\Database\Connection; 6 7/** 8 * Defines a storage class for books outline. 9 */ 10class BookOutlineStorage implements BookOutlineStorageInterface { 11 12 /** 13 * Database Service Object. 14 * 15 * @var \Drupal\Core\Database\Connection 16 */ 17 protected $connection; 18 19 /** 20 * Constructs a BookOutlineStorage object. 21 */ 22 public function __construct(Connection $connection) { 23 $this->connection = $connection; 24 } 25 26 /** 27 * {@inheritdoc} 28 */ 29 public function getBooks() { 30 return $this->connection->query("SELECT DISTINCT([bid]) FROM {book}")->fetchCol(); 31 } 32 33 /** 34 * {@inheritdoc} 35 */ 36 public function hasBooks() { 37 return (bool) $this->connection 38 ->query('SELECT count([bid]) FROM {book}') 39 ->fetchField(); 40 } 41 42 /** 43 * {@inheritdoc} 44 */ 45 public function loadMultiple($nids, $access = TRUE) { 46 $query = $this->connection->select('book', 'b', ['fetch' => \PDO::FETCH_ASSOC]); 47 $query->fields('b'); 48 $query->condition('b.nid', $nids, 'IN'); 49 50 if ($access) { 51 $query->addTag('node_access'); 52 $query->addMetaData('base_table', 'book'); 53 } 54 55 return $query->execute(); 56 } 57 58 /** 59 * {@inheritdoc} 60 */ 61 public function getChildRelativeDepth($book_link, $max_depth) { 62 $query = $this->connection->select('book'); 63 $query->addField('book', 'depth'); 64 $query->condition('bid', $book_link['bid']); 65 $query->orderBy('depth', 'DESC'); 66 $query->range(0, 1); 67 68 $i = 1; 69 $p = 'p1'; 70 while ($i <= $max_depth && $book_link[$p]) { 71 $query->condition($p, $book_link[$p]); 72 $p = 'p' . ++$i; 73 } 74 75 return $query->execute()->fetchField(); 76 } 77 78 /** 79 * {@inheritdoc} 80 */ 81 public function delete($nid) { 82 return $this->connection->delete('book') 83 ->condition('nid', $nid) 84 ->execute(); 85 } 86 87 /** 88 * {@inheritdoc} 89 */ 90 public function loadBookChildren($pid) { 91 return $this->connection 92 ->query("SELECT * FROM {book} WHERE [pid] = :pid", [':pid' => $pid]) 93 ->fetchAllAssoc('nid', \PDO::FETCH_ASSOC); 94 } 95 96 /** 97 * {@inheritdoc} 98 */ 99 public function getBookMenuTree($bid, $parameters, $min_depth, $max_depth) { 100 $query = $this->connection->select('book'); 101 $query->fields('book'); 102 for ($i = 1; $i <= $max_depth; $i++) { 103 $query->orderBy('p' . $i, 'ASC'); 104 } 105 $query->condition('bid', $bid); 106 if (!empty($parameters['expanded'])) { 107 $query->condition('pid', $parameters['expanded'], 'IN'); 108 } 109 if ($min_depth != 1) { 110 $query->condition('depth', $min_depth, '>='); 111 } 112 if (isset($parameters['max_depth'])) { 113 $query->condition('depth', $parameters['max_depth'], '<='); 114 } 115 // Add custom query conditions, if any were passed. 116 if (isset($parameters['conditions'])) { 117 foreach ($parameters['conditions'] as $column => $value) { 118 $query->condition($column, $value); 119 } 120 } 121 122 return $query->execute(); 123 } 124 125 /** 126 * {@inheritdoc} 127 */ 128 public function insert($link, $parents) { 129 return $this->connection 130 ->insert('book') 131 ->fields([ 132 'nid' => $link['nid'], 133 'bid' => $link['bid'], 134 'pid' => $link['pid'], 135 'weight' => $link['weight'], 136 ] + $parents 137 ) 138 ->execute(); 139 } 140 141 /** 142 * {@inheritdoc} 143 */ 144 public function update($nid, $fields) { 145 return $this->connection 146 ->update('book') 147 ->fields($fields) 148 ->condition('nid', $nid) 149 ->execute(); 150 } 151 152 /** 153 * {@inheritdoc} 154 */ 155 public function updateMovedChildren($bid, $original, $expressions, $shift) { 156 $query = $this->connection->update('book'); 157 $query->fields(['bid' => $bid]); 158 159 foreach ($expressions as $expression) { 160 $query->expression($expression[0], $expression[1], $expression[2]); 161 } 162 163 $query->expression('depth', '[depth] + :depth', [':depth' => $shift]); 164 $query->condition('bid', $original['bid']); 165 $p = 'p1'; 166 for ($i = 1; !empty($original[$p]); $p = 'p' . ++$i) { 167 $query->condition($p, $original[$p]); 168 } 169 170 return $query->execute(); 171 } 172 173 /** 174 * {@inheritdoc} 175 */ 176 public function countOriginalLinkChildren($original) { 177 return $this->connection->select('book', 'b') 178 ->condition('bid', $original['bid']) 179 ->condition('pid', $original['pid']) 180 ->condition('nid', $original['nid'], '<>') 181 ->countQuery() 182 ->execute()->fetchField(); 183 } 184 185 /** 186 * {@inheritdoc} 187 */ 188 public function getBookSubtree($link, $max_depth) { 189 $query = $this->connection->select('book', 'b', ['fetch' => \PDO::FETCH_ASSOC]); 190 $query->fields('b'); 191 $query->condition('b.bid', $link['bid']); 192 193 for ($i = 1; $i <= $max_depth && $link["p$i"]; ++$i) { 194 $query->condition("p$i", $link["p$i"]); 195 } 196 for ($i = 1; $i <= $max_depth; ++$i) { 197 $query->orderBy("p$i"); 198 } 199 return $query->execute(); 200 } 201 202} 203