qtools_profiler-8.x-1.x-dev/src/ReportService.php
src/ReportService.php
<?php
namespace Drupal\qtools_profiler;
use Drupal\Core\Render\Renderer;
use Drupal\Core\Url;
use Drupal\Core\Database\Connection;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Class ReportService.
*
* @package Drupal\qtools_profiler
*/
class ReportService {
use StringTranslationTrait;
/**
* Drupal\Core\Database\Connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* Renderer.
*
* @var Drupal\Core\Render\Renderer
*/
protected $renderer;
/**
* Drupal\qtools_profiler\PerformanceService.
*
* @var \Drupal\qtools_profiler\PerformanceService
*/
protected $performanceService;
// Table names.
const ITEMS_PER_PAGE = 15;
/**
* Constructor.
*/
public function __construct(Connection $connection, PerformanceService $performanceService, Renderer $renderer) {
$this->connection = $connection;
$this->performanceService = $performanceService;
$this->renderer = $renderer;
}
/**
* Sets report filter values.
*/
public function setReportFilters($filters) {
$_SESSION['qtools_profiler']['filters'] = $filters;
}
/**
* Gets current filter values.
*
* @return array
* Values of filters.
*/
public function getReportFilters($use_def = FALSE) {
$defaults = [
'start' => strtotime(date('Y-m-d', 0)),
'end' => strtotime(date('Y-m-d', time()) . ' +1day'),
'report' => FALSE,
];
if ($use_def) {
return $defaults;
}
$values = !empty($_SESSION['qtools_profiler']['filters']) ?
$_SESSION['qtools_profiler']['filters'] :
[];
foreach ($defaults as $key => $value) {
if (isset($values[$key])) {
$defaults[$key] = $values[$key];
}
}
return $defaults;
}
/**
* Builds a base query for Request report.
*
* @return \Drupal\Core\Database\Query\SelectInterface
* Select query.
*/
public function reportRequestBaseQuery($filters = [], $grouping = NULL) {
// Base table.
$query = $this->connection->select(PerformanceService::TABLE_REQUEST, 'r');
// Join additional resources.
$query->leftJoin(PerformanceService::TABLE_ROUTE, 'route', 'r.rid = route.id');
$query->leftJoin(PerformanceService::TABLE_RESPONSE, 'response', 'r.id = response.rid');
// Apply filters.
$query->condition('r.timestamp', $filters['start'], '>=');
$query->condition('r.timestamp', $filters['end'], '<=');
if (!empty($filters['route'])) {
$query->condition('r.rid', $filters['route'], '=');
}
if (!empty($filters['report'])) {
$query->condition('response.report', 0, '<>');
}
// Add grouping.
$query = $query->groupBy('r.id');
// Add fields.
$query->addExpression('MIN(r.id)', 'id');
$query->addExpression('MIN(r.timestamp)', 'timestamp');
$query->addExpression('MIN(response.code)', 'code');
$query->addExpression('MIN(response.report)', 'report');
$query->addExpression('MIN(r.uri)', 'uri');
$query->addExpression('MIN(response.time)', 'time');
$query->addExpression('MIN(response.memory)', 'memory');
$query = $query->extend('Drupal\Core\Database\Query\TableSortExtender')
->orderByHeader($this->reportRequestTableHeader($filters, $grouping));
$query = $query->extend('Drupal\Core\Database\Query\PagerSelectExtender')
->limit(static::ITEMS_PER_PAGE);
return $query;
}
/**
* Process results of Request report.
*
* @return array
* Processed items.
*/
public function reportRequestProcessResults($results, $filters = [], $grouping = NULL) {
$rows = [];
// Replace route column with a link to dedicated report.
foreach ($results as $result) {
$data = (array) $result;
$link = [
'#type' => 'link',
'#title' => $result->uri,
'#url' => Url::fromUri('internal:' . $result->uri),
'#attributes' => [
'target' => '_blank',
],
];
$data['uri'] = $this->renderer->renderRoot($link);
$data['timestamp'] = date('Y-m-d H:i:s Z', $data['timestamp']);
if ($result->report) {
$link = [
'#type' => 'link',
'#title' => $data['timestamp'],
'#url' => Url::fromRoute('qtools_profiler.admin.report_profile', ['id' => $data['id']]),
'#attributes' => [
'target' => '_blank',
],
];
$data['timestamp'] = $this->renderer->renderRoot($link);
}
unset($data['id']);
unset($data['report']);
$rows[] = $data;
}
return $this->processNumericValues($rows);
}
/**
* Return header definition for requests.
*
* @return array
* Table header.
*/
public function reportRequestTableHeader($filters = [], $grouping = NULL) {
return [
'timestamp' => [
'data' => $this->t('timestamp'),
'field' => 'timestamp',
'sort' => 'desc',
],
'id' => [
'data' => $this->t('code'),
'field' => 'code',
],
'uri' => [
'data' => $this->t('uri'),
'field' => 'uri',
],
'time' => [
'data' => $this->t('time'),
'field' => 'time',
],
'memory' => [
'data' => $this->t('memory'),
'field' => 'memory',
],
];
}
/**
* Apply precision to numeric values.
*/
protected function processNumericValues($rows) {
foreach ($rows as $row => $data) {
foreach ($data as $key => $value) {
if (is_numeric($value)) {
$data[$key] = round($value, 2);
}
}
$rows[$row] = $data;
}
return $rows;
}
/**
* Apply precision to numeric values.
*
* @return \Drupal\Core\Database\Query\SelectInterface
* Query with filters applied.
*/
protected function applyFilters($query, $filters = []) {
foreach ($filters as $field => $value) {
$query->condition($field, $value);
}
return $query;
}
/**
* Get profiling run details.
*/
public function getProfileDetails($id) {
$file_name = $this->performanceService->getProfilingDataFileName($id);
if (!empty($file_name) && file_exists($file_name)) {
$content = unserialize(file_get_contents($file_name));
}
else {
$content = NULL;
}
return $content;
}
}
