[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/maximebf/debugbar/src/DebugBar/ -> DebugBar.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 ArrayAccess;
  14  use DebugBar\DataCollector\DataCollectorInterface;
  15  use DebugBar\Storage\StorageInterface;
  16  
  17  /**
  18   * Main DebugBar object
  19   *
  20   * Manages data collectors. DebugBar provides an array-like access
  21   * to collectors by name.
  22   *
  23   * <code>
  24   *     $debugbar = new DebugBar();
  25   *     $debugbar->addCollector(new DataCollector\MessagesCollector());
  26   *     $debugbar['messages']->addMessage("foobar");
  27   * </code>
  28   */
  29  class DebugBar implements ArrayAccess
  30  {
  31      public static $useOpenHandlerWhenSendingDataHeaders = false;
  32  
  33      protected $collectors = array();
  34  
  35      protected $data;
  36  
  37      protected $jsRenderer;
  38  
  39      protected $requestIdGenerator;
  40  
  41      protected $requestId;
  42  
  43      protected $storage;
  44  
  45      protected $httpDriver;
  46  
  47      protected $stackSessionNamespace = 'PHPDEBUGBAR_STACK_DATA';
  48  
  49      protected $stackAlwaysUseSessionStorage = false;
  50  
  51      /**
  52       * Adds a data collector
  53       *
  54       * @param DataCollectorInterface $collector
  55       *
  56       * @throws DebugBarException
  57       * @return $this
  58       */
  59      public function addCollector(DataCollectorInterface $collector)
  60      {
  61          if ($collector->getName() === '__meta') {
  62              throw new DebugBarException("'__meta' is a reserved name and cannot be used as a collector name");
  63          }
  64          if (isset($this->collectors[$collector->getName()])) {
  65              throw new DebugBarException("'{$collector->getName()}' is already a registered collector");
  66          }
  67          $this->collectors[$collector->getName()] = $collector;
  68          return $this;
  69      }
  70  
  71      /**
  72       * Checks if a data collector has been added
  73       *
  74       * @param string $name
  75       * @return boolean
  76       */
  77      public function hasCollector($name)
  78      {
  79          return isset($this->collectors[$name]);
  80      }
  81  
  82      /**
  83       * Returns a data collector
  84       *
  85       * @param string $name
  86       * @return DataCollectorInterface
  87       * @throws DebugBarException
  88       */
  89      public function getCollector($name)
  90      {
  91          if (!isset($this->collectors[$name])) {
  92              throw new DebugBarException("'$name' is not a registered collector");
  93          }
  94          return $this->collectors[$name];
  95      }
  96  
  97      /**
  98       * Returns an array of all data collectors
  99       *
 100       * @return array[DataCollectorInterface]
 101       */
 102      public function getCollectors()
 103      {
 104          return $this->collectors;
 105      }
 106  
 107      /**
 108       * Sets the request id generator
 109       *
 110       * @param RequestIdGeneratorInterface $generator
 111       * @return $this
 112       */
 113      public function setRequestIdGenerator(RequestIdGeneratorInterface $generator)
 114      {
 115          $this->requestIdGenerator = $generator;
 116          return $this;
 117      }
 118  
 119      /**
 120       * @return RequestIdGeneratorInterface
 121       */
 122      public function getRequestIdGenerator()
 123      {
 124          if ($this->requestIdGenerator === null) {
 125              $this->requestIdGenerator = new RequestIdGenerator();
 126          }
 127          return $this->requestIdGenerator;
 128      }
 129  
 130      /**
 131       * Returns the id of the current request
 132       *
 133       * @return string
 134       */
 135      public function getCurrentRequestId()
 136      {
 137          if ($this->requestId === null) {
 138              $this->requestId = $this->getRequestIdGenerator()->generate();
 139          }
 140          return $this->requestId;
 141      }
 142  
 143      /**
 144       * Sets the storage backend to use to store the collected data
 145       *
 146       * @param StorageInterface $storage
 147       * @return $this
 148       */
 149      public function setStorage(StorageInterface $storage = null)
 150      {
 151          $this->storage = $storage;
 152          return $this;
 153      }
 154  
 155      /**
 156       * @return StorageInterface
 157       */
 158      public function getStorage()
 159      {
 160          return $this->storage;
 161      }
 162  
 163      /**
 164       * Checks if the data will be persisted
 165       *
 166       * @return boolean
 167       */
 168      public function isDataPersisted()
 169      {
 170          return $this->storage !== null;
 171      }
 172  
 173      /**
 174       * Sets the HTTP driver
 175       *
 176       * @param HttpDriverInterface $driver
 177       * @return $this
 178       */
 179      public function setHttpDriver(HttpDriverInterface $driver)
 180      {
 181          $this->httpDriver = $driver;
 182          return $this;
 183      }
 184  
 185      /**
 186       * Returns the HTTP driver
 187       *
 188       * If no http driver where defined, a PhpHttpDriver is automatically created
 189       *
 190       * @return HttpDriverInterface
 191       */
 192      public function getHttpDriver()
 193      {
 194          if ($this->httpDriver === null) {
 195              $this->httpDriver = new PhpHttpDriver();
 196          }
 197          return $this->httpDriver;
 198      }
 199  
 200      /**
 201       * Collects the data from the collectors
 202       *
 203       * @return array
 204       */
 205      public function collect()
 206      {
 207          if (php_sapi_name() === 'cli') {
 208              $ip = gethostname();
 209              if ($ip) {
 210                  $ip = gethostbyname($ip);
 211              } else {
 212                  $ip = '127.0.0.1';
 213              }
 214              $request_variables = array(
 215                  'method' => 'CLI',
 216                  'uri' => isset($_SERVER['SCRIPT_FILENAME']) ? realpath($_SERVER['SCRIPT_FILENAME']) : null,
 217                  'ip' => $ip
 218              );
 219          } else {
 220              $request_variables = array(
 221                  'method' => isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : null,
 222                  'uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : null,
 223                  'ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null
 224              );
 225          }
 226          $this->data = array(
 227              '__meta' => array_merge(
 228                  array(
 229                      'id' => $this->getCurrentRequestId(),
 230                      'datetime' => date('Y-m-d H:i:s'),
 231                      'utime' => microtime(true)
 232                  ),
 233                  $request_variables
 234              )
 235          );
 236  
 237          foreach ($this->collectors as $name => $collector) {
 238              $this->data[$name] = $collector->collect();
 239          }
 240  
 241          // Remove all invalid (non UTF-8) characters
 242          array_walk_recursive($this->data, function (&$item) {
 243                  if (is_string($item) && !mb_check_encoding($item, 'UTF-8')) {
 244                      $item = mb_convert_encoding($item, 'UTF-8', 'UTF-8');
 245                  }
 246              });
 247  
 248          if ($this->storage !== null) {
 249              $this->storage->save($this->getCurrentRequestId(), $this->data);
 250          }
 251  
 252          return $this->data;
 253      }
 254  
 255      /**
 256       * Returns collected data
 257       *
 258       * Will collect the data if none have been collected yet
 259       *
 260       * @return array
 261       */
 262      public function getData()
 263      {
 264          if ($this->data === null) {
 265              $this->collect();
 266          }
 267          return $this->data;
 268      }
 269  
 270      /**
 271       * Returns an array of HTTP headers containing the data
 272       *
 273       * @param string $headerName
 274       * @param integer $maxHeaderLength
 275       * @return array
 276       */
 277      public function getDataAsHeaders($headerName = 'phpdebugbar', $maxHeaderLength = 4096, $maxTotalHeaderLength = 250000)
 278      {
 279          $data = rawurlencode(json_encode(array(
 280              'id' => $this->getCurrentRequestId(),
 281              'data' => $this->getData()
 282          )));
 283  
 284          if (strlen($data) > $maxTotalHeaderLength) {
 285              $data = rawurlencode(json_encode(array(
 286                  'error' => 'Maximum header size exceeded'
 287              )));
 288          }
 289  
 290          $chunks = array();
 291  
 292          while (strlen($data) > $maxHeaderLength) {
 293              $chunks[] = substr($data, 0, $maxHeaderLength);
 294              $data = substr($data, $maxHeaderLength);
 295          }
 296          $chunks[] = $data;
 297  
 298          $headers = array();
 299          for ($i = 0, $c = count($chunks); $i < $c; $i++) {
 300              $name = $headerName . ($i > 0 ? "-$i" : '');
 301              $headers[$name] = $chunks[$i];
 302          }
 303  
 304          return $headers;
 305      }
 306  
 307      /**
 308       * Sends the data through the HTTP headers
 309       *
 310       * @param bool $useOpenHandler
 311       * @param string $headerName
 312       * @param integer $maxHeaderLength
 313       * @return $this
 314       */
 315      public function sendDataInHeaders($useOpenHandler = null, $headerName = 'phpdebugbar', $maxHeaderLength = 4096)
 316      {
 317          if ($useOpenHandler === null) {
 318              $useOpenHandler = self::$useOpenHandlerWhenSendingDataHeaders;
 319          }
 320          if ($useOpenHandler && $this->storage !== null) {
 321              $this->getData();
 322              $headerName .= '-id';
 323              $headers = array($headerName => $this->getCurrentRequestId());
 324          } else {
 325              $headers = $this->getDataAsHeaders($headerName, $maxHeaderLength);
 326          }
 327          $this->getHttpDriver()->setHeaders($headers);
 328          return $this;
 329      }
 330  
 331      /**
 332       * Stacks the data in the session for later rendering
 333       */
 334      public function stackData()
 335      {
 336          $http = $this->initStackSession();
 337  
 338          $data = null;
 339          if (!$this->isDataPersisted() || $this->stackAlwaysUseSessionStorage) {
 340              $data = $this->getData();
 341          } elseif ($this->data === null) {
 342              $this->collect();
 343          }
 344  
 345          $stack = $http->getSessionValue($this->stackSessionNamespace);
 346          $stack[$this->getCurrentRequestId()] = $data;
 347          $http->setSessionValue($this->stackSessionNamespace, $stack);
 348          return $this;
 349      }
 350  
 351      /**
 352       * Checks if there is stacked data in the session
 353       *
 354       * @return boolean
 355       */
 356      public function hasStackedData()
 357      {
 358          try {
 359              $http = $this->initStackSession();
 360          } catch (DebugBarException $e) {
 361              return false;
 362          }
 363          return count($http->getSessionValue($this->stackSessionNamespace)) > 0;
 364      }
 365  
 366      /**
 367       * Returns the data stacked in the session
 368       *
 369       * @param boolean $delete Whether to delete the data in the session
 370       * @return array
 371       */
 372      public function getStackedData($delete = true)
 373      {
 374          $http = $this->initStackSession();
 375          $stackedData = $http->getSessionValue($this->stackSessionNamespace);
 376          if ($delete) {
 377              $http->deleteSessionValue($this->stackSessionNamespace);
 378          }
 379  
 380          $datasets = array();
 381          if ($this->isDataPersisted() && !$this->stackAlwaysUseSessionStorage) {
 382              foreach ($stackedData as $id => $data) {
 383                  $datasets[$id] = $this->getStorage()->get($id);
 384              }
 385          } else {
 386              $datasets = $stackedData;
 387          }
 388  
 389          return $datasets;
 390      }
 391  
 392      /**
 393       * Sets the key to use in the $_SESSION array
 394       *
 395       * @param string $ns
 396       * @return $this
 397       */
 398      public function setStackDataSessionNamespace($ns)
 399      {
 400          $this->stackSessionNamespace = $ns;
 401          return $this;
 402      }
 403  
 404      /**
 405       * Returns the key used in the $_SESSION array
 406       *
 407       * @return string
 408       */
 409      public function getStackDataSessionNamespace()
 410      {
 411          return $this->stackSessionNamespace;
 412      }
 413  
 414      /**
 415       * Sets whether to only use the session to store stacked data even
 416       * if a storage is enabled
 417       *
 418       * @param boolean $enabled
 419       * @return $this
 420       */
 421      public function setStackAlwaysUseSessionStorage($enabled = true)
 422      {
 423          $this->stackAlwaysUseSessionStorage = $enabled;
 424          return $this;
 425      }
 426  
 427      /**
 428       * Checks if the session is always used to store stacked data
 429       * even if a storage is enabled
 430       *
 431       * @return boolean
 432       */
 433      public function isStackAlwaysUseSessionStorage()
 434      {
 435          return $this->stackAlwaysUseSessionStorage;
 436      }
 437  
 438      /**
 439       * Initializes the session for stacked data
 440       * @return HttpDriverInterface
 441       * @throws DebugBarException
 442       */
 443      protected function initStackSession()
 444      {
 445          $http = $this->getHttpDriver();
 446          if (!$http->isSessionStarted()) {
 447              throw new DebugBarException("Session must be started before using stack data in the debug bar");
 448          }
 449  
 450          if (!$http->hasSessionValue($this->stackSessionNamespace)) {
 451              $http->setSessionValue($this->stackSessionNamespace, array());
 452          }
 453  
 454          return $http;
 455      }
 456  
 457      /**
 458       * Returns a JavascriptRenderer for this instance
 459       * @param string $baseUrl
 460       * @param string $basePath
 461       * @return JavascriptRenderer
 462       */
 463      public function getJavascriptRenderer($baseUrl = null, $basePath = null)
 464      {
 465          if ($this->jsRenderer === null) {
 466              $this->jsRenderer = new JavascriptRenderer($this, $baseUrl, $basePath);
 467          }
 468          return $this->jsRenderer;
 469      }
 470  
 471      // --------------------------------------------
 472      // ArrayAccess implementation
 473  
 474      #[\ReturnTypeWillChange]
 475      public function offsetSet($key, $value)
 476      {
 477          throw new DebugBarException("DebugBar[] is read-only");
 478      }
 479  
 480      #[\ReturnTypeWillChange]
 481      public function offsetGet($key)
 482      {
 483          return $this->getCollector($key);
 484      }
 485  
 486      #[\ReturnTypeWillChange]
 487      public function offsetExists($key)
 488      {
 489          return $this->hasCollector($key);
 490      }
 491  
 492      #[\ReturnTypeWillChange]
 493      public function offsetUnset($key)
 494      {
 495          throw new DebugBarException("DebugBar[] is read-only");
 496      }
 497  }


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