| 1: | <?php |
| 2: | |
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: | |
| 10: | |
| 11: | |
| 12: | |
| 13: | |
| 14: | |
| 15: | |
| 16: | |
| 17: | |
| 18: | |
| 19: | |
| 20: | |
| 21: | |
| 22: | |
| 23: | |
| 24: | |
| 25: | |
| 26: | namespace Kint; |
| 27: | |
| 28: | use InvalidArgumentException; |
| 29: | use Kint\Object\BasicObject; |
| 30: | use Kint\Parser\Parser; |
| 31: | use Kint\Parser\Plugin; |
| 32: | use Kint\Renderer\Renderer; |
| 33: | use Kint\Renderer\TextRenderer; |
| 34: | |
| 35: | class Kint |
| 36: | { |
| 37: | const MODE_RICH = 'r'; |
| 38: | const MODE_TEXT = 't'; |
| 39: | const MODE_CLI = 'c'; |
| 40: | const MODE_PLAIN = 'p'; |
| 41: | |
| 42: | |
| 43: | |
| 44: | |
| 45: | |
| 46: | |
| 47: | |
| 48: | |
| 49: | public static $enabled_mode = true; |
| 50: | |
| 51: | |
| 52: | |
| 53: | |
| 54: | |
| 55: | |
| 56: | public static $mode_default = self::MODE_RICH; |
| 57: | |
| 58: | |
| 59: | |
| 60: | |
| 61: | |
| 62: | |
| 63: | public static $mode_default_cli = self::MODE_CLI; |
| 64: | |
| 65: | |
| 66: | |
| 67: | |
| 68: | public static $return; |
| 69: | |
| 70: | |
| 71: | |
| 72: | |
| 73: | |
| 74: | |
| 75: | |
| 76: | |
| 77: | |
| 78: | |
| 79: | public static $file_link_format = ''; |
| 80: | |
| 81: | |
| 82: | |
| 83: | |
| 84: | public static $display_called_from = true; |
| 85: | |
| 86: | |
| 87: | |
| 88: | |
| 89: | |
| 90: | |
| 91: | |
| 92: | |
| 93: | |
| 94: | |
| 95: | |
| 96: | |
| 97: | |
| 98: | |
| 99: | |
| 100: | |
| 101: | |
| 102: | |
| 103: | |
| 104: | |
| 105: | public static $app_root_dirs = array(); |
| 106: | |
| 107: | |
| 108: | |
| 109: | |
| 110: | public static $max_depth = 6; |
| 111: | |
| 112: | |
| 113: | |
| 114: | |
| 115: | public static $expanded = false; |
| 116: | |
| 117: | |
| 118: | |
| 119: | |
| 120: | |
| 121: | |
| 122: | public static $cli_detection = true; |
| 123: | |
| 124: | |
| 125: | |
| 126: | |
| 127: | public static $aliases = array( |
| 128: | array('Kint\\Kint', 'dump'), |
| 129: | array('Kint\\Kint', 'trace'), |
| 130: | array('Kint\\Kint', 'dumpArray'), |
| 131: | ); |
| 132: | |
| 133: | |
| 134: | |
| 135: | |
| 136: | public static $renderers = array( |
| 137: | self::MODE_RICH => 'Kint\\Renderer\\RichRenderer', |
| 138: | self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer', |
| 139: | self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer', |
| 140: | self::MODE_CLI => 'Kint\\Renderer\\CliRenderer', |
| 141: | ); |
| 142: | |
| 143: | public static $plugins = array( |
| 144: | 'Kint\\Parser\\ArrayObjectPlugin', |
| 145: | 'Kint\\Parser\\Base64Plugin', |
| 146: | 'Kint\\Parser\\BlacklistPlugin', |
| 147: | 'Kint\\Parser\\ClassMethodsPlugin', |
| 148: | 'Kint\\Parser\\ClassStaticsPlugin', |
| 149: | 'Kint\\Parser\\ClosurePlugin', |
| 150: | 'Kint\\Parser\\ColorPlugin', |
| 151: | 'Kint\\Parser\\DateTimePlugin', |
| 152: | 'Kint\\Parser\\FsPathPlugin', |
| 153: | 'Kint\\Parser\\IteratorPlugin', |
| 154: | 'Kint\\Parser\\JsonPlugin', |
| 155: | 'Kint\\Parser\\MicrotimePlugin', |
| 156: | 'Kint\\Parser\\SimpleXMLElementPlugin', |
| 157: | 'Kint\\Parser\\SplFileInfoPlugin', |
| 158: | 'Kint\\Parser\\SplObjectStoragePlugin', |
| 159: | 'Kint\\Parser\\StreamPlugin', |
| 160: | 'Kint\\Parser\\TablePlugin', |
| 161: | 'Kint\\Parser\\ThrowablePlugin', |
| 162: | 'Kint\\Parser\\TimestampPlugin', |
| 163: | 'Kint\\Parser\\TracePlugin', |
| 164: | 'Kint\\Parser\\XmlPlugin', |
| 165: | ); |
| 166: | |
| 167: | protected static $plugin_pool = array(); |
| 168: | |
| 169: | protected $parser; |
| 170: | protected $renderer; |
| 171: | |
| 172: | public function __construct(Parser $p, Renderer $r) |
| 173: | { |
| 174: | $this->parser = $p; |
| 175: | $this->renderer = $r; |
| 176: | } |
| 177: | |
| 178: | public function setParser(Parser $p) |
| 179: | { |
| 180: | $this->parser = $p; |
| 181: | } |
| 182: | |
| 183: | public function getParser() |
| 184: | { |
| 185: | return $this->parser; |
| 186: | } |
| 187: | |
| 188: | public function setRenderer(Renderer $r) |
| 189: | { |
| 190: | $this->renderer = $r; |
| 191: | } |
| 192: | |
| 193: | public function getRenderer() |
| 194: | { |
| 195: | return $this->renderer; |
| 196: | } |
| 197: | |
| 198: | public function setStatesFromStatics(array $statics) |
| 199: | { |
| 200: | $this->renderer->setStatics($statics); |
| 201: | |
| 202: | $this->parser->setDepthLimit(isset($statics['max_depth']) ? $statics['max_depth'] : false); |
| 203: | $this->parser->clearPlugins(); |
| 204: | |
| 205: | if (!isset($statics['plugins'])) { |
| 206: | return; |
| 207: | } |
| 208: | |
| 209: | $plugins = array(); |
| 210: | |
| 211: | foreach ($statics['plugins'] as $plugin) { |
| 212: | if ($plugin instanceof Plugin) { |
| 213: | $plugins[] = $plugin; |
| 214: | } elseif (\is_string($plugin) && \is_subclass_of($plugin, 'Kint\\Parser\\Plugin')) { |
| 215: | if (!isset(self::$plugin_pool[$plugin])) { |
| 216: | $p = new $plugin(); |
| 217: | self::$plugin_pool[$plugin] = $p; |
| 218: | } |
| 219: | $plugins[] = self::$plugin_pool[$plugin]; |
| 220: | } |
| 221: | } |
| 222: | |
| 223: | $plugins = $this->renderer->filterParserPlugins($plugins); |
| 224: | |
| 225: | foreach ($plugins as $plugin) { |
| 226: | $this->parser->addPlugin($plugin); |
| 227: | } |
| 228: | } |
| 229: | |
| 230: | public function setStatesFromCallInfo(array $info) |
| 231: | { |
| 232: | $this->renderer->setCallInfo($info); |
| 233: | |
| 234: | if (isset($info['modifiers']) && \is_array($info['modifiers']) && \in_array('+', $info['modifiers'], true)) { |
| 235: | $this->parser->setDepthLimit(false); |
| 236: | } |
| 237: | |
| 238: | $this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null); |
| 239: | } |
| 240: | |
| 241: | |
| 242: | |
| 243: | |
| 244: | |
| 245: | |
| 246: | |
| 247: | |
| 248: | |
| 249: | public function dumpAll(array $vars, array $base) |
| 250: | { |
| 251: | if (\array_keys($vars) !== \array_keys($base)) { |
| 252: | throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments'); |
| 253: | } |
| 254: | |
| 255: | $output = $this->renderer->preRender(); |
| 256: | |
| 257: | if ($vars === array()) { |
| 258: | $output .= $this->renderer->renderNothing(); |
| 259: | } |
| 260: | |
| 261: | foreach ($vars as $key => $arg) { |
| 262: | if (!$base[$key] instanceof BasicObject) { |
| 263: | throw new InvalidArgumentException('Kint::dumpAll requires all elements of the second argument to be BasicObject instances'); |
| 264: | } |
| 265: | $output .= $this->dumpVar($arg, $base[$key]); |
| 266: | } |
| 267: | |
| 268: | $output .= $this->renderer->postRender(); |
| 269: | |
| 270: | return $output; |
| 271: | } |
| 272: | |
| 273: | |
| 274: | |
| 275: | |
| 276: | |
| 277: | |
| 278: | |
| 279: | |
| 280: | |
| 281: | public function dumpVar(&$var, BasicObject $base) |
| 282: | { |
| 283: | return $this->renderer->render( |
| 284: | $this->parser->parse($var, $base) |
| 285: | ); |
| 286: | } |
| 287: | |
| 288: | |
| 289: | |
| 290: | |
| 291: | |
| 292: | |
| 293: | public static function getStatics() |
| 294: | { |
| 295: | return array( |
| 296: | 'aliases' => self::$aliases, |
| 297: | 'app_root_dirs' => self::$app_root_dirs, |
| 298: | 'cli_detection' => self::$cli_detection, |
| 299: | 'display_called_from' => self::$display_called_from, |
| 300: | 'enabled_mode' => self::$enabled_mode, |
| 301: | 'expanded' => self::$expanded, |
| 302: | 'file_link_format' => self::$file_link_format, |
| 303: | 'max_depth' => self::$max_depth, |
| 304: | 'mode_default' => self::$mode_default, |
| 305: | 'mode_default_cli' => self::$mode_default_cli, |
| 306: | 'plugins' => self::$plugins, |
| 307: | 'renderers' => self::$renderers, |
| 308: | 'return' => self::$return, |
| 309: | ); |
| 310: | } |
| 311: | |
| 312: | |
| 313: | |
| 314: | |
| 315: | |
| 316: | |
| 317: | |
| 318: | |
| 319: | |
| 320: | |
| 321: | public static function createFromStatics(array $statics) |
| 322: | { |
| 323: | $mode = false; |
| 324: | |
| 325: | if (isset($statics['enabled_mode'])) { |
| 326: | $mode = $statics['enabled_mode']; |
| 327: | |
| 328: | if (true === $statics['enabled_mode'] && isset($statics['mode_default'])) { |
| 329: | $mode = $statics['mode_default']; |
| 330: | |
| 331: | if (PHP_SAPI === 'cli' && !empty($statics['cli_detection']) && isset($statics['mode_default_cli'])) { |
| 332: | $mode = $statics['mode_default_cli']; |
| 333: | } |
| 334: | } |
| 335: | } |
| 336: | |
| 337: | if (!$mode) { |
| 338: | return null; |
| 339: | } |
| 340: | |
| 341: | if (!isset($statics['renderers'][$mode])) { |
| 342: | $renderer = new TextRenderer(); |
| 343: | } else { |
| 344: | |
| 345: | $renderer = new $statics['renderers'][$mode](); |
| 346: | } |
| 347: | |
| 348: | return new self(new Parser(), $renderer); |
| 349: | } |
| 350: | |
| 351: | |
| 352: | |
| 353: | |
| 354: | |
| 355: | |
| 356: | |
| 357: | |
| 358: | |
| 359: | public static function getBasesFromParamInfo(array $params, $argc) |
| 360: | { |
| 361: | static $blacklist = array( |
| 362: | 'null', |
| 363: | 'true', |
| 364: | 'false', |
| 365: | 'array(...)', |
| 366: | 'array()', |
| 367: | '[...]', |
| 368: | '[]', |
| 369: | '(...)', |
| 370: | '()', |
| 371: | '"..."', |
| 372: | 'b"..."', |
| 373: | "'...'", |
| 374: | "b'...'", |
| 375: | ); |
| 376: | |
| 377: | $params = \array_values($params); |
| 378: | $bases = array(); |
| 379: | |
| 380: | for ($i = 0; $i < $argc; ++$i) { |
| 381: | if (isset($params[$i])) { |
| 382: | $param = $params[$i]; |
| 383: | } else { |
| 384: | $param = null; |
| 385: | } |
| 386: | |
| 387: | if (!isset($param['name']) || \is_numeric($param['name'])) { |
| 388: | $name = null; |
| 389: | } elseif (\in_array(\strtolower($param['name']), $blacklist, true)) { |
| 390: | $name = null; |
| 391: | } else { |
| 392: | $name = $param['name']; |
| 393: | } |
| 394: | |
| 395: | if (isset($param['path'])) { |
| 396: | $access_path = $param['path']; |
| 397: | |
| 398: | if (!empty($param['expression'])) { |
| 399: | $access_path = '('.$access_path.')'; |
| 400: | } |
| 401: | } else { |
| 402: | $access_path = '$'.$i; |
| 403: | } |
| 404: | |
| 405: | $bases[] = BasicObject::blank($name, $access_path); |
| 406: | } |
| 407: | |
| 408: | return $bases; |
| 409: | } |
| 410: | |
| 411: | |
| 412: | |
| 413: | |
| 414: | |
| 415: | |
| 416: | |
| 417: | |
| 418: | |
| 419: | |
| 420: | |
| 421: | |
| 422: | public static function getCallInfo(array $aliases, array $trace, $argc) |
| 423: | { |
| 424: | $found = false; |
| 425: | $callee = null; |
| 426: | $caller = null; |
| 427: | $miniTrace = array(); |
| 428: | |
| 429: | foreach ($trace as $index => $frame) { |
| 430: | if (Utils::traceFrameIsListed($frame, $aliases)) { |
| 431: | $found = true; |
| 432: | $miniTrace = array(); |
| 433: | } |
| 434: | |
| 435: | if (!Utils::traceFrameIsListed($frame, array('spl_autoload_call'))) { |
| 436: | $miniTrace[] = $frame; |
| 437: | } |
| 438: | } |
| 439: | |
| 440: | if ($found) { |
| 441: | $callee = \reset($miniTrace) ?: null; |
| 442: | |
| 443: | |
| 444: | $caller = \next($miniTrace) ?: null; |
| 445: | } |
| 446: | |
| 447: | foreach ($miniTrace as $index => $frame) { |
| 448: | if ((0 === $index && $callee === $frame) || isset($frame['file'], $frame['line'])) { |
| 449: | unset($frame['object'], $frame['args']); |
| 450: | $miniTrace[$index] = $frame; |
| 451: | } else { |
| 452: | unset($miniTrace[$index]); |
| 453: | } |
| 454: | } |
| 455: | |
| 456: | $miniTrace = \array_values($miniTrace); |
| 457: | |
| 458: | $call = self::getSingleCall($callee ?: array(), $argc); |
| 459: | |
| 460: | $ret = array( |
| 461: | 'params' => null, |
| 462: | 'modifiers' => array(), |
| 463: | 'callee' => $callee, |
| 464: | 'caller' => $caller, |
| 465: | 'trace' => $miniTrace, |
| 466: | ); |
| 467: | |
| 468: | if ($call) { |
| 469: | $ret['params'] = $call['parameters']; |
| 470: | $ret['modifiers'] = $call['modifiers']; |
| 471: | } |
| 472: | |
| 473: | return $ret; |
| 474: | } |
| 475: | |
| 476: | |
| 477: | |
| 478: | |
| 479: | |
| 480: | |
| 481: | |
| 482: | |
| 483: | public static function trace() |
| 484: | { |
| 485: | if (!self::$enabled_mode) { |
| 486: | return 0; |
| 487: | } |
| 488: | |
| 489: | Utils::normalizeAliases(self::$aliases); |
| 490: | |
| 491: | $args = \func_get_args(); |
| 492: | |
| 493: | $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args)); |
| 494: | |
| 495: | $statics = self::getStatics(); |
| 496: | |
| 497: | if (\in_array('~', $call_info['modifiers'], true)) { |
| 498: | $statics['enabled_mode'] = self::MODE_TEXT; |
| 499: | } |
| 500: | |
| 501: | $kintstance = self::createFromStatics($statics); |
| 502: | if (!$kintstance) { |
| 503: | |
| 504: | return 0; |
| 505: | } |
| 506: | |
| 507: | if (\in_array('-', $call_info['modifiers'], true)) { |
| 508: | while (\ob_get_level()) { |
| 509: | \ob_end_clean(); |
| 510: | } |
| 511: | } |
| 512: | |
| 513: | $kintstance->setStatesFromStatics($statics); |
| 514: | $kintstance->setStatesFromCallInfo($call_info); |
| 515: | |
| 516: | $trimmed_trace = array(); |
| 517: | $trace = \debug_backtrace(true); |
| 518: | |
| 519: | foreach ($trace as $frame) { |
| 520: | if (Utils::traceFrameIsListed($frame, self::$aliases)) { |
| 521: | $trimmed_trace = array(); |
| 522: | } |
| 523: | |
| 524: | $trimmed_trace[] = $frame; |
| 525: | } |
| 526: | |
| 527: | $output = $kintstance->dumpAll( |
| 528: | array($trimmed_trace), |
| 529: | array(BasicObject::blank('Kint\\Kint::trace()', 'debug_backtrace(true)')) |
| 530: | ); |
| 531: | |
| 532: | if (self::$return || \in_array('@', $call_info['modifiers'], true)) { |
| 533: | return $output; |
| 534: | } |
| 535: | |
| 536: | echo $output; |
| 537: | |
| 538: | if (\in_array('-', $call_info['modifiers'], true)) { |
| 539: | \flush(); |
| 540: | } |
| 541: | |
| 542: | return 0; |
| 543: | } |
| 544: | |
| 545: | |
| 546: | |
| 547: | |
| 548: | |
| 549: | |
| 550: | |
| 551: | |
| 552: | public static function dump() |
| 553: | { |
| 554: | if (!self::$enabled_mode) { |
| 555: | return 0; |
| 556: | } |
| 557: | |
| 558: | Utils::normalizeAliases(self::$aliases); |
| 559: | |
| 560: | $args = \func_get_args(); |
| 561: | |
| 562: | $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args)); |
| 563: | |
| 564: | $statics = self::getStatics(); |
| 565: | |
| 566: | if (\in_array('~', $call_info['modifiers'], true)) { |
| 567: | $statics['enabled_mode'] = self::MODE_TEXT; |
| 568: | } |
| 569: | |
| 570: | $kintstance = self::createFromStatics($statics); |
| 571: | if (!$kintstance) { |
| 572: | |
| 573: | return 0; |
| 574: | } |
| 575: | |
| 576: | if (\in_array('-', $call_info['modifiers'], true)) { |
| 577: | while (\ob_get_level()) { |
| 578: | \ob_end_clean(); |
| 579: | } |
| 580: | } |
| 581: | |
| 582: | $kintstance->setStatesFromStatics($statics); |
| 583: | $kintstance->setStatesFromCallInfo($call_info); |
| 584: | |
| 585: | |
| 586: | if ($args === array(1) && (!isset($call_info['params'][0]['name']) || '1' === $call_info['params'][0]['name'])) { |
| 587: | $args = \debug_backtrace(true); |
| 588: | $trace = array(); |
| 589: | |
| 590: | foreach ($args as $index => $frame) { |
| 591: | if (Utils::traceFrameIsListed($frame, self::$aliases)) { |
| 592: | $trace = array(); |
| 593: | } |
| 594: | |
| 595: | $trace[] = $frame; |
| 596: | } |
| 597: | |
| 598: | if (isset($call_info['callee']['function'])) { |
| 599: | $tracename = $call_info['callee']['function'].'(1)'; |
| 600: | if (isset($call_info['callee']['class'], $call_info['callee']['type'])) { |
| 601: | $tracename = $call_info['callee']['class'].$call_info['callee']['type'].$tracename; |
| 602: | } |
| 603: | } else { |
| 604: | $tracename = 'Kint\\Kint::dump(1)'; |
| 605: | } |
| 606: | |
| 607: | $tracebase = BasicObject::blank($tracename, 'debug_backtrace(true)'); |
| 608: | |
| 609: | $output = $kintstance->dumpAll(array($trace), array($tracebase)); |
| 610: | } else { |
| 611: | $bases = self::getBasesFromParamInfo( |
| 612: | isset($call_info['params']) ? $call_info['params'] : array(), |
| 613: | \count($args) |
| 614: | ); |
| 615: | $output = $kintstance->dumpAll($args, $bases); |
| 616: | } |
| 617: | |
| 618: | if (self::$return || \in_array('@', $call_info['modifiers'], true)) { |
| 619: | return $output; |
| 620: | } |
| 621: | |
| 622: | echo $output; |
| 623: | |
| 624: | if (\in_array('-', $call_info['modifiers'], true)) { |
| 625: | \flush(); |
| 626: | } |
| 627: | |
| 628: | return 0; |
| 629: | } |
| 630: | |
| 631: | |
| 632: | |
| 633: | |
| 634: | |
| 635: | |
| 636: | |
| 637: | |
| 638: | |
| 639: | public static function shortenPath($file) |
| 640: | { |
| 641: | $file = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $file)), 'strlen')); |
| 642: | |
| 643: | $longest_match = 0; |
| 644: | $match = '/'; |
| 645: | |
| 646: | foreach (self::$app_root_dirs as $path => $alias) { |
| 647: | if (empty($path)) { |
| 648: | continue; |
| 649: | } |
| 650: | |
| 651: | $path = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $path)), 'strlen')); |
| 652: | |
| 653: | if (\array_slice($file, 0, \count($path)) === $path && \count($path) > $longest_match) { |
| 654: | $longest_match = \count($path); |
| 655: | $match = $alias; |
| 656: | } |
| 657: | } |
| 658: | |
| 659: | if ($longest_match) { |
| 660: | $file = \array_merge(array($match), \array_slice($file, $longest_match)); |
| 661: | |
| 662: | return \implode('/', $file); |
| 663: | } |
| 664: | |
| 665: | |
| 666: | $kint = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', KINT_DIR)), 'strlen')); |
| 667: | |
| 668: | foreach ($file as $i => $part) { |
| 669: | if (!isset($kint[$i]) || $kint[$i] !== $part) { |
| 670: | return ($i ? '.../' : '/').\implode('/', \array_slice($file, $i)); |
| 671: | } |
| 672: | } |
| 673: | |
| 674: | return '/'.\implode('/', $file); |
| 675: | } |
| 676: | |
| 677: | public static function getIdeLink($file, $line) |
| 678: | { |
| 679: | return \str_replace(array('%f', '%l'), array($file, $line), self::$file_link_format); |
| 680: | } |
| 681: | |
| 682: | |
| 683: | |
| 684: | |
| 685: | |
| 686: | |
| 687: | |
| 688: | |
| 689: | |
| 690: | protected static function getSingleCall(array $frame, $argc) |
| 691: | { |
| 692: | if (!isset($frame['file'], $frame['line'], $frame['function']) || !\is_readable($frame['file'])) { |
| 693: | return null; |
| 694: | } |
| 695: | |
| 696: | if (empty($frame['class'])) { |
| 697: | $callfunc = $frame['function']; |
| 698: | } else { |
| 699: | $callfunc = array($frame['class'], $frame['function']); |
| 700: | } |
| 701: | |
| 702: | $calls = CallFinder::getFunctionCalls( |
| 703: | \file_get_contents($frame['file']), |
| 704: | $frame['line'], |
| 705: | $callfunc |
| 706: | ); |
| 707: | |
| 708: | $return = null; |
| 709: | |
| 710: | foreach ($calls as $call) { |
| 711: | $is_unpack = false; |
| 712: | |
| 713: | |
| 714: | if (KINT_PHP56) { |
| 715: | foreach ($call['parameters'] as $i => &$param) { |
| 716: | if (0 === \strpos($param['name'], '...')) { |
| 717: | if ($i < $argc && $i === \count($call['parameters']) - 1) { |
| 718: | for ($j = 1; $j + $i < $argc; ++$j) { |
| 719: | $call['parameters'][] = array( |
| 720: | 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']', |
| 721: | 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']', |
| 722: | 'expression' => false, |
| 723: | ); |
| 724: | } |
| 725: | |
| 726: | $param['name'] = 'reset('.\substr($param['name'], 3).')'; |
| 727: | $param['path'] = 'reset('.\substr($param['path'], 3).')'; |
| 728: | $param['expression'] = false; |
| 729: | } else { |
| 730: | $call['parameters'] = \array_slice($call['parameters'], 0, $i); |
| 731: | } |
| 732: | |
| 733: | $is_unpack = true; |
| 734: | break; |
| 735: | } |
| 736: | |
| 737: | if ($i >= $argc) { |
| 738: | continue 2; |
| 739: | } |
| 740: | } |
| 741: | } |
| 742: | |
| 743: | if ($is_unpack || \count($call['parameters']) === $argc) { |
| 744: | if (null === $return) { |
| 745: | $return = $call; |
| 746: | } else { |
| 747: | |
| 748: | |
| 749: | return null; |
| 750: | } |
| 751: | } |
| 752: | } |
| 753: | |
| 754: | return $return; |
| 755: | } |
| 756: | } |
| 757: | |