[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/maximebf/debugbar/src/DebugBar/ -> JavascriptRenderer.php (source)

   1  <?php
   2  /*
   3   * This file is part of the DebugBar package.
   4   *
   5   * (c) 2013 Maxime Bouroumeau-Fuseau
   6   *
   7   * For the full copyright and license information, please view the LICENSE
   8   * file that was distributed with this source code.
   9   */
  10  
  11  namespace DebugBar;
  12  
  13  use DebugBar\DataCollector\AssetProvider;
  14  use DebugBar\DataCollector\Renderable;
  15  
  16  /**
  17   * Renders the debug bar using the client side javascript implementation
  18   *
  19   * Generates all the needed initialization code of controls
  20   */
  21  class JavascriptRenderer
  22  {
  23      const INITIALIZE_CONSTRUCTOR = 2;
  24  
  25      const INITIALIZE_CONTROLS = 4;
  26  
  27      const REPLACEABLE_TAG = "{--DEBUGBAR_OB_START_REPLACE_ME--}";
  28  
  29      const RELATIVE_PATH = 'path';
  30  
  31      const RELATIVE_URL = 'url';
  32  
  33      protected $debugBar;
  34  
  35      protected $baseUrl;
  36  
  37      protected $basePath;
  38  
  39      protected $cssVendors = array(
  40          'fontawesome' => 'vendor/font-awesome/css/font-awesome.min.css',
  41          'highlightjs' => 'vendor/highlightjs/styles/github.css'
  42      );
  43  
  44      protected $jsVendors = array(
  45          'jquery' => 'vendor/jquery/dist/jquery.min.js',
  46          'highlightjs' => 'vendor/highlightjs/highlight.pack.js'
  47      );
  48  
  49      protected $includeVendors = true;
  50  
  51      protected $cssFiles = array('debugbar.css', 'widgets.css', 'openhandler.css');
  52  
  53      protected $jsFiles = array('debugbar.js', 'widgets.js', 'openhandler.js');
  54  
  55      protected $additionalAssets = array();
  56  
  57      protected $javascriptClass = 'PhpDebugBar.DebugBar';
  58  
  59      protected $variableName = 'phpdebugbar';
  60  
  61      protected $enableJqueryNoConflict = true;
  62  
  63      protected $useRequireJs = false;
  64  
  65      protected $initialization;
  66  
  67      protected $controls = array();
  68  
  69      protected $ignoredCollectors = array();
  70  
  71      protected $ajaxHandlerClass = 'PhpDebugBar.AjaxHandler';
  72  
  73      protected $ajaxHandlerBindToFetch = false;
  74  
  75      protected $ajaxHandlerBindToJquery = true;
  76  
  77      protected $ajaxHandlerBindToXHR = false;
  78  
  79      protected $ajaxHandlerAutoShow = true;
  80  
  81      protected $openHandlerClass = 'PhpDebugBar.OpenHandler';
  82  
  83      protected $openHandlerUrl;
  84  
  85      protected $cspNonce;
  86  
  87      /**
  88       * @param \DebugBar\DebugBar $debugBar
  89       * @param string $baseUrl
  90       * @param string $basePath
  91       */
  92      public function __construct(DebugBar $debugBar, $baseUrl = null, $basePath = null)
  93      {
  94          $this->debugBar = $debugBar;
  95  
  96          if ($baseUrl === null) {
  97              $baseUrl = '/vendor/maximebf/debugbar/src/DebugBar/Resources';
  98          }
  99          $this->baseUrl = $baseUrl;
 100  
 101          if ($basePath === null) {
 102              $basePath = __DIR__ . DIRECTORY_SEPARATOR . 'Resources';
 103          }
 104          $this->basePath = $basePath;
 105  
 106          // bitwise operations cannot be done in class definition :(
 107          $this->initialization = self::INITIALIZE_CONSTRUCTOR | self::INITIALIZE_CONTROLS;
 108      }
 109  
 110      /**
 111       * Sets options from an array
 112       *
 113       * Options:
 114       *  - base_path
 115       *  - base_url
 116       *  - include_vendors
 117       *  - javascript_class
 118       *  - variable_name
 119       *  - initialization
 120       *  - enable_jquery_noconflict
 121       *  - controls
 122       *  - disable_controls
 123       *  - ignore_collectors
 124       *  - ajax_handler_classname
 125       *  - ajax_handler_bind_to_jquery
 126       *  - ajax_handler_auto_show
 127       *  - open_handler_classname
 128       *  - open_handler_url
 129       *
 130       * @param array $options [description]
 131       */
 132      public function setOptions(array $options)
 133      {
 134          if (array_key_exists('base_path', $options)) {
 135              $this->setBasePath($options['base_path']);
 136          }
 137          if (array_key_exists('base_url', $options)) {
 138              $this->setBaseUrl($options['base_url']);
 139          }
 140          if (array_key_exists('include_vendors', $options)) {
 141              $this->setIncludeVendors($options['include_vendors']);
 142          }
 143          if (array_key_exists('javascript_class', $options)) {
 144              $this->setJavascriptClass($options['javascript_class']);
 145          }
 146          if (array_key_exists('variable_name', $options)) {
 147              $this->setVariableName($options['variable_name']);
 148          }
 149          if (array_key_exists('initialization', $options)) {
 150              $this->setInitialization($options['initialization']);
 151          }
 152          if (array_key_exists('enable_jquery_noconflict', $options)) {
 153              $this->setEnableJqueryNoConflict($options['enable_jquery_noconflict']);
 154          }
 155          if (array_key_exists('use_requirejs', $options)) {
 156              $this->setUseRequireJs($options['use_requirejs']);
 157          }
 158          if (array_key_exists('controls', $options)) {
 159              foreach ($options['controls'] as $name => $control) {
 160                  $this->addControl($name, $control);
 161              }
 162          }
 163          if (array_key_exists('disable_controls', $options)) {
 164              foreach ((array) $options['disable_controls'] as $name) {
 165                  $this->disableControl($name);
 166              }
 167          }
 168          if (array_key_exists('ignore_collectors', $options)) {
 169              foreach ((array) $options['ignore_collectors'] as $name) {
 170                  $this->ignoreCollector($name);
 171              }
 172          }
 173          if (array_key_exists('ajax_handler_classname', $options)) {
 174              $this->setAjaxHandlerClass($options['ajax_handler_classname']);
 175          }
 176          if (array_key_exists('ajax_handler_bind_to_jquery', $options)) {
 177              $this->setBindAjaxHandlerToJquery($options['ajax_handler_bind_to_jquery']);
 178          }
 179          if (array_key_exists('ajax_handler_auto_show', $options)) {
 180              $this->setAjaxHandlerAutoShow($options['ajax_handler_auto_show']);
 181          }
 182          if (array_key_exists('open_handler_classname', $options)) {
 183              $this->setOpenHandlerClass($options['open_handler_classname']);
 184          }
 185          if (array_key_exists('open_handler_url', $options)) {
 186              $this->setOpenHandlerUrl($options['open_handler_url']);
 187          }
 188          if (array_key_exists('csp_nonce', $options)) {
 189              $this->setCspNonce($options['csp_nonce']);
 190          }
 191      }
 192  
 193      /**
 194       * Sets the path which assets are relative to
 195       *
 196       * @param string $path
 197       */
 198      public function setBasePath($path)
 199      {
 200          $this->basePath = $path;
 201          return $this;
 202      }
 203  
 204      /**
 205       * Returns the path which assets are relative to
 206       *
 207       * @return string
 208       */
 209      public function getBasePath()
 210      {
 211          return $this->basePath;
 212      }
 213  
 214      /**
 215       * Sets the base URL from which assets will be served
 216       *
 217       * @param string $url
 218       */
 219      public function setBaseUrl($url)
 220      {
 221          $this->baseUrl = $url;
 222          return $this;
 223      }
 224  
 225      /**
 226       * Returns the base URL from which assets will be served
 227       *
 228       * @return string
 229       */
 230      public function getBaseUrl()
 231      {
 232          return $this->baseUrl;
 233      }
 234  
 235      /**
 236       * Whether to include vendor assets
 237       *
 238       * You can only include js or css vendors using
 239       * setIncludeVendors('css') or setIncludeVendors('js')
 240       *
 241       * @param boolean $enabled
 242       */
 243      public function setIncludeVendors($enabled = true)
 244      {
 245          if (is_string($enabled)) {
 246              $enabled = array($enabled);
 247          }
 248          $this->includeVendors = $enabled;
 249  
 250          if (!$enabled || (is_array($enabled) && !in_array('js', $enabled))) {
 251              // no need to call jQuery.noConflict() if we do not include our own version
 252              $this->enableJqueryNoConflict = false;
 253          }
 254  
 255          return $this;
 256      }
 257  
 258      /**
 259       * Checks if vendors assets are included
 260       *
 261       * @return boolean
 262       */
 263      public function areVendorsIncluded()
 264      {
 265          return $this->includeVendors !== false;
 266      }
 267  
 268      /**
 269       * Disable a specific vendor's assets.
 270       *
 271       * @param  string $name "jquery", "fontawesome", "highlightjs"
 272       *
 273       * @return void
 274       */
 275      public function disableVendor($name)
 276      {
 277          if (array_key_exists($name, $this->cssVendors)) {
 278              unset($this->cssVendors[$name]);
 279          }
 280          if (array_key_exists($name, $this->jsVendors)) {
 281              unset($this->jsVendors[$name]);
 282          }
 283      }
 284  
 285      /**
 286       * Sets the javascript class name
 287       *
 288       * @param string $className
 289       */
 290      public function setJavascriptClass($className)
 291      {
 292          $this->javascriptClass = $className;
 293          return $this;
 294      }
 295  
 296      /**
 297       * Returns the javascript class name
 298       *
 299       * @return string
 300       */
 301      public function getJavascriptClass()
 302      {
 303          return $this->javascriptClass;
 304      }
 305  
 306      /**
 307       * Sets the variable name of the class instance
 308       *
 309       * @param string $name
 310       */
 311      public function setVariableName($name)
 312      {
 313          $this->variableName = $name;
 314          return $this;
 315      }
 316  
 317      /**
 318       * Returns the variable name of the class instance
 319       *
 320       * @return string
 321       */
 322      public function getVariableName()
 323      {
 324          return $this->variableName;
 325      }
 326  
 327      /**
 328       * Sets what should be initialized
 329       *
 330       *  - INITIALIZE_CONSTRUCTOR: only initializes the instance
 331       *  - INITIALIZE_CONTROLS: initializes the controls and data mapping
 332       *  - INITIALIZE_CONSTRUCTOR | INITIALIZE_CONTROLS: initialize everything (default)
 333       *
 334       * @param integer $init
 335       */
 336      public function setInitialization($init)
 337      {
 338          $this->initialization = $init;
 339          return $this;
 340      }
 341  
 342      /**
 343       * Returns what should be initialized
 344       *
 345       * @return integer
 346       */
 347      public function getInitialization()
 348      {
 349          return $this->initialization;
 350      }
 351  
 352      /**
 353       * Sets whether to call jQuery.noConflict()
 354       *
 355       * @param boolean $enabled
 356       */
 357      public function setEnableJqueryNoConflict($enabled = true)
 358      {
 359          $this->enableJqueryNoConflict = $enabled;
 360          return $this;
 361      }
 362  
 363      /**
 364       * Checks if jQuery.noConflict() will be called
 365       *
 366       * @return boolean
 367       */
 368      public function isJqueryNoConflictEnabled()
 369      {
 370          return $this->enableJqueryNoConflict;
 371      }
 372  
 373      /**
 374       * Sets whether to use RequireJS or not
 375       *
 376       * @param boolean $enabled
 377       * @return $this
 378       */
 379      public function setUseRequireJs($enabled = true)
 380      {
 381          $this->useRequireJs = $enabled;
 382          return $this;
 383      }
 384  
 385      /**
 386       * Checks if RequireJS is used
 387       *
 388       * @return boolean
 389       */
 390      public function isRequireJsUsed()
 391      {
 392          return $this->useRequireJs;
 393      }
 394  
 395      /**
 396       * Adds a control to initialize
 397       *
 398       * Possible options:
 399       *  - icon: icon name
 400       *  - tooltip: string
 401       *  - widget: widget class name
 402       *  - title: tab title
 403       *  - map: a property name from the data to map the control to
 404       *  - default: a js string, default value of the data map
 405       *
 406       * "icon" or "widget" are at least needed
 407       *
 408       * @param string $name
 409       * @param array $options
 410       */
 411      public function addControl($name, array $options)
 412      {
 413          if (count(array_intersect(array_keys($options), array('icon', 'widget', 'tab', 'indicator'))) === 0) {
 414              throw new DebugBarException("Not enough options for control '$name'");
 415          }
 416          $this->controls[$name] = $options;
 417          return $this;
 418      }
 419  
 420      /**
 421       * Disables a control
 422       *
 423       * @param string $name
 424       */
 425      public function disableControl($name)
 426      {
 427          $this->controls[$name] = null;
 428          return $this;
 429      }
 430  
 431      /**
 432       * Returns the list of controls
 433       *
 434       * This does not include controls provided by collectors
 435       *
 436       * @return array
 437       */
 438      public function getControls()
 439      {
 440          return $this->controls;
 441      }
 442  
 443      /**
 444       * Ignores widgets provided by a collector
 445       *
 446       * @param string $name
 447       */
 448      public function ignoreCollector($name)
 449      {
 450          $this->ignoredCollectors[] = $name;
 451          return $this;
 452      }
 453  
 454      /**
 455       * Returns the list of ignored collectors
 456       *
 457       * @return array
 458       */
 459      public function getIgnoredCollectors()
 460      {
 461          return $this->ignoredCollectors;
 462      }
 463  
 464      /**
 465       * Sets the class name of the ajax handler
 466       *
 467       * Set to false to disable
 468       *
 469       * @param string $className
 470       */
 471      public function setAjaxHandlerClass($className)
 472      {
 473          $this->ajaxHandlerClass = $className;
 474          return $this;
 475      }
 476  
 477      /**
 478       * Returns the class name of the ajax handler
 479       *
 480       * @return string
 481       */
 482      public function getAjaxHandlerClass()
 483      {
 484          return $this->ajaxHandlerClass;
 485      }
 486  
 487      /**
 488       * Sets whether to call bindToFetch() on the ajax handler
 489       *
 490       * @param boolean $bind
 491       */
 492      public function setBindAjaxHandlerToFetch($bind = true)
 493      {
 494          $this->ajaxHandlerBindToFetch = $bind;
 495          return $this;
 496      }
 497  
 498      /**
 499       * Checks whether bindToFetch() will be called on the ajax handler
 500       *
 501       * @return boolean
 502       */
 503      public function isAjaxHandlerBoundToFetch()
 504      {
 505          return $this->ajaxHandlerBindToFetch;
 506      }
 507  
 508      /**
 509       * Sets whether to call bindToJquery() on the ajax handler
 510       *
 511       * @param boolean $bind
 512       */
 513      public function setBindAjaxHandlerToJquery($bind = true)
 514      {
 515          $this->ajaxHandlerBindToJquery = $bind;
 516          return $this;
 517      }
 518  
 519      /**
 520       * Checks whether bindToJquery() will be called on the ajax handler
 521       *
 522       * @return boolean
 523       */
 524      public function isAjaxHandlerBoundToJquery()
 525      {
 526          return $this->ajaxHandlerBindToJquery;
 527      }
 528  
 529      /**
 530       * Sets whether to call bindToXHR() on the ajax handler
 531       *
 532       * @param boolean $bind
 533       */
 534      public function setBindAjaxHandlerToXHR($bind = true)
 535      {
 536          $this->ajaxHandlerBindToXHR = $bind;
 537          return $this;
 538      }
 539  
 540      /**
 541       * Checks whether bindToXHR() will be called on the ajax handler
 542       *
 543       * @return boolean
 544       */
 545      public function isAjaxHandlerBoundToXHR()
 546      {
 547          return $this->ajaxHandlerBindToXHR;
 548      }
 549  
 550      /**
 551       * Sets whether new ajax debug data will be immediately shown.  Setting to false could be useful
 552       * if there are a lot of tracking events cluttering things.
 553       *
 554       * @param boolean $autoShow
 555       */
 556      public function setAjaxHandlerAutoShow($autoShow = true)
 557      {
 558          $this->ajaxHandlerAutoShow = $autoShow;
 559          return $this;
 560      }
 561  
 562      /**
 563       * Checks whether the ajax handler will immediately show new ajax requests.
 564       *
 565       * @return boolean
 566       */
 567      public function isAjaxHandlerAutoShow()
 568      {
 569          return $this->ajaxHandlerAutoShow;
 570      }
 571  
 572      /**
 573       * Sets the class name of the js open handler
 574       *
 575       * @param string $className
 576       */
 577      public function setOpenHandlerClass($className)
 578      {
 579          $this->openHandlerClass = $className;
 580          return $this;
 581      }
 582  
 583      /**
 584       * Returns the class name of the js open handler
 585       *
 586       * @return string
 587       */
 588      public function getOpenHandlerClass()
 589      {
 590          return $this->openHandlerClass;
 591      }
 592  
 593      /**
 594       * Sets the url of the open handler
 595       *
 596       * @param string $url
 597       */
 598      public function setOpenHandlerUrl($url)
 599      {
 600          $this->openHandlerUrl = $url;
 601          return $this;
 602      }
 603  
 604      /**
 605       * Returns the url for the open handler
 606       *
 607       * @return string
 608       */
 609      public function getOpenHandlerUrl()
 610      {
 611          return $this->openHandlerUrl;
 612      }
 613  
 614      /**
 615       * Sets the CSP Nonce (or remove it by setting to null)
 616       *
 617       * @param string|null $nonce
 618       * @return $this
 619       */
 620      public function setCspNonce($nonce = null)
 621      {
 622          $this->cspNonce = $nonce;
 623          return $this;
 624      }
 625  
 626      /**
 627       * Get the CSP Nonce
 628       *
 629       * @return string|null
 630       */
 631      public function getCspNonce()
 632      {
 633          return $this->cspNonce;
 634      }
 635  
 636      /**
 637       * Add assets stored in files to render in the head
 638       *
 639       * @param array $cssFiles An array of filenames
 640       * @param array $jsFiles  An array of filenames
 641       * @param string $basePath Base path of those files
 642       * @param string $baseUrl  Base url of those files
 643       * @return $this
 644       */
 645      public function addAssets($cssFiles, $jsFiles, $basePath = null, $baseUrl = null)
 646      {
 647          $this->additionalAssets[] = array(
 648              'base_path' => $basePath,
 649              'base_url' => $baseUrl,
 650              'css' => (array) $cssFiles,
 651              'js' => (array) $jsFiles
 652          );
 653          return $this;
 654      }
 655  
 656      /**
 657       * Add inline assets to render inline in the head.  Ideally, you should store static assets in
 658       * files that you add with the addAssets function.  However, adding inline assets is useful when
 659       * integrating with 3rd-party libraries that require static assets that are only available in an
 660       * inline format.
 661       *
 662       * The inline content arrays require special string array keys:  they are used to deduplicate
 663       * content.  This is particularly useful if multiple instances of the same asset end up being
 664       * added.  Inline assets from all collectors are merged together into the same array, so these
 665       * content IDs effectively deduplicate the inline assets.
 666       *
 667       * @param array $inlineCss  An array map of content ID to inline CSS content (not including <style> tag)
 668       * @param array $inlineJs   An array map of content ID to inline JS content (not including <script> tag)
 669       * @param array $inlineHead An array map of content ID to arbitrary inline HTML content (typically
 670       *                          <style>/<script> tags); it must be embedded within the <head> element
 671       * @return $this
 672       */
 673      public function addInlineAssets($inlineCss, $inlineJs, $inlineHead)
 674      {
 675          $this->additionalAssets[] = array(
 676              'inline_css' => (array) $inlineCss,
 677              'inline_js' => (array) $inlineJs,
 678              'inline_head' => (array) $inlineHead
 679          );
 680          return $this;
 681      }
 682  
 683      /**
 684       * Returns the list of asset files
 685       *
 686       * @param string $type 'css', 'js', 'inline_css', 'inline_js', 'inline_head', or null for all
 687       * @param string $relativeTo The type of path to which filenames must be relative (path, url or null)
 688       * @return array
 689       */
 690      public function getAssets($type = null, $relativeTo = self::RELATIVE_PATH)
 691      {
 692          $cssFiles = $this->cssFiles;
 693          $jsFiles = $this->jsFiles;
 694          $inlineCss = array();
 695          $inlineJs = array();
 696          $inlineHead = array();
 697  
 698          if ($this->includeVendors !== false) {
 699              if ($this->includeVendors === true || in_array('css', $this->includeVendors)) {
 700                  $cssFiles = array_merge($this->cssVendors, $cssFiles);
 701              }
 702              if ($this->includeVendors === true || in_array('js', $this->includeVendors)) {
 703                  $jsFiles = array_merge($this->jsVendors, $jsFiles);
 704              }
 705          }
 706  
 707          if ($relativeTo) {
 708              $root = $this->getRelativeRoot($relativeTo, $this->basePath, $this->baseUrl);
 709              $cssFiles = $this->makeUriRelativeTo($cssFiles, $root);
 710              $jsFiles = $this->makeUriRelativeTo($jsFiles, $root);
 711          }
 712  
 713          $additionalAssets = $this->additionalAssets;
 714          // finds assets provided by collectors
 715          foreach ($this->debugBar->getCollectors() as $collector) {
 716              if (($collector instanceof AssetProvider) && !in_array($collector->getName(), $this->ignoredCollectors)) {
 717                  $additionalAssets[] = $collector->getAssets();
 718              }
 719          }
 720  
 721          foreach ($additionalAssets as $assets) {
 722              $basePath = isset($assets['base_path']) ? $assets['base_path'] : '';
 723              $baseUrl = isset($assets['base_url']) ? $assets['base_url'] : '';
 724              $root = $this->getRelativeRoot($relativeTo,
 725                  $this->makeUriRelativeTo($basePath, $this->basePath),
 726                  $this->makeUriRelativeTo($baseUrl, $this->baseUrl));
 727              if (isset($assets['css'])) {
 728                  $cssFiles = array_merge($cssFiles, $this->makeUriRelativeTo((array) $assets['css'], $root));
 729              }
 730              if (isset($assets['js'])) {
 731                  $jsFiles = array_merge($jsFiles, $this->makeUriRelativeTo((array) $assets['js'], $root));
 732              }
 733  
 734              if (isset($assets['inline_css'])) {
 735                  $inlineCss = array_merge($inlineCss, (array) $assets['inline_css']);
 736              }
 737              if (isset($assets['inline_js'])) {
 738                  $inlineJs = array_merge($inlineJs, (array) $assets['inline_js']);
 739              }
 740              if (isset($assets['inline_head'])) {
 741                  $inlineHead = array_merge($inlineHead, (array) $assets['inline_head']);
 742              }
 743          }
 744  
 745          // Deduplicate files
 746          $cssFiles = array_unique($cssFiles);
 747          $jsFiles = array_unique($jsFiles);
 748  
 749          return $this->filterAssetArray(array($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead), $type ?? '');
 750      }
 751  
 752      /**
 753       * Returns the correct base according to the type
 754       *
 755       * @param string $relativeTo
 756       * @param string $basePath
 757       * @param string $baseUrl
 758       * @return string
 759       */
 760      protected function getRelativeRoot($relativeTo, $basePath, $baseUrl)
 761      {
 762          if ($relativeTo === self::RELATIVE_PATH) {
 763              return $basePath;
 764          }
 765          if ($relativeTo === self::RELATIVE_URL) {
 766              return $baseUrl;
 767          }
 768          return null;
 769      }
 770  
 771      /**
 772       * Makes a URI relative to another
 773       *
 774       * @param string|array $uri
 775       * @param string $root
 776       * @return string
 777       */
 778      protected function makeUriRelativeTo($uri, $root)
 779      {
 780          if (!$root) {
 781              return $uri;
 782          }
 783  
 784          if (is_array($uri)) {
 785              $uris = array();
 786              foreach ($uri as $u) {
 787                  $uris[] = $this->makeUriRelativeTo($u, $root);
 788              }
 789              return $uris;
 790          }
 791  
 792          $uri = $uri ?? '';
 793  
 794          if (substr($uri, 0, 1) === '/' || preg_match('/^([a-zA-Z]+:\/\/|[a-zA-Z]:\/|[a-zA-Z]:\\\)/', $uri)) {
 795              return $uri;
 796          }
 797          return rtrim($root, '/') . "/$uri";
 798      }
 799  
 800      /**
 801       * Filters a tuple of (css, js, inline_css, inline_js, inline_head) assets according to $type
 802       *
 803       * @param array $array
 804       * @param string $type 'css', 'js', 'inline_css', 'inline_js', 'inline_head', or null for all
 805       * @return array
 806       */
 807      protected function filterAssetArray($array, $type = '')
 808      {
 809          $types = array('css', 'js', 'inline_css', 'inline_js', 'inline_head');
 810          $typeIndex = array_search(strtolower($type ?? ''), $types);
 811          return $typeIndex !== false ? $array[$typeIndex] : $array;
 812      }
 813  
 814      /**
 815       * Returns an array where all items are Assetic AssetCollection:
 816       *  - The first one contains the CSS files
 817       *  - The second one contains the JS files
 818       *  - The third one contains arbitrary inline HTML (typically composed of <script>/<style>
 819       *    elements); it must be embedded within the <head> element
 820       *
 821       * @param string $type Optionally return only 'css', 'js', or 'inline_head' collection
 822       * @return array|\Assetic\Asset\AssetCollection
 823       */
 824      public function getAsseticCollection($type = null)
 825      {
 826          $types = array('css', 'js', 'inline_head');
 827          $typeIndex = array_search(strtolower($type), $types);
 828  
 829          list($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead) = $this->getAssets();
 830          $collections = array(
 831              $this->createAsseticCollection($cssFiles, $inlineCss),
 832              $this->createAsseticCollection($jsFiles, $inlineJs),
 833              $this->createAsseticCollection(null, $inlineHead)
 834          );
 835          return $typeIndex !== false ? $collections[$typeIndex] : $collections;
 836      }
 837  
 838      /**
 839       * Create an Assetic AssetCollection with the given content.
 840       * Filenames will be converted to absolute path using
 841       * the base path.
 842       *
 843       * @param array|null $files Array of asset filenames.
 844       * @param array|null $content Array of inline asset content.
 845       * @return \Assetic\Asset\AssetCollection
 846       */
 847      protected function createAsseticCollection($files = null, $content = null)
 848      {
 849          $assets = array();
 850          if ($files) {
 851              foreach ($files as $file) {
 852                  $assets[] = new \Assetic\Asset\FileAsset($file);
 853              }
 854          }
 855          if ($content) {
 856              foreach ($content as $item) {
 857                  $assets[] = new \Assetic\Asset\StringAsset($item);
 858              }
 859          }
 860          return new \Assetic\Asset\AssetCollection($assets);
 861      }
 862  
 863      /**
 864       * Write all CSS assets to standard output or in a file
 865       *
 866       * @param string $targetFilename
 867       */
 868      public function dumpCssAssets($targetFilename = null)
 869      {
 870          $this->dumpAssets($this->getAssets('css'), $this->getAssets('inline_css'), $targetFilename);
 871      }
 872  
 873      /**
 874       * Write all JS assets to standard output or in a file
 875       *
 876       * @param string $targetFilename
 877       */
 878      public function dumpJsAssets($targetFilename = null)
 879      {
 880          $this->dumpAssets($this->getAssets('js'), $this->getAssets('inline_js'), $targetFilename, $this->useRequireJs);
 881      }
 882  
 883      /**
 884       * Write all inline HTML header assets to standard output or in a file (only returns assets not
 885       * already returned by dumpCssAssets or dumpJsAssets)
 886       *
 887       * @param string $targetFilename
 888       */
 889      public function dumpHeadAssets($targetFilename = null)
 890      {
 891          $this->dumpAssets(null, $this->getAssets('inline_head'), $targetFilename);
 892      }
 893  
 894      /**
 895       * Write assets to standard output or in a file
 896       *
 897       * @param array|null $files Filenames containing assets
 898       * @param array|null $content Inline content to dump
 899       * @param string $targetFilename
 900       * @param bool $useRequireJs
 901       */
 902      protected function dumpAssets($files = null, $content = null, $targetFilename = null, $useRequireJs = false)
 903      {
 904          $dumpedContent = '';
 905          if ($files) {
 906              foreach ($files as $file) {
 907                  $dumpedContent .= file_get_contents($file) . "\n";
 908              }
 909          }
 910          if ($content) {
 911              foreach ($content as $item) {
 912                  $dumpedContent .= $item . "\n";
 913              }
 914          }
 915          if ($useRequireJs) {
 916              $dumpedContent = "define('debugbar', ['jquery'], function($){\r\n" . $dumpedContent . "\r\n return PhpDebugBar; \r\n});";
 917          }
 918          if ($targetFilename !== null) {
 919              file_put_contents($targetFilename, $dumpedContent);
 920          } else {
 921              echo $dumpedContent;
 922          }
 923      }
 924  
 925      /**
 926       * Renders the html to include needed assets
 927       *
 928       * Only useful if Assetic is not used
 929       *
 930       * @return string
 931       */
 932      public function renderHead()
 933      {
 934          list($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead) = $this->getAssets(null, self::RELATIVE_URL);
 935          $html = '';
 936  
 937          $nonce = $this->getNonceAttribute();
 938  
 939          foreach ($cssFiles as $file) {
 940              $html .= sprintf('<link rel="stylesheet" type="text/css" href="%s">' . "\n", $file);
 941          }
 942  
 943          foreach ($inlineCss as $content) {
 944              $html .= sprintf('<style type="text/css">%s</style>' . "\n", $content);
 945          }
 946  
 947          foreach ($jsFiles as $file) {
 948              $html .= sprintf('<script type="text/javascript" src="%s"></script>' . "\n", $file);
 949          }
 950  
 951          foreach ($inlineJs as $content) {
 952              $html .= sprintf('<script type="text/javascript"%s>%s</script>' . "\n", $nonce, $content);
 953          }
 954  
 955          foreach ($inlineHead as $content) {
 956              $html .= $content . "\n";
 957          }
 958  
 959          if ($this->enableJqueryNoConflict && !$this->useRequireJs) {
 960              $html .= '<script type="text/javascript"' . $nonce . '>jQuery.noConflict(true);</script>' . "\n";
 961          }
 962  
 963          return $html;
 964      }
 965  
 966      /**
 967       * Register shutdown to display the debug bar
 968       *
 969       * @param boolean $here Set position of HTML. True if is to current position or false for end file
 970       * @param boolean $initialize Whether to render the de bug bar initialization code
 971       * @param bool $renderStackedData
 972       * @param bool $head
 973       * @return string Return "{--DEBUGBAR_OB_START_REPLACE_ME--}" or return an empty string if $here == false
 974       */
 975      public function renderOnShutdown($here = true, $initialize = true, $renderStackedData = true, $head = false)
 976      {
 977          register_shutdown_function(array($this, "replaceTagInBuffer"), $here, $initialize, $renderStackedData, $head);
 978  
 979          if (ob_get_level() === 0) {
 980              ob_start();
 981          }
 982  
 983          return ($here) ? self::REPLACEABLE_TAG : "";
 984      }
 985  
 986      /**
 987       * Same as renderOnShutdown() with $head = true
 988       *
 989       * @param boolean $here
 990       * @param boolean $initialize
 991       * @param boolean $renderStackedData
 992       * @return string
 993       */
 994      public function renderOnShutdownWithHead($here = true, $initialize = true, $renderStackedData = true)
 995      {
 996          return $this->renderOnShutdown($here, $initialize, $renderStackedData, true);
 997      }
 998  
 999      /**
1000       * Is callback function for register_shutdown_function(...)
1001       *
1002       * @param boolean $here Set position of HTML. True if is to current position or false for end file
1003       * @param boolean $initialize Whether to render the de bug bar initialization code
1004       * @param bool $renderStackedData
1005       * @param bool $head
1006       */
1007      public function replaceTagInBuffer($here = true, $initialize = true, $renderStackedData = true, $head = false)
1008      {
1009          $render = ($head ? $this->renderHead() : "")
1010                  . $this->render($initialize, $renderStackedData);
1011  
1012          $current = ($here && ob_get_level() > 0) ? ob_get_clean() : self::REPLACEABLE_TAG;
1013  
1014          echo str_replace(self::REPLACEABLE_TAG, $render, $current, $count);
1015  
1016          if ($count === 0) {
1017              echo $render;
1018          }
1019      }
1020  
1021      /**
1022       * Returns the code needed to display the debug bar
1023       *
1024       * AJAX request should not render the initialization code.
1025       *
1026       * @param boolean $initialize Whether or not to render the debug bar initialization code
1027       * @param boolean $renderStackedData Whether or not to render the stacked data
1028       * @return string
1029       */
1030      public function render($initialize = true, $renderStackedData = true)
1031      {
1032          $js = '';
1033  
1034          if ($initialize) {
1035              $js = $this->getJsInitializationCode();
1036          }
1037  
1038          if ($renderStackedData && $this->debugBar->hasStackedData()) {
1039              foreach ($this->debugBar->getStackedData() as $id => $data) {
1040                  $js .= $this->getAddDatasetCode($id, $data, '(stacked)');
1041              }
1042          }
1043  
1044          $suffix = !$initialize ? '(ajax)' : null;
1045          $js .= $this->getAddDatasetCode($this->debugBar->getCurrentRequestId(), $this->debugBar->getData(), $suffix);
1046  
1047          $nonce = $this->getNonceAttribute();
1048  
1049          if ($this->useRequireJs){
1050              return "<script type=\"text/javascript\"{$nonce}>\nrequire(['debugbar'], function(PhpDebugBar){ $js });\n</script>\n";
1051          } else {
1052              return "<script type=\"text/javascript\"{$nonce}>\n$js\n</script>\n";
1053          }
1054  
1055      }
1056  
1057      /**
1058       * Returns the js code needed to initialize the debug bar
1059       *
1060       * @return string
1061       */
1062      protected function getJsInitializationCode()
1063      {
1064          $js = '';
1065  
1066          if (($this->initialization & self::INITIALIZE_CONSTRUCTOR) === self::INITIALIZE_CONSTRUCTOR) {
1067              $js .= sprintf("var %s = new %s();\n", $this->variableName, $this->javascriptClass);
1068          }
1069  
1070          if (($this->initialization & self::INITIALIZE_CONTROLS) === self::INITIALIZE_CONTROLS) {
1071              $js .= $this->getJsControlsDefinitionCode($this->variableName);
1072          }
1073  
1074          if ($this->ajaxHandlerClass) {
1075              $js .= sprintf("%s.ajaxHandler = new %s(%s, undefined, %s);\n",
1076                  $this->variableName,
1077                  $this->ajaxHandlerClass,
1078                  $this->variableName,
1079                  $this->ajaxHandlerAutoShow ? 'true' : 'false'
1080              );
1081              if ($this->ajaxHandlerBindToFetch) {
1082                  $js .= sprintf("%s.ajaxHandler.bindToFetch();\n", $this->variableName);
1083              }
1084              if ($this->ajaxHandlerBindToXHR) {
1085                  $js .= sprintf("%s.ajaxHandler.bindToXHR();\n", $this->variableName);
1086              } elseif ($this->ajaxHandlerBindToJquery) {
1087                  $js .= sprintf("if (jQuery) %s.ajaxHandler.bindToJquery(jQuery);\n", $this->variableName);
1088              }
1089          }
1090  
1091          if ($this->openHandlerUrl !== null) {
1092              $js .= sprintf("%s.setOpenHandler(new %s(%s));\n", $this->variableName,
1093                  $this->openHandlerClass,
1094                  json_encode(array("url" => $this->openHandlerUrl)));
1095          }
1096  
1097          return $js;
1098      }
1099  
1100      /**
1101       * Returns the js code needed to initialized the controls and data mapping of the debug bar
1102       *
1103       * Controls can be defined by collectors themselves or using {@see addControl()}
1104       *
1105       * @param string $varname Debug bar's variable name
1106       * @return string
1107       */
1108      protected function getJsControlsDefinitionCode($varname)
1109      {
1110          $js = '';
1111          $dataMap = array();
1112          $excludedOptions = array('indicator', 'tab', 'map', 'default', 'widget', 'position');
1113  
1114          // finds controls provided by collectors
1115          $widgets = array();
1116          foreach ($this->debugBar->getCollectors() as $collector) {
1117              if (($collector instanceof Renderable) && !in_array($collector->getName(), $this->ignoredCollectors)) {
1118                  if ($w = $collector->getWidgets()) {
1119                      $widgets = array_merge($widgets, $w);
1120                  }
1121              }
1122          }
1123          $controls = array_merge($widgets, $this->controls);
1124  
1125          foreach (array_filter($controls) as $name => $options) {
1126              $opts = array_diff_key($options, array_flip($excludedOptions));
1127  
1128              if (isset($options['tab']) || isset($options['widget'])) {
1129                  if (!isset($opts['title'])) {
1130                      $opts['title'] = ucfirst(str_replace('_', ' ', $name));
1131                  }
1132                  $js .= sprintf("%s.addTab(\"%s\", new %s({%s%s}));\n",
1133                      $varname,
1134                      $name,
1135                      isset($options['tab']) ? $options['tab'] : 'PhpDebugBar.DebugBar.Tab',
1136                      substr(json_encode($opts, JSON_FORCE_OBJECT), 1, -1),
1137                      isset($options['widget']) ? sprintf('%s"widget": new %s()', count($opts) ? ', ' : '', $options['widget']) : ''
1138                  );
1139              } elseif (isset($options['indicator']) || isset($options['icon'])) {
1140                  $js .= sprintf("%s.addIndicator(\"%s\", new %s(%s), \"%s\");\n",
1141                      $varname,
1142                      $name,
1143                      isset($options['indicator']) ? $options['indicator'] : 'PhpDebugBar.DebugBar.Indicator',
1144                      json_encode($opts, JSON_FORCE_OBJECT),
1145                      isset($options['position']) ? $options['position'] : 'right'
1146                  );
1147              }
1148  
1149              if (isset($options['map']) && isset($options['default'])) {
1150                  $dataMap[$name] = array($options['map'], $options['default']);
1151              }
1152          }
1153  
1154          // creates the data mapping object
1155          $mapJson = array();
1156          foreach ($dataMap as $name => $values) {
1157              $mapJson[] = sprintf('"%s": ["%s", %s]', $name, $values[0], $values[1]);
1158          }
1159          $js .= sprintf("%s.setDataMap({\n%s\n});\n", $varname, implode(",\n", $mapJson));
1160  
1161          // activate state restoration
1162          $js .= sprintf("%s.restoreState();\n", $varname);
1163  
1164          return $js;
1165      }
1166  
1167      /**
1168       * Returns the js code needed to add a dataset
1169       *
1170       * @param string $requestId
1171       * @param array $data
1172       * @param mixed $suffix
1173       * @return string
1174       */
1175      protected function getAddDatasetCode($requestId, $data, $suffix = null)
1176      {
1177          $js = sprintf("%s.addDataSet(%s, \"%s\"%s);\n",
1178              $this->variableName,
1179              json_encode($data),
1180              $requestId,
1181              $suffix ? ", " . json_encode($suffix) : ''
1182          );
1183          return $js;
1184      }
1185  
1186      /**
1187       * If a nonce it set, create the correct attribute
1188       * @return string
1189       */
1190      protected function getNonceAttribute()
1191      {
1192          if ($nonce = $this->getCspNonce()) {
1193              return ' nonce="' . $nonce .'"';
1194          }
1195  
1196          return '';
1197      }
1198  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer