165 lines
5.0 KiB
PHP
165 lines
5.0 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/services/queryBuilders/PKPStatsQueryBuilder.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2000-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class PKPStatsQueryBuilder
|
|
*
|
|
* @ingroup query_builders
|
|
*
|
|
* @brief Base class for statistics query builders.
|
|
*/
|
|
|
|
namespace PKP\services\queryBuilders;
|
|
|
|
use Illuminate\Database\Query\Builder;
|
|
use Illuminate\Support\Facades\DB;
|
|
use PKP\config\Config;
|
|
use PKP\statistics\PKPStatisticsHelper;
|
|
|
|
abstract class PKPStatsQueryBuilder
|
|
{
|
|
/** Include records for these contexts */
|
|
protected array $contextIds = [];
|
|
|
|
/** Include records from this date or before. Default: yesterday's date */
|
|
protected string $dateEnd;
|
|
|
|
/** Include records from this date or after. Default: PKPStatisticsHelper::STATISTICS_EARLIEST_DATE */
|
|
protected string $dateStart;
|
|
|
|
/** The count of records to return */
|
|
protected int $limit = 0;
|
|
|
|
/** The offset of records to return */
|
|
protected int $offset = 0;
|
|
|
|
|
|
/**
|
|
* Set the contexts to get records for
|
|
*/
|
|
public function filterByContexts(array $contextIds): self
|
|
{
|
|
$this->contextIds = $contextIds;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the date before which to get records
|
|
*
|
|
* @param string $dateEnd YYYY-MM-DD
|
|
*
|
|
*/
|
|
public function before(string $dateEnd): self
|
|
{
|
|
$this->dateEnd = $dateEnd;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the date after which to get records
|
|
*
|
|
* @param string $dateStart YYYY-MM-DD
|
|
*
|
|
*/
|
|
public function after(string $dateStart): self
|
|
{
|
|
$this->dateStart = $dateStart;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the count of records to return
|
|
*/
|
|
public function limit(int $limit): self
|
|
{
|
|
$this->limit = $limit;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the offset of records to return
|
|
*/
|
|
public function offset(int $offset): self
|
|
{
|
|
$this->offset = $offset;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get the sum of all matching records
|
|
*
|
|
* Use this method to get the total X views. Pass a
|
|
* $groupBy argument to get the total X views for each
|
|
* object, grouped by one or more columns.
|
|
*
|
|
* @param array $groupBy One or more columns to group by
|
|
*
|
|
*/
|
|
public function getSum(array $groupBy = []): Builder
|
|
{
|
|
$selectColumns = $groupBy;
|
|
$selectColumns = $this->getSelectColumns($selectColumns);
|
|
|
|
$q = $this->_getObject();
|
|
// Build the select and group by clauses.
|
|
if (!empty($selectColumns)) {
|
|
$q->select($selectColumns);
|
|
if (!empty($groupBy)) {
|
|
$q->groupBy($groupBy);
|
|
}
|
|
}
|
|
$q->addSelect(DB::raw('SUM(metric) AS metric'));
|
|
|
|
return $q;
|
|
}
|
|
|
|
/**
|
|
* Generate a query object based on the configured conditions.
|
|
*
|
|
* Public methods should call this method to set up the query
|
|
* object and apply any additional selection, grouping and
|
|
* ordering conditions.
|
|
*/
|
|
abstract protected function _getObject(): Builder;
|
|
|
|
/**
|
|
* Get appropriate SQL code for columns in the select part of the query
|
|
*/
|
|
protected function getSelectColumns(array $selectColumns): array
|
|
{
|
|
if (!in_array(PKPStatisticsHelper::STATISTICS_DIMENSION_YEAR, $selectColumns)
|
|
&& !in_array(PKPStatisticsHelper::STATISTICS_DIMENSION_MONTH, $selectColumns)
|
|
&& !in_array(PKPStatisticsHelper::STATISTICS_DIMENSION_DAY, $selectColumns)) {
|
|
return $selectColumns;
|
|
}
|
|
foreach ($selectColumns as $i => $selectColumn) {
|
|
if ($selectColumn == PKPStatisticsHelper::STATISTICS_DIMENSION_YEAR) {
|
|
if (substr(Config::getVar('database', 'driver'), 0, strlen('postgres')) === 'postgres') {
|
|
// date_trunc: Values of type date are cast automatically to timestamp. So cast them back to date.
|
|
$selectColumns[$i] = DB::raw("date_trunc('year', date)::timestamp::date AS year");
|
|
} else {
|
|
$selectColumns[$i] = DB::raw("date_format(date, '%Y-01-01') AS year");
|
|
}
|
|
break;
|
|
} elseif ($selectColumn == PKPStatisticsHelper::STATISTICS_DIMENSION_MONTH) {
|
|
if (substr(Config::getVar('database', 'driver'), 0, strlen('postgres')) === 'postgres') {
|
|
// date_trunc: Values of type date are cast automatically to timestamp. So cast them back to date.
|
|
$selectColumns[$i] = DB::raw("date_trunc('month', date)::timestamp::date AS month");
|
|
} else {
|
|
$selectColumns[$i] = DB::raw("date_format(date, '%Y-%m-01') AS month");
|
|
}
|
|
break;
|
|
} elseif ($selectColumn == PKPStatisticsHelper::STATISTICS_DIMENSION_DAY) {
|
|
$selectColumns[$i] = DB::raw('date AS day');
|
|
break;
|
|
}
|
|
}
|
|
return $selectColumns;
|
|
}
|
|
}
|