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 
29  public $name;
30 
37  private $rawChildren;
38 
43  private $store;
44 
49  private $index;
50 
55  public const NAME = 0;
56 
61  public const CHILDREN = 1;
62 
70  public function __construct( array $store, $index ) {
71  $this->store = $store;
72  $this->index = $index;
73  list( $this->name, $this->rawChildren ) = $this->store[$index];
74  }
75 
85  public static function factory( array $store, $index ) {
86  if ( !isset( $store[$index] ) ) {
87  return false;
88  }
89 
90  $descriptor = $store[$index];
91  if ( is_string( $descriptor ) ) {
92  $class = PPNode_Hash_Text::class;
93  } elseif ( is_array( $descriptor ) ) {
94  if ( $descriptor[self::NAME][0] === '@' ) {
95  $class = PPNode_Hash_Attr::class;
96  } else {
97  $class = self::class;
98  }
99  } else {
100  throw new MWException( __METHOD__ . ': invalid node descriptor' );
101  }
102  return new $class( $store, $index );
103  }
104 
109  public function __toString() {
110  $inner = '';
111  $attribs = '';
112  for ( $node = $this->getFirstChild(); $node; $node = $node->getNextSibling() ) {
113  if ( $node instanceof PPNode_Hash_Attr ) {
114  $attribs .= ' ' . $node->name . '="' . htmlspecialchars( $node->value ) . '"';
115  } else {
116  $inner .= $node->__toString();
117  }
118  }
119  if ( $inner === '' ) {
120  return "<{$this->name}$attribs/>";
121  } else {
122  return "<{$this->name}$attribs>$inner</{$this->name}>";
123  }
124  }
125 
129  public function getChildren() {
130  $children = [];
131  foreach ( $this->rawChildren as $i => $child ) {
132  $children[] = self::factory( $this->rawChildren, $i );
133  }
134  return new PPNode_Hash_Array( $children );
135  }
136 
144  public function getFirstChild() {
145  if ( !isset( $this->rawChildren[0] ) ) {
146  return false;
147  } else {
148  return self::factory( $this->rawChildren, 0 );
149  }
150  }
151 
159  public function getNextSibling() {
160  return self::factory( $this->store, $this->index + 1 );
161  }
162 
169  public function getChildrenOfType( $name ) {
170  $children = [];
171  foreach ( $this->rawChildren as $i => $child ) {
172  if ( is_array( $child ) && $child[self::NAME] === $name ) {
173  $children[] = self::factory( $this->rawChildren, $i );
174  }
175  }
176  return new PPNode_Hash_Array( $children );
177  }
178 
183  public function getRawChildren() {
184  return $this->rawChildren;
185  }
186 
190  public function getLength() {
191  return false;
192  }
193 
198  public function item( $i ) {
199  return false;
200  }
201 
205  public function getName() {
206  return $this->name;
207  }
208 
218  public function splitArg() {
219  return self::splitRawArg( $this->rawChildren );
220  }
221 
227  public static function splitRawArg( array $children ) {
228  $bits = [];
229  foreach ( $children as $i => $child ) {
230  if ( !is_array( $child ) ) {
231  continue;
232  }
233  if ( $child[self::NAME] === 'name' ) {
234  $bits['name'] = new self( $children, $i );
235  if ( isset( $child[self::CHILDREN][0][self::NAME] )
236  && $child[self::CHILDREN][0][self::NAME] === '@index'
237  ) {
238  $bits['index'] = $child[self::CHILDREN][0][self::CHILDREN][0];
239  }
240  } elseif ( $child[self::NAME] === 'value' ) {
241  $bits['value'] = new self( $children, $i );
242  }
243  }
244 
245  if ( !isset( $bits['name'] ) ) {
246  throw new MWException( 'Invalid brace node passed to ' . __METHOD__ );
247  }
248  if ( !isset( $bits['index'] ) ) {
249  $bits['index'] = '';
250  }
251  return $bits;
252  }
253 
261  public function splitExt() {
262  return self::splitRawExt( $this->rawChildren );
263  }
264 
270  public static function splitRawExt( array $children ) {
271  $bits = [];
272  foreach ( $children as $i => $child ) {
273  if ( !is_array( $child ) ) {
274  continue;
275  }
276  switch ( $child[self::NAME] ) {
277  case 'name':
278  $bits['name'] = new self( $children, $i );
279  break;
280  case 'attr':
281  $bits['attr'] = new self( $children, $i );
282  break;
283  case 'inner':
284  $bits['inner'] = new self( $children, $i );
285  break;
286  case 'close':
287  $bits['close'] = new self( $children, $i );
288  break;
289  }
290  }
291  if ( !isset( $bits['name'] ) ) {
292  throw new MWException( 'Invalid ext node passed to ' . __METHOD__ );
293  }
294  return $bits;
295  }
296 
303  public function splitHeading() {
304  if ( $this->name !== 'h' ) {
305  throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
306  }
307  return self::splitRawHeading( $this->rawChildren );
308  }
309 
315  public static function splitRawHeading( array $children ) {
316  $bits = [];
317  foreach ( $children as $i => $child ) {
318  if ( !is_array( $child ) ) {
319  continue;
320  }
321  if ( $child[self::NAME] === '@i' ) {
322  $bits['i'] = $child[self::CHILDREN][0];
323  } elseif ( $child[self::NAME] === '@level' ) {
324  $bits['level'] = $child[self::CHILDREN][0];
325  }
326  }
327  if ( !isset( $bits['i'] ) ) {
328  throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
329  }
330  return $bits;
331  }
332 
339  public function splitTemplate() {
340  return self::splitRawTemplate( $this->rawChildren );
341  }
342 
349  public static function splitRawTemplate( array $children ) {
350  $parts = [];
351  $bits = [ 'lineStart' => '' ];
352  foreach ( $children as $i => $child ) {
353  if ( !is_array( $child ) ) {
354  continue;
355  }
356  switch ( $child[self::NAME] ) {
357  case 'title':
358  $bits['title'] = new self( $children, $i );
359  break;
360  case 'part':
361  $parts[] = new self( $children, $i );
362  break;
363  case '@lineStart':
364  $bits['lineStart'] = '1';
365  break;
366  }
367  }
368  if ( !isset( $bits['title'] ) ) {
369  throw new MWException( 'Invalid node passed to ' . __METHOD__ );
370  }
371  $bits['parts'] = new PPNode_Hash_Array( $parts );
372  return $bits;
373  }
374 }
PPNode_Hash_Tree\$name
string $name
Definition: PPNode_Hash_Tree.php:29
PPNode_Hash_Tree\getLength
getLength()
Definition: PPNode_Hash_Tree.php:190
PPNode_Hash_Tree\getChildrenOfType
getChildrenOfType( $name)
Get an array of the children with a given node name.
Definition: PPNode_Hash_Tree.php:169
PPNode_Hash_Tree\item
item( $i)
Definition: PPNode_Hash_Tree.php:198
PPNode_Hash_Tree\getFirstChild
getFirstChild()
Get the first child, or false if there is none.
Definition: PPNode_Hash_Tree.php:144
PPNode_Hash_Tree\splitRawExt
static splitRawExt(array $children)
Like splitExt() but for a raw child array.
Definition: PPNode_Hash_Tree.php:270
PPNode_Hash_Tree\splitHeading
splitHeading()
Split an "<h>" node.
Definition: PPNode_Hash_Tree.php:303
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:261
PPNode_Hash_Tree\splitRawArg
static splitRawArg(array $children)
Like splitArg() but for a raw child array.
Definition: PPNode_Hash_Tree.php:227
PPNode_Hash_Tree\splitRawHeading
static splitRawHeading(array $children)
Like splitHeading() but for a raw child array.
Definition: PPNode_Hash_Tree.php:315
PPNode_Hash_Tree\$store
array $store
The store array for the siblings of this node, including this node itself.
Definition: PPNode_Hash_Tree.php:43
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:61
PPNode_Hash_Tree\getNextSibling
getNextSibling()
Get the next sibling, or false if there is none.
Definition: PPNode_Hash_Tree.php:159
PPNode_Hash_Tree\splitTemplate
splitTemplate()
Split a "<template>" or "<tplarg>" node.
Definition: PPNode_Hash_Tree.php:339
PPNode_Hash_Tree\__toString
__toString()
Convert a node to XML, for debugging.
Definition: PPNode_Hash_Tree.php:109
PPNode
There are three types of nodes:
Definition: PPNode.php:35
PPNode_Hash_Tree\$index
int $index
The index into $this->store which contains the descriptor of this node.
Definition: PPNode_Hash_Tree.php:49
PPNode_Hash_Tree\splitRawTemplate
static splitRawTemplate(array $children)
Like splitTemplate() but for a raw child array.
Definition: PPNode_Hash_Tree.php:349
PPNode_Hash_Tree\__construct
__construct(array $store, $index)
Construct an object using the data from $store[$index].
Definition: PPNode_Hash_Tree.php:70
PPNode_Hash_Array
Definition: PPNode_Hash_Array.php:26
PPNode_Hash_Tree\getRawChildren
getRawChildren()
Get the raw child array.
Definition: PPNode_Hash_Tree.php:183
PPNode_Hash_Tree\getName
getName()
Definition: PPNode_Hash_Tree.php:205
PPNode_Hash_Tree\getChildren
getChildren()
Definition: PPNode_Hash_Tree.php:129
PPNode_Hash_Attr
Definition: PPNode_Hash_Attr.php:26
PPNode_Hash_Tree
Definition: PPNode_Hash_Tree.php:26
PPNode_Hash_Tree\$rawChildren
array $rawChildren
The store array for children of this node.
Definition: PPNode_Hash_Tree.php:37
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:85
PPNode_Hash_Tree\NAME
const NAME
The offset of the name within descriptors, used in some places for readability.
Definition: PPNode_Hash_Tree.php:55
PPNode_Hash_Tree\splitArg
splitArg()
Split a "<part>" node into an associative array containing:
Definition: PPNode_Hash_Tree.php:218