Version 1
[yaffs-website] / web / core / lib / Drupal / Core / Database / Query / PagerSelectExtender.php
diff --git a/web/core/lib/Drupal/Core/Database/Query/PagerSelectExtender.php b/web/core/lib/Drupal/Core/Database/Query/PagerSelectExtender.php
new file mode 100644 (file)
index 0000000..5207f58
--- /dev/null
@@ -0,0 +1,170 @@
+<?php
+
+namespace Drupal\Core\Database\Query;
+
+use Drupal\Core\Database\Connection;
+
+/**
+ * Query extender for pager queries.
+ *
+ * This is the "default" pager mechanism.  It creates a paged query with a fixed
+ * number of entries per page.
+ *
+ * When adding this extender along with other extenders, be sure to add
+ * PagerSelectExtender last, so that its range and count are based on the full
+ * query.
+ */
+class PagerSelectExtender extends SelectExtender {
+
+  /**
+   * The highest element we've autogenerated so far.
+   *
+   * @var int
+   */
+  public static $maxElement = 0;
+
+  /**
+   * The number of elements per page to allow.
+   *
+   * @var int
+   */
+  protected $limit = 10;
+
+  /**
+   * The unique ID of this pager on this page.
+   *
+   * @var int
+   */
+  protected $element = NULL;
+
+  /**
+   * The count query that will be used for this pager.
+   *
+   * @var \Drupal\Core\Database\Query\SelectInterface
+   */
+  protected $customCountQuery = FALSE;
+
+  public function __construct(SelectInterface $query, Connection $connection) {
+    parent::__construct($query, $connection);
+
+    // Add pager tag. Do this here to ensure that it is always added before
+    // preExecute() is called.
+    $this->addTag('pager');
+  }
+
+  /**
+   * Override the execute method.
+   *
+   * Before we run the query, we need to add pager-based range() instructions
+   * to it.
+   */
+  public function execute() {
+    // By calling preExecute() here, we force it to preprocess the extender
+    // object rather than just the base query object. That means
+    // hook_query_alter() gets access to the extended object.
+    if (!$this->preExecute($this)) {
+      return NULL;
+    }
+
+    // A NULL limit is the "kill switch" for pager queries.
+    if (empty($this->limit)) {
+      return;
+    }
+    $this->ensureElement();
+
+    $total_items = $this->getCountQuery()->execute()->fetchField();
+    $current_page = pager_default_initialize($total_items, $this->limit, $this->element);
+    $this->range($current_page * $this->limit, $this->limit);
+
+    // Now that we've added our pager-based range instructions, run the query normally.
+    return $this->query->execute();
+  }
+
+  /**
+   * Ensure that there is an element associated with this query.
+   * If an element was not specified previously, then the value of the
+   * $maxElement counter is taken, after which the counter is incremented.
+   *
+   * After running this method, access $this->element to get the element for this
+   * query.
+   */
+  protected function ensureElement() {
+    if (!isset($this->element)) {
+      $this->element = self::$maxElement++;
+    }
+  }
+
+  /**
+   * Specify the count query object to use for this pager.
+   *
+   * You will rarely need to specify a count query directly.  If not specified,
+   * one is generated off of the pager query itself.
+   *
+   * @param \Drupal\Core\Database\Query\SelectInterface $query
+   *   The count query object.  It must return a single row with a single column,
+   *   which is the total number of records.
+   */
+  public function setCountQuery(SelectInterface $query) {
+    $this->customCountQuery = $query;
+  }
+
+  /**
+   * Retrieve the count query for this pager.
+   *
+   * The count query may be specified manually or, by default, taken from the
+   * query we are extending.
+   *
+   * @return \Drupal\Core\Database\Query\SelectInterface
+   *   A count query object.
+   */
+  public function getCountQuery() {
+    if ($this->customCountQuery) {
+      return $this->customCountQuery;
+    }
+    else {
+      return $this->query->countQuery();
+    }
+  }
+
+  /**
+   * Specify the maximum number of elements per page for this query.
+   *
+   * The default if not specified is 10 items per page.
+   *
+   * @param int|false $limit
+   *   An integer specifying the number of elements per page. If passed a false
+   *   value (FALSE, 0, NULL), the pager is disabled.
+   */
+  public function limit($limit = 10) {
+    $this->limit = $limit;
+    return $this;
+  }
+
+  /**
+   * Specify the element ID for this pager query.
+   *
+   * The element is used to differentiate different pager queries on the same
+   * page so that they may be operated independently.  If you do not specify an
+   * element, every pager query on the page will get a unique element.  If for
+   * whatever reason you want to explicitly define an element for a given query,
+   * you may do so here.
+   *
+   * Setting the element here also increments the static $maxElement counter,
+   * which is used for determining the $element when there's none specified.
+   *
+   * Note that no collision detection is done when setting an element ID
+   * explicitly, so it is possible for two pagers to end up using the same ID
+   * if both are set explicitly.
+   *
+   * @param $element
+   *   Element ID that is used to differentiate different pager queries.
+   */
+  public function element($element) {
+    $this->element = $element;
+    if ($element >= self::$maxElement) {
+      self::$maxElement = $element + 1;
+    }
+    return $this;
+  }
+
+}