Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4146285
PPNode_Hash_Tree.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
PPNode_Hash_Tree.php
View Options
<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Parser
*/
namespace
MediaWiki\Parser
;
use
BadMethodCallException
;
use
InvalidArgumentException
;
use
Stringable
;
/**
* @ingroup Parser
*/
// phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
class
PPNode_Hash_Tree
implements
Stringable
,
PPNode
{
/** @var string */
public
$name
;
/**
* The store array for children of this node. It is "raw" in the sense that
* nodes are two-element arrays ("descriptors") rather than PPNode_Hash_*
* objects.
* @var array
*/
private
$rawChildren
;
/**
* The store array for the siblings of this node, including this node itself.
* @var array
*/
private
$store
;
/**
* The index into $this->store which contains the descriptor of this node.
* @var int
*/
private
$index
;
/**
* The offset of the name within descriptors, used in some places for
* readability.
*/
public
const
NAME
=
0
;
/**
* The offset of the child list within descriptors, used in some places for
* readability.
*/
public
const
CHILDREN
=
1
;
/**
* Construct an object using the data from $store[$index]. The rest of the
* store array can be accessed via getNextSibling().
*
* @param array $store
* @param int $index
*/
public
function
__construct
(
array
$store
,
$index
)
{
$this
->
store
=
$store
;
$this
->
index
=
$index
;
[
$this
->
name
,
$this
->
rawChildren
]
=
$this
->
store
[
$index
];
}
/**
* Construct an appropriate PPNode_Hash_* object with a class that depends
* on what is at the relevant store index.
*
* @param array $store
* @param int $index
* @return PPNode_Hash_Tree|PPNode_Hash_Attr|PPNode_Hash_Text|false
*/
public
static
function
factory
(
array
$store
,
$index
)
{
if
(
!
isset
(
$store
[
$index
]
)
)
{
return
false
;
}
$descriptor
=
$store
[
$index
];
if
(
is_string
(
$descriptor
)
)
{
$class
=
PPNode_Hash_Text
::
class
;
}
elseif
(
is_array
(
$descriptor
)
)
{
if
(
$descriptor
[
self
::
NAME
][
0
]
===
'@'
)
{
$class
=
PPNode_Hash_Attr
::
class
;
}
else
{
$class
=
self
::
class
;
}
}
else
{
throw
new
InvalidArgumentException
(
__METHOD__
.
': invalid node descriptor'
);
}
return
new
$class
(
$store
,
$index
);
}
/**
* Convert a node to XML, for debugging
* @return string
*/
public
function
__toString
()
{
$inner
=
''
;
$attribs
=
''
;
for
(
$node
=
$this
->
getFirstChild
();
$node
;
$node
=
$node
->
getNextSibling
()
)
{
if
(
$node
instanceof
PPNode_Hash_Attr
)
{
$attribs
.=
' '
.
$node
->
name
.
'="'
.
htmlspecialchars
(
$node
->
value
,
ENT_COMPAT
)
.
'"'
;
}
else
{
$inner
.=
$node
->
__toString
();
}
}
if
(
$inner
===
''
)
{
return
"<{$this->name}$attribs/>"
;
}
else
{
return
"<{$this->name}$attribs>$inner</{$this->name}>"
;
}
}
/**
* @return PPNode_Hash_Array
*/
public
function
getChildren
()
{
$children
=
[];
foreach
(
$this
->
rawChildren
as
$i
=>
$child
)
{
$children
[]
=
self
::
factory
(
$this
->
rawChildren
,
$i
);
}
return
new
PPNode_Hash_Array
(
$children
);
}
/**
* Get the first child, or false if there is none. Note that this will
* return a temporary proxy object: different instances will be returned
* if this is called more than once on the same node.
*
* @return PPNode_Hash_Tree|PPNode_Hash_Attr|PPNode_Hash_Text|false
*/
public
function
getFirstChild
()
{
if
(
!
isset
(
$this
->
rawChildren
[
0
]
)
)
{
return
false
;
}
else
{
return
self
::
factory
(
$this
->
rawChildren
,
0
);
}
}
/**
* Get the next sibling, or false if there is none. Note that this will
* return a temporary proxy object: different instances will be returned
* if this is called more than once on the same node.
*
* @return PPNode_Hash_Tree|PPNode_Hash_Attr|PPNode_Hash_Text|false
*/
public
function
getNextSibling
()
{
return
self
::
factory
(
$this
->
store
,
$this
->
index
+
1
);
}
/**
* Get an array of the children with a given node name
*
* @param string $name
* @return PPNode_Hash_Array
*/
public
function
getChildrenOfType
(
$name
)
{
$children
=
[];
foreach
(
$this
->
rawChildren
as
$i
=>
$child
)
{
if
(
is_array
(
$child
)
&&
$child
[
self
::
NAME
]
===
$name
)
{
$children
[]
=
self
::
factory
(
$this
->
rawChildren
,
$i
);
}
}
return
new
PPNode_Hash_Array
(
$children
);
}
/**
* Get the raw child array. For internal use.
* @return array
*/
public
function
getRawChildren
()
{
return
$this
->
rawChildren
;
}
/**
* @return bool
*/
public
function
getLength
()
{
return
false
;
}
/**
* @param int $i
* @return bool
*/
public
function
item
(
$i
)
{
return
false
;
}
/**
* @return string
*/
public
function
getName
()
{
return
$this
->
name
;
}
/**
* Split a "<part>" node into an associative array containing:
* - name PPNode name
* - index String index
* - value PPNode value
*
* @return array
*/
public
function
splitArg
()
{
return
self
::
splitRawArg
(
$this
->
rawChildren
);
}
/**
* Like splitArg() but for a raw child array. For internal use only.
* @param array $children
* @return array
*/
public
static
function
splitRawArg
(
array
$children
)
{
$bits
=
[];
foreach
(
$children
as
$i
=>
$child
)
{
if
(
!
is_array
(
$child
)
)
{
continue
;
}
if
(
$child
[
self
::
NAME
]
===
'name'
)
{
$bits
[
'name'
]
=
new
self
(
$children
,
$i
);
if
(
isset
(
$child
[
self
::
CHILDREN
][
0
][
self
::
NAME
]
)
&&
$child
[
self
::
CHILDREN
][
0
][
self
::
NAME
]
===
'@index'
)
{
$bits
[
'index'
]
=
$child
[
self
::
CHILDREN
][
0
][
self
::
CHILDREN
][
0
];
}
}
elseif
(
$child
[
self
::
NAME
]
===
'value'
)
{
$bits
[
'value'
]
=
new
self
(
$children
,
$i
);
}
}
if
(
!
isset
(
$bits
[
'name'
]
)
)
{
throw
new
InvalidArgumentException
(
'Invalid brace node passed to '
.
__METHOD__
);
}
if
(
!
isset
(
$bits
[
'index'
]
)
)
{
$bits
[
'index'
]
=
''
;
}
return
$bits
;
}
/**
* Split an "<ext>" node into an associative array containing name, attr, inner and close
* All values in the resulting array are PPNodes. Inner and close are optional.
*
* @return array
*/
public
function
splitExt
()
{
return
self
::
splitRawExt
(
$this
->
rawChildren
);
}
/**
* Like splitExt() but for a raw child array. For internal use only.
* @param array $children
* @return array
*/
public
static
function
splitRawExt
(
array
$children
)
{
$bits
=
[];
foreach
(
$children
as
$i
=>
$child
)
{
if
(
!
is_array
(
$child
)
)
{
continue
;
}
switch
(
$child
[
self
::
NAME
]
)
{
case
'name'
:
$bits
[
'name'
]
=
new
self
(
$children
,
$i
);
break
;
case
'attr'
:
$bits
[
'attr'
]
=
new
self
(
$children
,
$i
);
break
;
case
'inner'
:
$bits
[
'inner'
]
=
new
self
(
$children
,
$i
);
break
;
case
'close'
:
$bits
[
'close'
]
=
new
self
(
$children
,
$i
);
break
;
}
}
if
(
!
isset
(
$bits
[
'name'
]
)
)
{
throw
new
InvalidArgumentException
(
'Invalid ext node passed to '
.
__METHOD__
);
}
return
$bits
;
}
/**
* Split an "<h>" node
*
* @return array
*/
public
function
splitHeading
()
{
if
(
$this
->
name
!==
'h'
)
{
throw
new
BadMethodCallException
(
'Invalid h node passed to '
.
__METHOD__
);
}
return
self
::
splitRawHeading
(
$this
->
rawChildren
);
}
/**
* Like splitHeading() but for a raw child array. For internal use only.
* @param array $children
* @return array
*/
public
static
function
splitRawHeading
(
array
$children
)
{
$bits
=
[];
foreach
(
$children
as
$child
)
{
if
(
!
is_array
(
$child
)
)
{
continue
;
}
if
(
$child
[
self
::
NAME
]
===
'@i'
)
{
$bits
[
'i'
]
=
$child
[
self
::
CHILDREN
][
0
];
}
elseif
(
$child
[
self
::
NAME
]
===
'@level'
)
{
$bits
[
'level'
]
=
$child
[
self
::
CHILDREN
][
0
];
}
}
if
(
!
isset
(
$bits
[
'i'
]
)
)
{
throw
new
InvalidArgumentException
(
'Invalid h node passed to '
.
__METHOD__
);
}
return
$bits
;
}
/**
* Split a "<template>" or "<tplarg>" node
*
* @return array
*/
public
function
splitTemplate
()
{
return
self
::
splitRawTemplate
(
$this
->
rawChildren
);
}
/**
* Like splitTemplate() but for a raw child array. For internal use only.
* @param array $children
* @return array
* @suppress SecurityCheck-XSS
*/
public
static
function
splitRawTemplate
(
array
$children
)
{
$parts
=
[];
$bits
=
[
'lineStart'
=>
''
];
foreach
(
$children
as
$i
=>
$child
)
{
if
(
!
is_array
(
$child
)
)
{
continue
;
}
switch
(
$child
[
self
::
NAME
]
)
{
case
'title'
:
$bits
[
'title'
]
=
new
self
(
$children
,
$i
);
break
;
case
'part'
:
$parts
[]
=
new
self
(
$children
,
$i
);
break
;
case
'@lineStart'
:
$bits
[
'lineStart'
]
=
'1'
;
break
;
}
}
if
(
!
isset
(
$bits
[
'title'
]
)
)
{
throw
new
InvalidArgumentException
(
'Invalid node passed to '
.
__METHOD__
);
}
$bits
[
'parts'
]
=
new
PPNode_Hash_Array
(
$parts
);
return
$bits
;
}
}
/** @deprecated class alias since 1.43 */
class_alias
(
PPNode_Hash_Tree
::
class
,
'PPNode_Hash_Tree'
);
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Aug 19 2026, 17:57 (5 w, 5 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
6c/4e/7cc94aa87fcb56012f4e12b01f9f
Default Alt Text
PPNode_Hash_Tree.php (9 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment