You are here

class XHProfEventSubscriber in XHProf 8

Provides handling of start/stop for profiler.

Hierarchy

  • class \Drupal\xhprof\EventSubscriber\XHProfEventSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface

Expanded class hierarchy of XHProfEventSubscriber

1 string reference to 'XHProfEventSubscriber'
xhprof.services.yml in ./xhprof.services.yml
xhprof.services.yml
1 service uses XHProfEventSubscriber
xhprof.xhprof_event_subscriber in ./xhprof.services.yml
Drupal\xhprof\EventSubscriber\XHProfEventSubscriber

File

src/EventSubscriber/XHProfEventSubscriber.php, line 17

Namespace

Drupal\xhprof\EventSubscriber
View source
class XHProfEventSubscriber implements EventSubscriberInterface {

  /**
   * The profiler.
   *
   * @var \Drupal\xhprof\ProfilerInterface
   */
  public $profiler;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  private $currentUser;

  /**
   * The profiling run ID.
   *
   * @var string
   */
  private $xhprofRunId;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  private $moduleHandler;

  /**
   * Constructs XHProfEventSubscriber object.
   *
   * @param \Drupal\xhprof\ProfilerInterface $profiler
   *   The profiler.
   * @param \Drupal\Core\Session\AccountInterface $currentUser
   *   The current user.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   */
  public function __construct(ProfilerInterface $profiler, AccountInterface $currentUser, ModuleHandlerInterface $module_handler) {
    $this->profiler = $profiler;
    $this->currentUser = $currentUser;
    $this->moduleHandler = $module_handler;
  }

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    return [
      KernelEvents::REQUEST => [
        'onKernelRequest',
        0,
      ],
      KernelEvents::RESPONSE => [
        'onKernelResponse',
        0,
      ],
      KernelEvents::TERMINATE => [
        'onKernelTerminate',
        0,
      ],
    ];
  }

  /**
   * Enables profiling if allowed.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   *   The event.
   */
  public function onKernelRequest(GetResponseEvent $event) {
    if ($this->profiler
      ->canEnable($event
      ->getRequest())) {
      $this->profiler
        ->enable();
    }
  }

  /**
   * Renders link to the finished run.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The event.
   */
  public function onKernelResponse(FilterResponseEvent $event) {
    if ($this->profiler
      ->isEnabled()) {
      $this->xhprofRunId = $this->profiler
        ->createRunId();

      // Don't print the link to xhprof run page if
      // Webprofiler module is enabled, a widget will
      // be rendered into Webprofiler toolbar.
      if (!$this->moduleHandler
        ->moduleExists('webprofiler')) {
        $response = $event
          ->getResponse();

        // Try not to break non html pages.
        $formats = [
          'xml',
          'javascript',
          'json',
          'plain',
          'image',
          'application',
          'csv',
          'x-comma-separated-values',
        ];
        foreach ($formats as $format) {
          if ($response->headers
            ->get($format)) {
            return;
          }
        }
        if ($this->currentUser
          ->hasPermission('access xhprof data')) {
          $this
            ->injectLink($response, $this->xhprofRunId);
        }
      }
    }
  }

  /**
   * Stops profiling and saves data.
   */
  public function onKernelTerminate() {
    if ($this->profiler
      ->isEnabled()) {
      $this->profiler
        ->shutdown($this->xhprofRunId);
    }
  }

  /**
   * Adds link to view report to the end of the response.
   *
   * @param \Symfony\Component\HttpFoundation\Response $response
   *   The response.
   * @param string $xhprofRunId
   *   The run ID.
   */
  protected function injectLink(Response $response, $xhprofRunId) {
    $content = $response
      ->getContent();
    $pos = mb_strripos($content, '</body>');
    if (FALSE !== $pos) {
      $output = '<div class="xhprof-ui">' . $this->profiler
        ->link($xhprofRunId) . '</div>';
      $content = mb_substr($content, 0, $pos) . $output . mb_substr($content, $pos);
      $response
        ->setContent($content);
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
XHProfEventSubscriber::$currentUser private property The current user.
XHProfEventSubscriber::$moduleHandler private property The module handler.
XHProfEventSubscriber::$profiler public property The profiler.
XHProfEventSubscriber::$xhprofRunId private property The profiling run ID.
XHProfEventSubscriber::getSubscribedEvents static function Returns an array of event names this subscriber wants to listen to.
XHProfEventSubscriber::injectLink protected function Adds link to view report to the end of the response.
XHProfEventSubscriber::onKernelRequest public function Enables profiling if allowed.
XHProfEventSubscriber::onKernelResponse public function Renders link to the finished run.
XHProfEventSubscriber::onKernelTerminate public function Stops profiling and saves data.
XHProfEventSubscriber::__construct public function Constructs XHProfEventSubscriber object.