MediaWiki  master
PPNode_Hash_Tree.php
Go to the documentation of this file.
1 <?php
25 // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
26 class PPNode_Hash_Tree implements PPNode {
27 
28  public $name;
29 
35  private $rawChildren;
36 
40  private $store;
41 
45  private $index;
46 
51  public const NAME = 0;
52 
57  public const CHILDREN = 1;
58 
66  public function __construct( array $store, $index ) {
67  $this->store = $store;
68  $this->index = $index;
69  list( $this->name, $this->rawChildren ) = $this->store[$index];
70  }
71 
81  public static function factory( array $store, $index ) {
82  if ( !isset( $store[$index] ) ) {
83  return false;
84  }
85 
86  $descriptor = $store[$index];
87  if ( is_string( $descriptor ) ) {
88  $class = PPNode_Hash_Text::class;
89  } elseif ( is_array( $descriptor ) ) {
90  if ( $descriptor[self::NAME][0] === '@' ) {
91  $class = PPNode_Hash_Attr::class;
92  } else {
93  $class = self::class;
94  }
95  } else {
96  throw new MWException( __METHOD__ . ': invalid node descriptor' );
97  }
98  return new $class( $store, $index );
99  }
100 
105  public function __toString() {
106  $inner = '';
107  $attribs = '';
108  for ( $node = $this->getFirstChild(); $node; $node = $node->getNextSibling() ) {
109  if ( $node instanceof PPNode_Hash_Attr ) {
110  $attribs .= ' ' . $node->name . '="' . htmlspecialchars( $node->value ) . '"';
111  } else {
112  $inner .= $node->__toString();
113  }
114  }
115  if ( $inner === '' ) {
116  return "<{$this->name}$attribs/>";
117  } else {
118  return "<{$this->name}$attribs>$inner</{$this->name}>";
119  }
120  }
121 
125  public function getChildren() {
126  $children = [];
127  foreach ( $this->rawChildren as $i => $child ) {
128  $children[] = self::factory( $this->rawChildren, $i );
129  }
130  return new PPNode_Hash_Array( $children );
131  }
132 
140  public function getFirstChild() {
141  if ( !isset( $this->rawChildren[0] ) ) {
142  return false;
143  } else {
144  return self::factory( $this->rawChildren, 0 );
145  }
146  }
147 
155  public function getNextSibling() {
156  return self::factory( $this->store, $this->index + 1 );
157  }
158 
165  public function getChildrenOfType( $name ) {
166  $children = [];
167  foreach ( $this->rawChildren as $i => $child ) {
168  if ( is_array( $child ) && $child[self::NAME] === $name ) {
169  $children[] = self::factory( $this->rawChildren, $i );
170  }
171  }
172  return new PPNode_Hash_Array( $children );
173  }
174 
179  public function getRawChildren() {
180  return $this->rawChildren;
181  }
182 
186  public function getLength() {
187  return false;
188  }
189 
194  public function item( $i ) {
195  return false;
196  }
197 
201  public function getName() {
202  return $this->name;
203  }
204 
214  public function splitArg() {
215  return self::splitRawArg( $this->rawChildren );
216  }
217 
223  public static function splitRawArg( array $children ) {
224  $bits = [];
225  foreach ( $children as $i => $child ) {
226  if ( !is_array( $child ) ) {
227  continue;
228  }
229  if ( $child[self::NAME] === 'name' ) {
230  $bits['name'] = new self( $children, $i );
231  if ( isset( $child[self::CHILDREN][0][self::NAME] )
232  && $child[self::CHILDREN][0][self::NAME] === '@index'
233  ) {
234  $bits['index'] = $child[self::CHILDREN][0][self::CHILDREN][0];
235  }
236  } elseif ( $child[self::NAME] === 'value' ) {
237  $bits['value'] = new self( $children, $i );
238  }
239  }
240 
241  if ( !isset( $bits['name'] ) ) {
242  throw new MWException( 'Invalid brace node passed to ' . __METHOD__ );
243  }
244  if ( !isset( $bits['index'] ) ) {
245  $bits['index'] = '';
246  }
247  return $bits;
248  }
249 
257  public function splitExt() {
258  return self::splitRawExt( $this->rawChildren );
259  }
260 
266  public static function splitRawExt( array $children ) {
267  $bits = [];
268  foreach ( $children as $i => $child ) {
269  if ( !is_array( $child ) ) {
270  continue;
271  }
272  switch ( $child[self::NAME] ) {
273  case 'name':
274  $bits['name'] = new self( $children, $i );
275  break;
276  case 'attr':
277  $bits['attr'] = new self( $children, $i );
278  break;
279  case 'inner':
280  $bits['inner'] = new self( $children, $i );
281  break;
282  case 'close':
283  $bits['close'] = new self( $children, $i );
284  break;
285  }
286  }
287  if ( !isset( $bits['name'] ) ) {
288  throw new MWException( 'Invalid ext node passed to ' . __METHOD__ );
289  }
290  return $bits;
291  }
292 
299  public function splitHeading() {
300  if ( $this->name !== 'h' ) {
301  throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
302  }
303  return self::splitRawHeading( $this->rawChildren );
304  }
305 
311  public static function splitRawHeading( array $children ) {
312  $bits = [];
313  foreach ( $children as $i => $child ) {
314  if ( !is_array( $child ) ) {
315  continue;
316  }
317  if ( $child[self::NAME] === '@i' ) {
318  $bits['i'] = $child[self::CHILDREN][0];
319  } elseif ( $child[self::NAME] === '@level' ) {
320  $bits['level'] = $child[self::CHILDREN][0];
321  }
322  }
323  if ( !isset( $bits['i'] ) ) {
324  throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
325  }
326  return $bits;
327  }
328 
335  public function splitTemplate() {
336  return self::splitRawTemplate( $this->rawChildren );
337  }
338 
344  public static function splitRawTemplate( array $children ) {
345  $parts = [];
346  $bits = [ 'lineStart' => '' ];
347  foreach ( $children as $i => $child ) {
348  if ( !is_array( $child ) ) {
349  continue;
350  }
351  switch ( $child[self::NAME] ) {
352  case 'title':
353  $bits['title'] = new self( $children, $i );
354  break;
355  case 'part':
356  $parts[] = new self( $children, $i );
357  break;
358  case '@lineStart':
359  $bits['lineStart'] = '1';
360  break;
361  }
362  }
363  if ( !isset( $bits['title'] ) ) {
364  throw new MWException( 'Invalid node passed to ' . __METHOD__ );
365  }
366  $bits['parts'] = new PPNode_Hash_Array( $parts );
367  return $bits;
368  }
369 }
PPNode_Hash_Tree\getLength
getLength()
Definition: PPNode_Hash_Tree.php:186
PPNode_Hash_Tree\getChildrenOfType
getChildrenOfType( $name)
Get an array of the children with a given node name.
Definition: PPNode_Hash_Tree.php:165
PPNode_Hash_Tree\item
item( $i)
Definition: PPNode_Hash_Tree.php:194
PPNode_Hash_Tree\$store
$store
The store array for the siblings of this node, including this node itself.
Definition: PPNode_Hash_Tree.php:40
PPNode_Hash_Tree\getFirstChild
getFirstChild()
Get the first child, or false if there is none.
Definition: PPNode_Hash_Tree.php:140
PPNode_Hash_Tree\splitRawExt
static splitRawExt(array $children)
Like splitExt() but for a raw child array.
Definition: PPNode_Hash_Tree.php:266
PPNode_Hash_Tree\splitHeading
splitHeading()
Split an "<h>" node.
Definition: PPNode_Hash_Tree.php:299
PPNode_Hash_Tree\splitExt
splitExt()
Split an "<ext>" node into an associative array containing name, attr, inner and close All values in ...
Definition: PPNode_Hash_Tree.php:257
PPNode_Hash_Tree\splitRawArg
static splitRawArg(array $children)
Like splitArg() but for a raw child array.
Definition: PPNode_Hash_Tree.php:223
PPNode_Hash_Tree\splitRawHeading
static splitRawHeading(array $children)
Like splitHeading() but for a raw child array.
Definition: PPNode_Hash_Tree.php:311
PPNode_Hash_Tree\$name
$name
Definition: PPNode_Hash_Tree.php:28
MWException
MediaWiki exception.
Definition: MWException.php:29
PPNode_Hash_Tree\CHILDREN
const CHILDREN
The offset of the child list within descriptors, used in some places for readability.
Definition: PPNode_Hash_Tree.php:57
PPNode_Hash_Tree\getNextSibling
getNextSibling()
Get the next sibling, or false if there is none.
Definition: PPNode_Hash_Tree.php:155
PPNode_Hash_Tree\splitTemplate
splitTemplate()
Split a "<template>" or "<tplarg>" node.
Definition: PPNode_Hash_Tree.php:335
PPNode_Hash_Tree\__toString
__toString()
Convert a node to XML, for debugging.
Definition: PPNode_Hash_Tree.php:105
PPNode
There are three types of nodes:
Definition: PPNode.php:35
PPNode_Hash_Tree\splitRawTemplate
static splitRawTemplate(array $children)
Like splitTemplate() but for a raw child array.
Definition: PPNode_Hash_Tree.php:344
PPNode_Hash_Tree\__construct
__construct(array $store, $index)
Construct an object using the data from $store[$index].
Definition: PPNode_Hash_Tree.php:66
PPNode_Hash_Array
Definition: PPNode_Hash_Array.php:26
PPNode_Hash_Tree\getRawChildren
getRawChildren()
Get the raw child array.
Definition: PPNode_Hash_Tree.php:179
PPNode_Hash_Tree\getName
getName()
Definition: PPNode_Hash_Tree.php:201
PPNode_Hash_Tree\getChildren
getChildren()
Definition: PPNode_Hash_Tree.php:125
PPNode_Hash_Tree\$index
$index
The index into $this->store which contains the descriptor of this node.
Definition: PPNode_Hash_Tree.php:45
PPNode_Hash_Attr
Definition: PPNode_Hash_Attr.php:26
PPNode_Hash_Tree\$rawChildren
$rawChildren
The store array for children of this node.
Definition: PPNode_Hash_Tree.php:35
PPNode_Hash_Tree
Definition: PPNode_Hash_Tree.php:26
PPNode_Hash_Tree\factory
static factory(array $store, $index)
Construct an appropriate PPNode_Hash_* object with a class that depends on what is at the relevant st...
Definition: PPNode_Hash_Tree.php:81
PPNode_Hash_Tree\NAME
const NAME
The offset of the name within descriptors, used in some places for readability.
Definition: PPNode_Hash_Tree.php:51
PPNode_Hash_Tree\splitArg
splitArg()
Split a "<part>" node into an associative array containing:
Definition: PPNode_Hash_Tree.php:214