Version 1
[yaffs-website] / web / modules / contrib / devel / webprofiler / src / DataCollector / DatabaseDataCollector.php
diff --git a/web/modules/contrib/devel/webprofiler/src/DataCollector/DatabaseDataCollector.php b/web/modules/contrib/devel/webprofiler/src/DataCollector/DatabaseDataCollector.php
new file mode 100644 (file)
index 0000000..bdcf49c
--- /dev/null
@@ -0,0 +1,253 @@
+<?php
+
+namespace Drupal\webprofiler\DataCollector;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Database;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\webprofiler\DrupalDataCollectorInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\DataCollector\DataCollector;
+
+/**
+ * Class DatabaseDataCollector
+ */
+class DatabaseDataCollector extends DataCollector implements DrupalDataCollectorInterface {
+
+  use StringTranslationTrait, DrupalDataCollectorTrait;
+
+  /**
+   * @var \Drupal\Core\Database\Connection
+   */
+  private $database;
+
+  /**
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  private $configFactory;
+
+  /**
+   * @param \Drupal\Core\Database\Connection $database
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
+   */
+  public function __construct(Connection $database, ConfigFactoryInterface $configFactory) {
+    $this->database = $database;
+    $this->configFactory = $configFactory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function collect(Request $request, Response $response, \Exception $exception = NULL) {
+    $connections = [];
+    foreach (Database::getAllConnectionInfo() as $key => $info) {
+      $database = Database::getConnection('default', $key);
+      $connections[$key] = $database->getLogger()->get('webprofiler');
+    }
+
+    $this->data['connections'] = array_keys($connections);
+
+    $data = [];
+    foreach ($connections as $key => $queries) {
+      foreach ($queries as $query) {
+        // Remove caller args.
+        unset($query['caller']['args']);
+
+        // Remove query args element if empty.
+        if (empty($query['args'])) {
+          unset($query['args']);
+        }
+
+        // Save time in milliseconds.
+        $query['time'] = $query['time'] * 1000;
+        $query['database'] = $key;
+        $data[] = $query;
+      }
+    }
+
+    $querySort = $this->configFactory->get('webprofiler.config')
+      ->get('query_sort');
+    if ('duration' === $querySort) {
+      usort(
+        $data, [
+          "Drupal\\webprofiler\\DataCollector\\DatabaseDataCollector",
+          "orderQueryByTime",
+        ]
+      );
+    }
+
+    $this->data['queries'] = $data;
+
+    $options = $this->database->getConnectionOptions();
+
+    // Remove password for security.
+    unset($options['password']);
+
+    $this->data['database'] = $options;
+  }
+
+  /**
+   * @return array
+   */
+  public function getDatabase() {
+    return $this->data['database'];
+  }
+
+  /**
+   * @return int
+   */
+  public function getQueryCount() {
+    return count($this->data['queries']);
+  }
+
+  /**
+   * @return array
+   */
+  public function getQueries() {
+    return $this->data['queries'];
+  }
+
+  /**
+   * Returns the total execution time.
+   *
+   * @return float
+   */
+  public function getTime() {
+    $time = 0;
+
+    foreach ($this->data['queries'] as $query) {
+      $time += $query['time'];
+    }
+
+    return $time;
+  }
+
+  /**
+   * Returns a color based on the number of executed queries.
+   *
+   * @return string
+   */
+  public function getColorCode() {
+    if ($this->getQueryCount() < 100) {
+      return 'green';
+    }
+    if ($this->getQueryCount() < 200) {
+      return 'yellow';
+    }
+
+    return 'red';
+  }
+
+  /**
+   * Returns the configured query highlight threshold.
+   *
+   * @return int
+   */
+  public function getQueryHighlightThreshold() {
+    // When a profile is loaded from storage this object is deserialized and
+    // no constructor is called so we cannot use dependency injection.
+    return \Drupal::config('webprofiler.config')->get('query_highlight');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return 'database';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTitle() {
+    return $this->t('Database');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPanelSummary() {
+    return $this->t('Executed queries: @count', ['@count' => $this->getQueryCount()]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIcon() {
+    return 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAcCAYAAABh2p9gAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQRJREFUeNpi/P//PwM1ARMDlcGogZQDlpMnT7pxc3NbA9nhQKxOpL5rQLwJiPeBsI6Ozl+YBOOOHTv+AOllQNwtLS39F2owKYZ/gRq8G4i3ggxEToggWzvc3d2Pk+1lNL4fFAs6ODi8JzdS7mMRVyDVoAMHDsANdAPiOCC+jCQvQKqBQB/BDbwBxK5AHA3E/kB8nKJkA8TMQBwLxaBIKQbi70AvTADSBiSadwFXpCikpKQU8PDwkGTaly9fHFigkaKIJid4584dkiMFFI6jkTJII0WVmpHCAixZQEXWYhDeuXMnyLsVlEQKI45qFBQZ8eRECi4DBaAlDqle/8A48ip6gAADANdQY88Uc0oGAAAAAElFTkSuQmCC';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLibraries() {
+    return [
+      'webprofiler/database',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getData() {
+    $data = $this->data;
+
+    $conn = Database::getConnection();
+    foreach ($data['queries'] as &$query) {
+      $explain = TRUE;
+      $type = 'select';
+
+      if (strpos($query['query'], 'INSERT') !== FALSE) {
+        $explain = FALSE;
+        $type = 'insert';
+      }
+
+      if (strpos($query['query'], 'UPDATE') !== FALSE) {
+        $explain = FALSE;
+        $type = 'update';
+      }
+
+      if (strpos($query['query'], 'CREATE') !== FALSE) {
+        $explain = FALSE;
+        $type = 'create';
+      }
+
+      if (strpos($query['query'], 'DELETE') !== FALSE) {
+        $explain = FALSE;
+        $type = 'delete';
+      }
+
+      $query['explain'] = $explain;
+      $query['type'] = $type;
+
+      $quoted = [];
+      foreach ((array) $query['args'] as $key => $val) {
+        $quoted[$key] = is_null($val) ? 'NULL' : $conn->quote($val);
+      }
+
+      $query['query_args'] = strtr($query['query'], $quoted);
+    }
+
+    $data['query_highlight_threshold'] = $this->getQueryHighlightThreshold();
+
+    return $data;
+  }
+
+  /**
+   * @param $a
+   * @param $b
+   *
+   * @return int
+   */
+  private function orderQueryByTime($a, $b) {
+    $at = $a['time'];
+    $bt = $b['time'];
+
+    if ($at == $bt) {
+      return 0;
+    }
+    return ($at < $bt) ? 1 : -1;
+  }
+}