Vendor lock

This commit is contained in:
2023-06-16 02:08:47 +00:00
parent 7933e70e90
commit 3351b92dd6
4099 changed files with 345789 additions and 0 deletions

View File

@ -0,0 +1,63 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use ArrayObject;
use Kint\Object\BasicObject;
class ArrayObjectPlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_BEGIN;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof ArrayObject) {
return;
}
$flags = $var->getFlags();
if (ArrayObject::STD_PROP_LIST === $flags) {
return;
}
$var->setFlags(ArrayObject::STD_PROP_LIST);
$o = $this->parser->parse($var, $o);
$var->setFlags($flags);
$this->parser->haltParse();
}
}

View File

@ -0,0 +1,95 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class Base64Plugin extends Plugin
{
/**
* The minimum length before a string will be considered for base64 decoding.
*
* @var int
*/
public static $min_length_hard = 16;
/**
* The minimum length before the base64 decoding will take precedence.
*
* @var int
*/
public static $min_length_soft = 50;
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\strlen($var) < self::$min_length_hard || \strlen($var) % 4) {
return;
}
if (\preg_match('/^[A-Fa-f0-9]+$/', $var)) {
return;
}
if (!\preg_match('/^[A-Za-z0-9+\\/=]+$/', $var)) {
return;
}
/** @var false|string */
$data = \base64_decode($var, true);
if (false === $data) {
return;
}
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = 'base64_decode('.$o->name.')';
if ($o->access_path) {
$base_obj->access_path = 'base64_decode('.$o->access_path.')';
}
$r = new Representation('Base64');
$r->contents = $this->parser->parse($data, $base_obj);
if (\strlen($var) > self::$min_length_soft) {
$o->addRepresentation($r, 0);
} else {
$o->addRepresentation($r);
}
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
class BinaryPlugin extends Plugin
{
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o instanceof BlobObject || !\in_array($o->encoding, array('ASCII', 'UTF-8'), true)) {
$o->value->hints[] = 'binary';
}
}
}

View File

@ -0,0 +1,143 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
class BlacklistPlugin extends Plugin
{
/**
* List of classes and interfaces to blacklist.
*
* @var array
*/
public static $blacklist = array();
/**
* List of classes and interfaces to blacklist except when dumped directly.
*
* @var array
*/
public static $shallow_blacklist = array();
/**
* Maximum size of arrays before blacklisting.
*
* @var int
*/
public static $array_limit = 10000;
/**
* Maximum size of arrays before blacklisting except when dumped directly.
*
* @var int
*/
public static $shallow_array_limit = 1000;
public function getTypes()
{
return array('object', 'array');
}
public function getTriggers()
{
return Parser::TRIGGER_BEGIN;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\is_object($var)) {
return $this->parseObject($var, $o);
}
if (\is_array($var)) {
return $this->parseArray($var, $o);
}
}
protected function parseObject(&$var, BasicObject &$o)
{
foreach (self::$blacklist as $class) {
if ($var instanceof $class) {
return $this->blacklistObject($var, $o);
}
}
if ($o->depth <= 0) {
return;
}
foreach (self::$shallow_blacklist as $class) {
if ($var instanceof $class) {
return $this->blacklistObject($var, $o);
}
}
}
protected function blacklistObject(&$var, BasicObject &$o)
{
$object = new InstanceObject();
$object->transplant($o);
$object->classname = \get_class($var);
$object->hash = \spl_object_hash($var);
$object->clearRepresentations();
$object->value = null;
$object->size = null;
$object->hints[] = 'blacklist';
$o = $object;
$this->parser->haltParse();
}
protected function parseArray(array &$var, BasicObject &$o)
{
if (\count($var) > self::$array_limit) {
return $this->blacklistArray($var, $o);
}
if ($o->depth <= 0) {
return;
}
if (\count($var) > self::$shallow_array_limit) {
return $this->blacklistArray($var, $o);
}
}
protected function blacklistArray(array &$var, BasicObject &$o)
{
$object = new BasicObject();
$object->transplant($o);
$object->value = null;
$object->size = \count($var);
$object->hints[] = 'blacklist';
$o = $object;
$this->parser->haltParse();
}
}

View File

@ -0,0 +1,113 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
use Kint\Object\MethodObject;
use Kint\Object\Representation\Representation;
use ReflectionClass;
class ClassMethodsPlugin extends Plugin
{
private static $cache = array();
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$class = \get_class($var);
// assuming class definition will not change inside one request
if (!isset(self::$cache[$class])) {
$methods = array();
$reflection = new ReflectionClass($class);
foreach ($reflection->getMethods() as $method) {
$methods[] = new MethodObject($method);
}
\usort($methods, array('Kint\\Parser\\ClassMethodsPlugin', 'sort'));
self::$cache[$class] = $methods;
}
if (!empty(self::$cache[$class])) {
$rep = new Representation('Available methods', 'methods');
// Can't cache access paths
foreach (self::$cache[$class] as $m) {
$method = clone $m;
$method->depth = $o->depth + 1;
if (!$this->parser->childHasPath($o, $method)) {
$method->access_path = null;
} else {
$method->setAccessPathFrom($o);
}
if ($method->owner_class !== $class && $ds = $method->getRepresentation('docstring')) {
$ds = clone $ds;
$ds->class = $method->owner_class;
$method->replaceRepresentation($ds);
}
$rep->contents[] = $method;
}
$o->addRepresentation($rep);
}
}
private static function sort(MethodObject $a, MethodObject $b)
{
$sort = ((int) $a->static) - ((int) $b->static);
if ($sort) {
return $sort;
}
$sort = BasicObject::sortByAccess($a, $b);
if ($sort) {
return $sort;
}
$sort = InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class);
if ($sort) {
return $sort;
}
return $a->startline - $b->startline;
}
}

View File

@ -0,0 +1,122 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
use Kint\Object\Representation\Representation;
use ReflectionClass;
use ReflectionProperty;
class ClassStaticsPlugin extends Plugin
{
private static $cache = array();
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$class = \get_class($var);
$reflection = new ReflectionClass($class);
// Constants
// TODO: PHP 7.1 allows private consts but reflection doesn't have a way to check them yet
if (!isset(self::$cache[$class])) {
$consts = array();
foreach ($reflection->getConstants() as $name => $val) {
$const = BasicObject::blank($name, '\\'.$class.'::'.$name);
$const->const = true;
$const->depth = $o->depth + 1;
$const->owner_class = $class;
$const->operator = BasicObject::OPERATOR_STATIC;
$const = $this->parser->parse($val, $const);
$consts[] = $const;
}
self::$cache[$class] = $consts;
}
$statics = new Representation('Static class properties', 'statics');
$statics->contents = self::$cache[$class];
foreach ($reflection->getProperties(ReflectionProperty::IS_STATIC) as $static) {
$prop = new BasicObject();
$prop->name = '$'.$static->getName();
$prop->depth = $o->depth + 1;
$prop->static = true;
$prop->operator = BasicObject::OPERATOR_STATIC;
$prop->owner_class = $static->getDeclaringClass()->name;
$prop->access = BasicObject::ACCESS_PUBLIC;
if ($static->isProtected()) {
$prop->access = BasicObject::ACCESS_PROTECTED;
} elseif ($static->isPrivate()) {
$prop->access = BasicObject::ACCESS_PRIVATE;
}
if ($this->parser->childHasPath($o, $prop)) {
$prop->access_path = '\\'.$prop->owner_class.'::'.$prop->name;
}
$static->setAccessible(true);
$static = $static->getValue();
$statics->contents[] = $this->parser->parse($static, $prop);
}
if (empty($statics->contents)) {
return;
}
\usort($statics->contents, array('Kint\\Parser\\ClassStaticsPlugin', 'sort'));
$o->addRepresentation($statics);
}
private static function sort(BasicObject $a, BasicObject $b)
{
$sort = ((int) $a->const) - ((int) $b->const);
if ($sort) {
return $sort;
}
$sort = BasicObject::sortByAccess($a, $b);
if ($sort) {
return $sort;
}
return InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class);
}
}

View File

@ -0,0 +1,94 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Closure;
use Kint\Object\BasicObject;
use Kint\Object\ClosureObject;
use Kint\Object\ParameterObject;
use Kint\Object\Representation\Representation;
use ReflectionFunction;
class ClosurePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Closure) {
return;
}
$object = new ClosureObject();
$object->transplant($o);
$o = $object;
$object->removeRepresentation('properties');
$closure = new ReflectionFunction($var);
$o->filename = $closure->getFileName();
$o->startline = $closure->getStartLine();
foreach ($closure->getParameters() as $param) {
$o->parameters[] = new ParameterObject($param);
}
$p = new Representation('Parameters');
$p->contents = &$o->parameters;
$o->addRepresentation($p, 0);
$statics = array();
if (\method_exists($closure, 'getClosureThis') && $v = $closure->getClosureThis()) {
$statics = array('this' => $v);
}
if (\count($statics = $statics + $closure->getStaticVariables())) {
$statics_parsed = array();
foreach ($statics as $name => &$static) {
$obj = BasicObject::blank('$'.$name);
$obj->depth = $o->depth + 1;
$statics_parsed[$name] = $this->parser->parse($static, $obj);
if (null === $statics_parsed[$name]->value) {
$statics_parsed[$name]->access_path = null;
}
}
$r = new Representation('Uses');
$r->contents = $statics_parsed;
$o->addRepresentation($r, 0);
}
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\ColorRepresentation;
class ColorPlugin extends Plugin
{
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\strlen($var) > 32) {
return;
}
$trimmed = \strtolower(\trim($var));
if (!isset(ColorRepresentation::$color_map[$trimmed]) && !\preg_match('/^(?:(?:rgb|hsl)[^\\)]{6,}\\)|#[0-9a-fA-F]{3,8})$/', $trimmed)) {
return;
}
$rep = new ColorRepresentation($var);
if ($rep->variant) {
$o->removeRepresentation($o->value);
$o->addRepresentation($rep, 0);
$o->hints[] = 'color';
}
}
}

View File

@ -0,0 +1,328 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DOMNamedNodeMap;
use DOMNode;
use DOMNodeList;
use Kint\Object\BasicObject;
use Kint\Object\InstanceObject;
use Kint\Object\Representation\Representation;
/**
* The DOMDocument parser plugin is particularly useful as it is both the only
* way to see inside the DOMNode without print_r, and the only way to see mixed
* text and node inside XML (SimpleXMLElement will strip out the text).
*/
class DOMDocumentPlugin extends Plugin
{
/**
* List of properties to skip parsing.
*
* The properties of a DOMNode can do a *lot* of damage to debuggers. The
* DOMNode contains not one, not two, not three, not four, not 5, not 6,
* not 7 but 8 different ways to recurse into itself:
* * firstChild
* * lastChild
* * previousSibling
* * nextSibling
* * ownerDocument
* * parentNode
* * childNodes
* * attributes
*
* All of this combined: the tiny SVGs used as the caret in Kint are already
* enough to make parsing and rendering take over a second, and send memory
* usage over 128 megs. So we blacklist every field we don't strictly need
* and hope that that's good enough.
*
* In retrospect - this is probably why print_r does the same
*
* @var array
*/
public static $blacklist = array(
'parentNode' => 'DOMNode',
'firstChild' => 'DOMNode',
'lastChild' => 'DOMNode',
'previousSibling' => 'DOMNode',
'nextSibling' => 'DOMNode',
'ownerDocument' => 'DOMDocument',
);
/**
* Show all properties and methods.
*
* @var bool
*/
public static $verbose = false;
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o instanceof InstanceObject) {
return;
}
if ($var instanceof DOMNamedNodeMap || $var instanceof DOMNodeList) {
return $this->parseList($var, $o, $trigger);
}
if ($var instanceof DOMNode) {
return $this->parseNode($var, $o);
}
}
protected function parseList(&$var, InstanceObject &$o, $trigger)
{
// Recursion should never happen, should always be stopped at the parent
// DOMNode. Depth limit on the other hand we're going to skip since
// that would show an empty iterator and rather useless. Let the depth
// limit hit the children (DOMNodeList only has DOMNode as children)
if ($trigger & Parser::TRIGGER_RECURSION) {
return;
}
$o->size = $var->length;
if (0 === $o->size) {
$o->replaceRepresentation(new Representation('Iterator'));
$o->size = null;
return;
}
// Depth limit
// Make empty iterator representation since we need it in DOMNode to point out depth limits
if ($this->parser->getDepthLimit() && $o->depth + 1 >= $this->parser->getDepthLimit()) {
$b = new BasicObject();
$b->name = $o->classname.' Iterator Contents';
$b->access_path = 'iterator_to_array('.$o->access_path.')';
$b->depth = $o->depth + 1;
$b->hints[] = 'depth_limit';
$r = new Representation('Iterator');
$r->contents = array($b);
$o->replaceRepresentation($r, 0);
return;
}
$data = \iterator_to_array($var);
$r = new Representation('Iterator');
$o->replaceRepresentation($r, 0);
foreach ($data as $key => $item) {
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $item->nodeName;
if ($o->access_path) {
if ($var instanceof DOMNamedNodeMap) {
$base_obj->access_path = $o->access_path.'->getNamedItem('.\var_export($key, true).')';
} elseif ($var instanceof DOMNodeList) {
$base_obj->access_path = $o->access_path.'->item('.\var_export($key, true).')';
} else {
$base_obj->access_path = 'iterator_to_array('.$o->access_path.')';
}
}
$r->contents[] = $this->parser->parse($item, $base_obj);
}
}
protected function parseNode(&$var, InstanceObject &$o)
{
// Fill the properties
// They can't be enumerated through reflection or casting,
// so we have to trust the docs and try them one at a time
$known_properties = array(
'nodeValue',
'childNodes',
'attributes',
);
if (self::$verbose) {
$known_properties = array(
'nodeName',
'nodeValue',
'nodeType',
'parentNode',
'childNodes',
'firstChild',
'lastChild',
'previousSibling',
'nextSibling',
'attributes',
'ownerDocument',
'namespaceURI',
'prefix',
'localName',
'baseURI',
'textContent',
);
}
$childNodes = array();
$attributes = array();
$rep = $o->value;
foreach ($known_properties as $prop) {
$prop_obj = $this->parseProperty($o, $prop, $var);
$rep->contents[] = $prop_obj;
if ('childNodes' === $prop) {
$childNodes = $prop_obj->getRepresentation('iterator');
} elseif ('attributes' === $prop) {
$attributes = $prop_obj->getRepresentation('iterator');
}
}
if (!self::$verbose) {
$o->removeRepresentation('methods');
$o->removeRepresentation('properties');
}
// Attributes and comments and text nodes don't
// need children or attributes of their own
if (\in_array($o->classname, array('DOMAttr', 'DOMText', 'DOMComment'), true)) {
return;
}
// Set the attributes
if ($attributes) {
$a = new Representation('Attributes');
foreach ($attributes->contents as $attribute) {
$a->contents[] = self::textualNodeToString($attribute);
}
$o->addRepresentation($a, 0);
}
// Set the children
if ($childNodes) {
$c = new Representation('Children');
if (1 === \count($childNodes->contents) && ($node = \reset($childNodes->contents)) && \in_array('depth_limit', $node->hints, true)) {
$n = new InstanceObject();
$n->transplant($node);
$n->name = 'childNodes';
$n->classname = 'DOMNodeList';
$c->contents = array($n);
} else {
foreach ($childNodes->contents as $index => $node) {
// Shortcircuit text nodes to plain strings
if ('DOMText' === $node->classname || 'DOMComment' === $node->classname) {
$node = self::textualNodeToString($node);
// And remove them if they're empty
if (\ctype_space($node->value->contents) || '' === $node->value->contents) {
continue;
}
}
$c->contents[] = $node;
}
}
$o->addRepresentation($c, 0);
}
if (isset($c) && \count($c->contents)) {
$o->size = \count($c->contents);
}
if (!$o->size) {
$o->size = null;
}
}
protected function parseProperty(InstanceObject $o, $prop, &$var)
{
// Duplicating (And slightly optimizing) the Parser::parseObject() code here
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->owner_class = $o->classname;
$base_obj->name = $prop;
$base_obj->operator = BasicObject::OPERATOR_OBJECT;
$base_obj->access = BasicObject::ACCESS_PUBLIC;
if (null !== $o->access_path) {
$base_obj->access_path = $o->access_path;
if (\preg_match('/^[A-Za-z0-9_]+$/', $base_obj->name)) {
$base_obj->access_path .= '->'.$base_obj->name;
} else {
$base_obj->access_path .= '->{'.\var_export($base_obj->name, true).'}';
}
}
if (!isset($var->{$prop})) {
$base_obj->type = 'null';
} elseif (isset(self::$blacklist[$prop])) {
$b = new InstanceObject();
$b->transplant($base_obj);
$base_obj = $b;
$base_obj->hints[] = 'blacklist';
$base_obj->classname = self::$blacklist[$prop];
} elseif ('attributes' === $prop) {
$base_obj = $this->parser->parseDeep($var->{$prop}, $base_obj);
} else {
$base_obj = $this->parser->parse($var->{$prop}, $base_obj);
}
return $base_obj;
}
protected static function textualNodeToString(InstanceObject $o)
{
if (empty($o->value) || empty($o->value->contents) || empty($o->classname)) {
return;
}
if (!\in_array($o->classname, array('DOMText', 'DOMAttr', 'DOMComment'), true)) {
return;
}
foreach ($o->value->contents as $property) {
if ('nodeValue' === $property->name) {
$ret = clone $property;
$ret->name = $o->name;
return $ret;
}
}
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DateTime;
use Kint\Object\BasicObject;
use Kint\Object\DateTimeObject;
class DateTimePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof DateTime) {
return;
}
$object = new DateTimeObject($var);
$object->transplant($o);
$o = $object;
}
}

View File

@ -0,0 +1,72 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\SplFileInfoRepresentation;
use SplFileInfo;
class FsPathPlugin extends Plugin
{
public static $blacklist = array('/', '.');
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\strlen($var) > 2048) {
return;
}
if (!\preg_match('/[\\/\\'.DIRECTORY_SEPARATOR.']/', $var)) {
return;
}
if (\preg_match('/[?<>"*|]/', $var)) {
return;
}
if (!@\file_exists($var)) {
return;
}
if (\in_array($var, self::$blacklist, true)) {
return;
}
$r = new SplFileInfoRepresentation(new SplFileInfo($var));
$r->hints[] = 'fspath';
$o->addRepresentation($r, 0);
}
}

View File

@ -0,0 +1,110 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
use Traversable;
class IteratorPlugin extends Plugin
{
/**
* List of classes and interfaces to blacklist.
*
* Certain classes (Such as PDOStatement) irreversibly lose information
* when traversed. Others are just huge. Either way, put them in here
* and you won't have to worry about them being parsed.
*
* @var array
*/
public static $blacklist = array(
'DOMNamedNodeMap',
'DOMNodeList',
'mysqli_result',
'PDOStatement',
'SplFileObject',
);
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Traversable) {
return;
}
foreach (self::$blacklist as $class) {
if ($var instanceof $class) {
$b = new BasicObject();
$b->name = $class.' Iterator Contents';
$b->access_path = 'iterator_to_array('.$o->access_path.', true)';
$b->depth = $o->depth + 1;
$b->hints[] = 'blacklist';
$r = new Representation('Iterator');
$r->contents = array($b);
$o->addRepresentation($r);
return;
}
}
/** @var array|false */
$data = \iterator_to_array($var);
if (false === $data) {
return;
}
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = 'iterator_to_array('.$o->access_path.')';
}
$r = new Representation('Iterator');
$r->contents = $this->parser->parse($data, $base_obj);
$r->contents = $r->contents->value->contents;
$primary = $o->getRepresentations();
$primary = \reset($primary);
if ($primary && $primary === $o->value && $primary->contents === array()) {
$o->addRepresentation($r, 0);
} else {
$o->addRepresentation($r);
}
}
}

View File

@ -0,0 +1,73 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class JsonPlugin extends Plugin
{
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!isset($var[0]) || ('{' !== $var[0] && '[' !== $var[0])) {
return;
}
$json = \json_decode($var, true);
if (!$json) {
return;
}
$json = (array) $json;
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = 'json_decode('.$o->access_path.', true)';
}
$r = new Representation('Json');
$r->contents = $this->parser->parse($json, $base_obj);
if (!\in_array('depth_limit', $r->contents->hints, true)) {
$r->contents = $r->contents->value->contents;
}
$o->addRepresentation($r, 0);
}
}

View File

@ -0,0 +1,105 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\MicrotimeRepresentation;
class MicrotimePlugin extends Plugin
{
private static $last = null;
private static $start = null;
private static $times = 0;
private static $group = 0;
public function getTypes()
{
return array('string', 'double');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (0 !== $o->depth) {
return;
}
if (\is_string($var)) {
if ('microtime()' !== $o->name || !\preg_match('/^0\\.[0-9]{8} [0-9]{10}$/', $var)) {
return;
}
$usec = (int) \substr($var, 2, 6);
$sec = (int) \substr($var, 11, 10);
} else {
if ('microtime(...)' !== $o->name) {
return;
}
$sec = \floor($var);
$usec = $var - $sec;
$usec = \floor($usec * 1000000);
}
$time = $sec + ($usec / 1000000);
if (null !== self::$last) {
$last_time = self::$last[0] + (self::$last[1] / 1000000);
$lap = $time - $last_time;
++self::$times;
} else {
$lap = null;
self::$start = $time;
}
self::$last = array($sec, $usec);
if (null !== $lap) {
$total = $time - self::$start;
$r = new MicrotimeRepresentation($sec, $usec, self::$group, $lap, $total, self::$times);
} else {
$r = new MicrotimeRepresentation($sec, $usec, self::$group);
}
$r->contents = $var;
$r->implicit_label = true;
$o->removeRepresentation($o->value);
$o->addRepresentation($r);
$o->hints[] = 'microtime';
}
public static function clean()
{
self::$last = null;
self::$start = null;
self::$times = 0;
++self::$group;
}
}

View File

@ -0,0 +1,129 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Mysqli;
/**
* Adds support for Mysqli object parsing.
*
* Due to the way mysqli is implemented in PHP, this will cause
* warnings on certain Mysqli objects if screaming is enabled.
*/
class MysqliPlugin extends Plugin
{
// These 'properties' are actually globals
protected $always_readable = array(
'client_version' => true,
'connect_errno' => true,
'connect_error' => true,
);
// These are readable on empty mysqli objects, but not on failed connections
protected $empty_readable = array(
'client_info' => true,
'errno' => true,
'error' => true,
);
// These are only readable on connected mysqli objects
protected $connected_readable = array(
'affected_rows' => true,
'error_list' => true,
'field_count' => true,
'host_info' => true,
'info' => true,
'insert_id' => true,
'server_info' => true,
'server_version' => true,
'stat' => true,
'sqlstate' => true,
'protocol_version' => true,
'thread_id' => true,
'warning_count' => true,
);
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_COMPLETE;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Mysqli) {
return;
}
$connected = false;
$empty = false;
if (\is_string(@$var->sqlstate)) {
$connected = true;
} elseif (\is_string(@$var->client_info)) {
$empty = true;
}
foreach ($o->value->contents as $key => $obj) {
if (isset($this->connected_readable[$obj->name])) {
if (!$connected) {
continue;
}
} elseif (isset($this->empty_readable[$obj->name])) {
if (!$connected && !$empty) {
continue;
}
} elseif (!isset($this->always_readable[$obj->name])) {
continue;
}
if ('null' !== $obj->type) {
continue;
}
$param = $var->{$obj->name};
if (null === $param) {
continue;
}
$base = BasicObject::blank($obj->name, $obj->access_path);
$base->depth = $obj->depth;
$base->owner_class = $obj->owner_class;
$base->operator = $obj->operator;
$base->access = $obj->access;
$base->reference = $obj->reference;
$o->value->contents[$key] = $this->parser->parse($param, $base);
}
}
}

View File

@ -0,0 +1,604 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DomainException;
use Exception;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
use Kint\Object\InstanceObject;
use Kint\Object\Representation\Representation;
use Kint\Object\ResourceObject;
use ReflectionObject;
use stdClass;
class Parser
{
/**
* Plugin triggers.
*
* These are constants indicating trigger points for plugins
*
* BEGIN: Before normal parsing
* SUCCESS: After successful parsing
* RECURSION: After parsing cancelled by recursion
* DEPTH_LIMIT: After parsing cancelled by depth limit
* COMPLETE: SUCCESS | RECURSION | DEPTH_LIMIT
*
* While a plugin's getTriggers may return any of these
*/
const TRIGGER_NONE = 0;
const TRIGGER_BEGIN = 1;
const TRIGGER_SUCCESS = 2;
const TRIGGER_RECURSION = 4;
const TRIGGER_DEPTH_LIMIT = 8;
const TRIGGER_COMPLETE = 14;
protected $caller_class;
protected $depth_limit = false;
protected $marker;
protected $object_hashes = array();
protected $parse_break = false;
protected $plugins = array();
/**
* @param false|int $depth_limit Maximum depth to parse data
* @param null|string $caller Caller class name
*/
public function __construct($depth_limit = false, $caller = null)
{
$this->marker = \uniqid("kint\0", true);
$this->caller_class = $caller;
if ($depth_limit) {
$this->depth_limit = $depth_limit;
}
}
/**
* Set the caller class.
*
* @param null|string $caller Caller class name
*/
public function setCallerClass($caller = null)
{
$this->noRecurseCall();
$this->caller_class = $caller;
}
public function getCallerClass()
{
return $this->caller_class;
}
/**
* Set the depth limit.
*
* @param false|int $depth_limit Maximum depth to parse data
*/
public function setDepthLimit($depth_limit = false)
{
$this->noRecurseCall();
$this->depth_limit = $depth_limit;
}
public function getDepthLimit()
{
return $this->depth_limit;
}
/**
* Disables the depth limit and parses a variable.
*
* This should not be used unless you know what you're doing!
*
* @param mixed $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
public function parseDeep(&$var, BasicObject $o)
{
$depth_limit = $this->depth_limit;
$this->depth_limit = false;
$out = $this->parse($var, $o);
$this->depth_limit = $depth_limit;
return $out;
}
/**
* Parses a variable into a Kint object structure.
*
* @param mixed $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
public function parse(&$var, BasicObject $o)
{
$o->type = \strtolower(\gettype($var));
if (!$this->applyPlugins($var, $o, self::TRIGGER_BEGIN)) {
return $o;
}
switch ($o->type) {
case 'array':
return $this->parseArray($var, $o);
case 'boolean':
case 'double':
case 'integer':
case 'null':
return $this->parseGeneric($var, $o);
case 'object':
return $this->parseObject($var, $o);
case 'resource':
return $this->parseResource($var, $o);
case 'string':
return $this->parseString($var, $o);
default:
return $this->parseUnknown($var, $o);
}
}
public function addPlugin(Plugin $p)
{
if (!$types = $p->getTypes()) {
return false;
}
if (!$triggers = $p->getTriggers()) {
return false;
}
$p->setParser($this);
foreach ($types as $type) {
if (!isset($this->plugins[$type])) {
$this->plugins[$type] = array(
self::TRIGGER_BEGIN => array(),
self::TRIGGER_SUCCESS => array(),
self::TRIGGER_RECURSION => array(),
self::TRIGGER_DEPTH_LIMIT => array(),
);
}
foreach ($this->plugins[$type] as $trigger => &$pool) {
if ($triggers & $trigger) {
$pool[] = $p;
}
}
}
return true;
}
public function clearPlugins()
{
$this->plugins = array();
}
public function haltParse()
{
$this->parse_break = true;
}
public function childHasPath(InstanceObject $parent, BasicObject $child)
{
if ('object' === $parent->type && (null !== $parent->access_path || $child->static || $child->const)) {
if (BasicObject::ACCESS_PUBLIC === $child->access) {
return true;
}
if (BasicObject::ACCESS_PRIVATE === $child->access && $this->caller_class) {
if ($this->caller_class === $child->owner_class) {
return true;
}
} elseif (BasicObject::ACCESS_PROTECTED === $child->access && $this->caller_class) {
if ($this->caller_class === $child->owner_class) {
return true;
}
if (\is_subclass_of($this->caller_class, $child->owner_class)) {
return true;
}
if (\is_subclass_of($child->owner_class, $this->caller_class)) {
return true;
}
}
}
return false;
}
/**
* Returns an array without the recursion marker in it.
*
* DO NOT pass an array that has had it's marker removed back
* into the parser, it will result in an extra recursion
*
* @param array $array Array potentially containing a recursion marker
*
* @return array Array with recursion marker removed
*/
public function getCleanArray(array $array)
{
unset($array[$this->marker]);
return $array;
}
protected function noRecurseCall()
{
$bt = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
$caller_frame = array(
'function' => __FUNCTION__,
);
while (isset($bt[0]['object']) && $bt[0]['object'] === $this) {
$caller_frame = \array_shift($bt);
}
foreach ($bt as $frame) {
if (isset($frame['object']) && $frame['object'] === $this) {
throw new DomainException(__CLASS__.'::'.$caller_frame['function'].' cannot be called from inside a parse');
}
}
}
private function parseGeneric(&$var, BasicObject $o)
{
$rep = new Representation('Contents');
$rep->contents = $var;
$rep->implicit_label = true;
$o->addRepresentation($rep);
$o->value = $rep;
$this->applyPlugins($var, $o, self::TRIGGER_SUCCESS);
return $o;
}
/**
* Parses a string into a Kint BlobObject structure.
*
* @param string $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseString(&$var, BasicObject $o)
{
$string = new BlobObject();
$string->transplant($o);
$string->encoding = BlobObject::detectEncoding($var);
$string->size = BlobObject::strlen($var, $string->encoding);
$rep = new Representation('Contents');
$rep->contents = $var;
$rep->implicit_label = true;
$string->addRepresentation($rep);
$string->value = $rep;
$this->applyPlugins($var, $string, self::TRIGGER_SUCCESS);
return $string;
}
/**
* Parses an array into a Kint object structure.
*
* @param array $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseArray(array &$var, BasicObject $o)
{
$array = new BasicObject();
$array->transplant($o);
$array->size = \count($var);
if (isset($var[$this->marker])) {
--$array->size;
$array->hints[] = 'recursion';
$this->applyPlugins($var, $array, self::TRIGGER_RECURSION);
return $array;
}
$rep = new Representation('Contents');
$rep->implicit_label = true;
$array->addRepresentation($rep);
$array->value = $rep;
if (!$array->size) {
$this->applyPlugins($var, $array, self::TRIGGER_SUCCESS);
return $array;
}
if ($this->depth_limit && $o->depth >= $this->depth_limit) {
$array->hints[] = 'depth_limit';
$this->applyPlugins($var, $array, self::TRIGGER_DEPTH_LIMIT);
return $array;
}
$copy = \array_values($var);
// It's really really hard to access numeric string keys in arrays,
// and it's really really hard to access integer properties in
// objects, so we just use array_values and index by counter to get
// at it reliably for reference testing. This also affects access
// paths since it's pretty much impossible to access these things
// without complicated stuff you should never need to do.
$i = 0;
// Set the marker for recursion
$var[$this->marker] = $array->depth;
$refmarker = new stdClass();
foreach ($var as $key => &$val) {
if ($key === $this->marker) {
continue;
}
$child = new BasicObject();
$child->name = $key;
$child->depth = $array->depth + 1;
$child->access = BasicObject::ACCESS_NONE;
$child->operator = BasicObject::OPERATOR_ARRAY;
if (null !== $array->access_path) {
if (\is_string($key) && (string) (int) $key === $key) {
$child->access_path = 'array_values('.$array->access_path.')['.$i.']'; // @codeCoverageIgnore
} else {
$child->access_path = $array->access_path.'['.\var_export($key, true).']';
}
}
$stash = $val;
$copy[$i] = $refmarker;
if ($val === $refmarker) {
$child->reference = true;
$val = $stash;
}
$rep->contents[] = $this->parse($val, $child);
++$i;
}
$this->applyPlugins($var, $array, self::TRIGGER_SUCCESS);
unset($var[$this->marker]);
return $array;
}
/**
* Parses an object into a Kint InstanceObject structure.
*
* @param object $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseObject(&$var, BasicObject $o)
{
$hash = \spl_object_hash($var);
$values = (array) $var;
$object = new InstanceObject();
$object->transplant($o);
$object->classname = \get_class($var);
$object->hash = $hash;
$object->size = \count($values);
if (isset($this->object_hashes[$hash])) {
$object->hints[] = 'recursion';
$this->applyPlugins($var, $object, self::TRIGGER_RECURSION);
return $object;
}
$this->object_hashes[$hash] = $object;
if ($this->depth_limit && $o->depth >= $this->depth_limit) {
$object->hints[] = 'depth_limit';
$this->applyPlugins($var, $object, self::TRIGGER_DEPTH_LIMIT);
unset($this->object_hashes[$hash]);
return $object;
}
$reflector = new ReflectionObject($var);
if ($reflector->isUserDefined()) {
$object->filename = $reflector->getFileName();
$object->startline = $reflector->getStartLine();
}
$rep = new Representation('Properties');
$copy = \array_values($values);
$refmarker = new stdClass();
$i = 0;
// Reflection will not show parent classes private properties, and if a
// property was unset it will happly trigger a notice looking for it.
foreach ($values as $key => &$val) {
// Casting object to array:
// private properties show in the form "\0$owner_class_name\0$property_name";
// protected properties show in the form "\0*\0$property_name";
// public properties show in the form "$property_name";
// http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
$child = new BasicObject();
$child->depth = $object->depth + 1;
$child->owner_class = $object->classname;
$child->operator = BasicObject::OPERATOR_OBJECT;
$child->access = BasicObject::ACCESS_PUBLIC;
$split_key = \explode("\0", $key, 3);
if (3 === \count($split_key) && '' === $split_key[0]) {
$child->name = $split_key[2];
if ('*' === $split_key[1]) {
$child->access = BasicObject::ACCESS_PROTECTED;
} else {
$child->access = BasicObject::ACCESS_PRIVATE;
$child->owner_class = $split_key[1];
}
} elseif (KINT_PHP72) {
$child->name = (string) $key;
} else {
$child->name = $key; // @codeCoverageIgnore
}
if ($this->childHasPath($object, $child)) {
$child->access_path = $object->access_path;
if (!KINT_PHP72 && \is_int($child->name)) {
$child->access_path = 'array_values((array) '.$child->access_path.')['.$i.']'; // @codeCoverageIgnore
} elseif (\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $child->name)) {
$child->access_path .= '->'.$child->name;
} else {
$child->access_path .= '->{'.\var_export((string) $child->name, true).'}';
}
}
$stash = $val;
$copy[$i] = $refmarker;
if ($val === $refmarker) {
$child->reference = true;
$val = $stash;
}
$rep->contents[] = $this->parse($val, $child);
++$i;
}
$object->addRepresentation($rep);
$object->value = $rep;
$this->applyPlugins($var, $object, self::TRIGGER_SUCCESS);
unset($this->object_hashes[$hash]);
return $object;
}
/**
* Parses a resource into a Kint ResourceObject structure.
*
* @param resource $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseResource(&$var, BasicObject $o)
{
$resource = new ResourceObject();
$resource->transplant($o);
$resource->resource_type = \get_resource_type($var);
$this->applyPlugins($var, $resource, self::TRIGGER_SUCCESS);
return $resource;
}
/**
* Parses an unknown into a Kint object structure.
*
* @param mixed $var The input variable
* @param BasicObject $o The base object
*
* @return BasicObject
*/
private function parseUnknown(&$var, BasicObject $o)
{
$o->type = 'unknown';
$this->applyPlugins($var, $o, self::TRIGGER_SUCCESS);
return $o;
}
/**
* Applies plugins for an object type.
*
* @param mixed $var variable
* @param BasicObject $o Kint object parsed so far
* @param int $trigger The trigger to check for the plugins
*
* @return bool Continue parsing
*/
private function applyPlugins(&$var, BasicObject &$o, $trigger)
{
$break_stash = $this->parse_break;
/** @var bool Psalm bug workaround */
$this->parse_break = false;
$plugins = array();
if (isset($this->plugins[$o->type][$trigger])) {
$plugins = $this->plugins[$o->type][$trigger];
}
foreach ($plugins as $plugin) {
try {
$plugin->parse($var, $o, $trigger);
} catch (Exception $e) {
\trigger_error(
'An exception ('.\get_class($e).') was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing Kint Parser Plugin "'.\get_class($plugin).'". Error message: '.$e->getMessage(),
E_USER_WARNING
);
}
if ($this->parse_break) {
$this->parse_break = $break_stash;
return false;
}
}
$this->parse_break = $break_stash;
return true;
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
abstract class Plugin
{
protected $parser;
public function setParser(Parser $p)
{
$this->parser = $p;
}
/**
* An array of types (As returned by gettype) for all data this plugin can operate on.
*
* @return array List of types
*/
public function getTypes()
{
return array();
}
public function getTriggers()
{
return Parser::TRIGGER_NONE;
}
abstract public function parse(&$variable, BasicObject &$o, $trigger);
}

View File

@ -0,0 +1,66 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use InvalidArgumentException;
use Kint\Object\BasicObject;
class ProxyPlugin extends Plugin
{
protected $types;
protected $triggers;
protected $callback;
public function __construct(array $types, $triggers, $callback)
{
if (!\is_int($triggers)) {
throw new InvalidArgumentException('ProxyPlugin triggers must be an int bitmask');
}
if (!\is_callable($callback)) {
throw new InvalidArgumentException('ProxyPlugin callback must be callable');
}
$this->types = $types;
$this->triggers = $triggers;
$this->callback = $callback;
}
public function getTypes()
{
return $this->types;
}
public function getTriggers()
{
return $this->triggers;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
return \call_user_func_array($this->callback, array(&$var, &$o, $trigger, $this->parser));
}
}

View File

@ -0,0 +1,108 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class SerializePlugin extends Plugin
{
/**
* Disables automatic unserialization on arrays and objects.
*
* As the PHP manual notes:
*
* > Unserialization can result in code being loaded and executed due to
* > object instantiation and autoloading, and a malicious user may be able
* > to exploit this.
*
* The natural way to stop that from happening is to just refuse to unserialize
* stuff by default. Which is what we're doing for anything that's not scalar.
*
* @var bool
*/
public static $safe_mode = true;
public static $options = array(true);
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$trimmed = \rtrim($var);
if ('N;' !== $trimmed && !\preg_match('/^(?:[COabis]:\\d+[:;]|d:\\d+(?:\\.\\d+);)/', $trimmed)) {
return;
}
if (!self::$safe_mode || !\in_array($trimmed[0], array('C', 'O', 'a'), true)) {
// Second parameter only supported on PHP 7
if (KINT_PHP70) {
// Suppress warnings on unserializeable variable
$data = @\unserialize($trimmed, self::$options);
} else {
$data = @\unserialize($trimmed);
}
if (false === $data && 'b:0;' !== \substr($trimmed, 0, 4)) {
return;
}
}
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = 'unserialize('.$o->name.')';
if ($o->access_path) {
$base_obj->access_path = 'unserialize('.$o->access_path;
if (!KINT_PHP70 || self::$options === array(true)) {
$base_obj->access_path .= ')';
} elseif (self::$options === array(false)) {
$base_obj->access_path .= ', false)';
} else {
$base_obj->access_path .= ', Serialize::$options)';
}
}
$r = new Representation('Serialized');
if (isset($data)) {
$r->contents = $this->parser->parse($data, $base_obj);
} else {
$base_obj->hints[] = 'blacklist';
$r->contents = $base_obj;
}
$o->addRepresentation($r, 0);
}
}

View File

@ -0,0 +1,154 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\BlobObject;
use Kint\Object\Representation\Representation;
use SimpleXMLElement;
class SimpleXMLElementPlugin extends Plugin
{
/**
* Show all properties and methods.
*
* @var bool
*/
public static $verbose = false;
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof SimpleXMLElement) {
return;
}
$o->hints[] = 'simplexml_element';
if (!self::$verbose) {
$o->removeRepresentation('properties');
$o->removeRepresentation('iterator');
$o->removeRepresentation('methods');
}
// Attributes
$a = new Representation('Attributes');
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = '(string) '.$o->access_path;
}
if ($attribs = $var->attributes()) {
$attribs = \iterator_to_array($attribs);
$attribs = \array_map('strval', $attribs);
} else {
$attribs = array();
}
// XML attributes are by definition strings and don't have children,
// so up the depth limit in case we're just below the limit since
// there won't be any recursive stuff anyway.
$a->contents = $this->parser->parseDeep($attribs, $base_obj)->value->contents;
$o->addRepresentation($a, 0);
// Children
// We need to check children() separately from the values we already parsed because
// text contents won't show up in children() but they will show up in properties.
//
// Why do we still need to check for attributes if we already have an attributes()
// method? Hell if I know!
$children = $var->children();
if ($o->value) {
$c = new Representation('Children');
foreach ($o->value->contents as $value) {
if ('@attributes' === $value->name) {
continue;
}
if (isset($children->{$value->name})) {
$i = 0;
while (isset($children->{$value->name}[$i])) {
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $value->name;
if ($value->access_path) {
$base_obj->access_path = $value->access_path.'['.$i.']';
}
$value = $this->parser->parse($children->{$value->name}[$i], $base_obj);
if ($value->access_path && 'string' === $value->type) {
$value->access_path = '(string) '.$value->access_path;
}
$c->contents[] = $value;
++$i;
}
}
}
$o->size = \count($c->contents);
if (!$o->size) {
$o->size = null;
if (\strlen((string) $var)) {
$base_obj = new BlobObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $o->name;
if ($o->access_path) {
$base_obj->access_path = '(string) '.$o->access_path;
}
$value = (string) $var;
$c = new Representation('Contents');
$c->implicit_label = true;
$c->contents = array($this->parser->parseDeep($value, $base_obj));
}
}
$o->addRepresentation($c, 0);
}
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\SplFileInfoRepresentation;
use SplFileInfo;
use SplFileObject;
class SplFileInfoPlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_COMPLETE;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof SplFileInfo || $var instanceof SplFileObject) {
return;
}
$r = new SplFileInfoRepresentation(clone $var);
$o->addRepresentation($r, 0);
$o->size = $r->getSize();
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use SplObjectStorage;
class SplObjectStoragePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_COMPLETE;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof SplObjectStorage || !($r = $o->getRepresentation('iterator'))) {
return;
}
$r = $o->getRepresentation('iterator');
if ($r) {
$o->size = !\is_array($r->contents) ? null : \count($r->contents);
}
}
}

View File

@ -0,0 +1,78 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
use Kint\Object\ResourceObject;
use Kint\Object\StreamObject;
class StreamPlugin extends Plugin
{
public function getTypes()
{
return array('resource');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o instanceof ResourceObject || 'stream' !== $o->resource_type) {
return;
}
if (!$meta = \stream_get_meta_data($var)) {
return;
}
$rep = new Representation('Stream');
$rep->implicit_label = true;
$base_obj = new BasicObject();
$base_obj->depth = $o->depth;
if ($o->access_path) {
$base_obj->access_path = 'stream_get_meta_data('.$o->access_path.')';
}
$rep->contents = $this->parser->parse($meta, $base_obj);
if (!\in_array('depth_limit', $rep->contents->hints, true)) {
$rep->contents = $rep->contents->value->contents;
}
$o->addRepresentation($rep, 0);
$o->value = $rep;
$stream = new StreamObject($meta);
$stream->transplant($o);
$o = $stream;
}
}

View File

@ -0,0 +1,87 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class TablePlugin extends Plugin
{
public function getTypes()
{
return array('array');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (empty($o->value->contents)) {
return;
}
$array = $this->parser->getCleanArray($var);
if (\count($array) < 2) {
return;
}
// Ensure this is an array of arrays and that all child arrays have the
// same keys. We don't care about their children - if there's another
// "table" inside we'll just make another one down the value tab
$keys = null;
foreach ($array as $elem) {
if (!\is_array($elem) || \count($elem) < 2) {
return;
}
if (null === $keys) {
$keys = \array_keys($elem);
} elseif (\array_keys($elem) !== $keys) {
return;
}
}
// Ensure none of the child arrays are recursion or depth limit. We
// don't care if their children are since they are the table cells
foreach ($o->value->contents as $childarray) {
if (empty($childarray->value->contents)) {
return;
}
}
// Objects by reference for the win! We can do a copy-paste of the value
// representation contents and just slap a new hint on there and hey
// presto we have our table representation with no extra memory used!
$table = new Representation('Table');
$table->contents = $o->value->contents;
$table->hints[] = 'table';
$o->addRepresentation($table, 0);
}
}

View File

@ -0,0 +1,60 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Exception;
use Kint\Object\BasicObject;
use Kint\Object\Representation\SourceRepresentation;
use Kint\Object\ThrowableObject;
use Throwable;
class ThrowablePlugin extends Plugin
{
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$var instanceof Exception && (!KINT_PHP70 || !$var instanceof Throwable)) {
return;
}
$throw = new ThrowableObject($var);
$throw->transplant($o);
$r = new SourceRepresentation($var->getFile(), $var->getLine());
$r->showfilename = true;
$throw->addRepresentation($r, 0);
$o = $throw;
}
}

View File

@ -0,0 +1,71 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
class TimestampPlugin extends Plugin
{
public static $blacklist = array(
2147483648,
2147483647,
1073741824,
1073741823,
);
public function getTypes()
{
return array('string', 'integer');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (\is_string($var) && !\ctype_digit($var)) {
return;
}
if (\in_array($var, self::$blacklist, true)) {
return;
}
$len = \strlen($var);
// Guess for anything between March 1973 and November 2286
if (9 === $len || 10 === $len) {
// If it's an int or string that's this short it probably has no other meaning
// Additionally it's highly unlikely the shortValue will be clipped for length
// If you're writing a plugin that interferes with this, just put your
// parser plugin further down the list so that it gets loaded afterwards.
$o->value->label = 'Timestamp';
$o->value->hints[] = 'timestamp';
}
}
}

View File

@ -0,0 +1,67 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
use ReflectionClass;
class ToStringPlugin extends Plugin
{
public static $blacklist = array(
'SimpleXMLElement',
'SplFileObject',
);
public function getTypes()
{
return array('object');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
$reflection = new ReflectionClass($var);
if (!$reflection->hasMethod('__toString')) {
return;
}
foreach (self::$blacklist as $class) {
if ($var instanceof $class) {
return;
}
}
$r = new Representation('toString');
$r->contents = (string) $var;
$o->addRepresentation($r);
}
}

View File

@ -0,0 +1,92 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use Kint\Object\BasicObject;
use Kint\Object\TraceFrameObject;
use Kint\Object\TraceObject;
use Kint\Utils;
class TracePlugin extends Plugin
{
public static $blacklist = array('spl_autoload_call');
public function getTypes()
{
return array('array');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if (!$o->value) {
return;
}
$trace = $this->parser->getCleanArray($var);
if (\count($trace) !== \count($o->value->contents) || !Utils::isTrace($trace)) {
return;
}
$traceobj = new TraceObject();
$traceobj->transplant($o);
$rep = $traceobj->value;
$old_trace = $rep->contents;
Utils::normalizeAliases(self::$blacklist);
$rep->contents = array();
foreach ($old_trace as $frame) {
$index = $frame->name;
if (!isset($trace[$index]['function'])) {
// Something's very very wrong here, but it's probably a plugin's fault
continue;
}
if (Utils::traceFrameIsListed($trace[$index], self::$blacklist)) {
continue;
}
$rep->contents[$index] = new TraceFrameObject($frame, $trace[$index]);
}
\ksort($rep->contents);
$rep->contents = \array_values($rep->contents);
$traceobj->clearRepresentations();
$traceobj->addRepresentation($rep);
$traceobj->size = \count($rep->contents);
$o = $traceobj;
}
}

View File

@ -0,0 +1,150 @@
<?php
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Kint\Parser;
use DOMDocument;
use Exception;
use Kint\Object\BasicObject;
use Kint\Object\Representation\Representation;
class XmlPlugin extends Plugin
{
/**
* Which method to parse the variable with.
*
* DOMDocument provides more information including the text between nodes,
* however it's memory usage is very high and it takes longer to parse and
* render. Plus it's a pain to work with. So SimpleXML is the default.
*
* @var string
*/
public static $parse_method = 'SimpleXML';
public function getTypes()
{
return array('string');
}
public function getTriggers()
{
return Parser::TRIGGER_SUCCESS;
}
public function parse(&$var, BasicObject &$o, $trigger)
{
if ('<?xml' !== \substr($var, 0, 5)) {
return;
}
if (!\method_exists(\get_class($this), 'xmlTo'.self::$parse_method)) {
return;
}
$xml = \call_user_func(array(\get_class($this), 'xmlTo'.self::$parse_method), $var, $o->access_path);
if (empty($xml)) {
return;
}
list($xml, $access_path, $name) = $xml;
$base_obj = new BasicObject();
$base_obj->depth = $o->depth + 1;
$base_obj->name = $name;
$base_obj->access_path = $access_path;
$r = new Representation('XML');
$r->contents = $this->parser->parse($xml, $base_obj);
$o->addRepresentation($r, 0);
}
protected static function xmlToSimpleXML($var, $parent_path)
{
try {
$errors = \libxml_use_internal_errors(true);
$xml = \simplexml_load_string($var);
\libxml_use_internal_errors($errors);
} catch (Exception $e) {
if (isset($errors)) {
\libxml_use_internal_errors($errors);
}
return;
}
if (!$xml) {
return;
}
if (null === $parent_path) {
$access_path = null;
} else {
$access_path = 'simplexml_load_string('.$parent_path.')';
}
$name = $xml->getName();
return array($xml, $access_path, $name);
}
/**
* Get the DOMDocument info.
*
* The documentation of DOMDocument::loadXML() states that while you can
* call it statically, it will give an E_STRICT warning. On my system it
* actually gives an E_DEPRECATED warning, but it works so we'll just add
* an error-silencing '@' to the access path.
*
* If it errors loading then we wouldn't have gotten this far in the first place.
*
* @param string $var The XML string
* @param null|string $parent_path The path to the parent, in this case the XML string
*
* @return null|array The root element DOMNode, the access path, and the root element name
*/
protected static function xmlToDOMDocument($var, $parent_path)
{
// There's no way to check validity in DOMDocument without making errors. For shame!
if (!self::xmlToSimpleXML($var, $parent_path)) {
return null;
}
$xml = new DOMDocument();
$xml->loadXML($var);
$xml = $xml->firstChild;
if (null === $parent_path) {
$access_path = null;
} else {
$access_path = '@\\DOMDocument::loadXML('.$parent_path.')->firstChild';
}
$name = $xml->nodeName;
return array($xml, $access_path, $name);
}
}