Open Journal Systems  3.3.0
PKPStatsService.inc.php
1 <?php
2 
16 namespace PKP\Services;
17 
19 
35  public function getRecords($args = []) {
36 
37  // Get the stats constants
38  import('classes.statistics.StatisticsHelper');
39 
40  $defaultArgs = [
41  'dateStart' => STATISTICS_EARLIEST_DATE,
42  'dateEnd' => date('Y-m-d', strtotime('yesterday')),
43 
44  // Require a context to be specified to prevent unwanted data leakage
45  // if someone forgets to specify the context.
46  'contextIds' => [CONTEXT_ID_NONE],
47  ];
48 
49  $args = array_merge($defaultArgs, $args);
50  $statsQB = $this->getQueryBuilder($args);
51 
52  \HookRegistry::call('Stats::getRecords::queryBuilder', array($statsQB, $args));
53 
54  $statsQO = $statsQB->getRecords();
55 
56  $result = \DAORegistry::getDAO('MetricsDAO')
57  ->retrieve($statsQO->toSql(), $statsQO->getBindings());
58 
59  $records = [];
60  while (!$result->EOF) {
61  $records[] = [
62  'loadId' => $result->fields['load_id'],
63  'contextId' => (int) $result->fields['context_id'],
64  'submissionId' => (int) $result->fields['submission_id'],
65  'assocType' => (int) $result->fields['assoc_type'],
66  'assocId' => (int) $result->fields['assoc_id'],
67  'day' => (int) $result->fields['day'],
68  'month' => (int) $result->fields['month'],
69  'fileType' => (int) $result->fields['file_type'],
70  'countryId' => $result->fields['country_id'],
71  'region' => $result->fields['region'],
72  'city' => $result->fields['city'],
73  'metric' => (int) $result->fields['metric'],
74  'metricType' => $result->fields['metric_type'],
75  'pkpSectionId' => (int) $result->fields['pkp_section_id'],
76  'assocObjectType' => (int) $result->fields['assoc_object_type'],
77  'assocObjectTId' => (int) $result->fields['assoc_object_id'],
78  'representation_id' => (int) $result->fields['representation_id'],
79  ];
80  $result->MoveNext();
81  }
82 
83  return $records;
84  }
85 
93  public function getTimeline($timelineInterval, $args = []) {
94 
95  $defaultArgs = [
96  'dateStart' => STATISTICS_EARLIEST_DATE,
97  'dateEnd' => date('Y-m-d', strtotime('yesterday')),
98 
99  // Require a context to be specified to prevent unwanted data leakage
100  // if someone forgets to specify the context. If you really want to
101  // get data across all contexts, pass an empty `contextId` arg.
102  'contextIds' => [CONTEXT_ID_NONE],
103  ];
104 
105  $args = array_merge($defaultArgs, $args);
106  $timelineQB = $this->getQueryBuilder($args);
107 
108  \HookRegistry::call('Stats::getTimeline::queryBuilder', array($timelineQB, $args));
109 
110  $timelineQO = $timelineQB
111  ->getSum([$timelineInterval])
112  ->orderBy($timelineInterval);
113 
114  $result = \DAORegistry::getDAO('MetricsDAO')
115  ->retrieve($timelineQO->toSql(), $timelineQO->getBindings());
116 
117  $dateValues = [];
118  while (!$result->EOF) {
119  $date = substr($result->fields[$timelineInterval], 0, 4) . '-' . substr($result->fields[$timelineInterval], 4, 2);
120  if ($timelineInterval === STATISTICS_DIMENSION_DAY) {
121  $date = substr($date, 0, 7) . '-' . substr($result->fields[$timelineInterval], 6, 2);
122  }
123  $dateValues[$date] = (int) $result->fields['metric'];
124  $result->MoveNext();
125  }
126 
127  $timeline = $this->getEmptyTimelineIntervals($args['dateStart'], $args['dateEnd'], $timelineInterval);
128 
129  $timeline = array_map(function($entry) use ($dateValues) {
130  foreach ($dateValues as $date => $value) {
131  if ($entry['date'] === $date) {
132  $entry['value'] = $value;
133  break;
134  }
135  }
136  return $entry;
137  }, $timeline);
138 
139  return $timeline;
140  }
141 
161  public function getOrderedObjects($groupBy, $orderDirection, $args = []) {
162 
163  $defaultArgs = [
164  'dateStart' => STATISTICS_EARLIEST_DATE,
165  'dateEnd' => date('Y-m-d', strtotime('yesterday')),
166 
167  // Require a context to be specified to prevent unwanted data leakage
168  // if someone forgets to specify the context. If you really want to
169  // get data across all contexts, pass an empty `contextId` arg.
170  'contextIds' => [CONTEXT_ID_NONE],
171  ];
172 
173  $args = array_merge($defaultArgs, $args);
174  $orderedQB = $this->getQueryBuilder($args);
175 
176  \HookRegistry::call('Stats::getOrderedObjects::queryBuilder', array($orderedQB, $args));
177 
178  $orderedQO = $orderedQB
179  ->getSum([$groupBy])
180  ->orderBy('metric', $orderDirection === STATISTICS_ORDER_ASC ? 'asc' : 'desc');
181 
182  $range = null;
183  if (isset($args['count'])) {
184  import('lib.pkp.classes.db.DBResultRange');
185  $range = new \DBResultRange($args['count'], null, isset($args['offset']) ? $args['offset'] : 0);
186  }
187 
188  $result = \DAORegistry::getDAO('MetricsDAO')
189  ->retrieveRange($orderedQO->toSql(), $orderedQO->getBindings(), $range);
190 
191  $objects = [];
192  while (!$result->EOF) {
193  $objects[] = [
194  'id' => (int) $result->fields[$groupBy],
195  'total' => (int) $result->fields['metric'],
196  ];
197  $result->MoveNext();
198  }
199 
200  return $objects;
201  }
202 
210  public function sumMetric($total, $record) {
211  $total += $record['metric'];
212  return $total;
213  }
214 
222  public function filterRecordFile($record) {
223  return !empty($record['fileType']);
224  }
225 
233  public function filterRecordPdf($record) {
234  return $record['fileType'] === STATISTICS_FILE_TYPE_PDF;
235  }
236 
244  public function filterRecordHtml($record) {
245  return $record['fileType'] === STATISTICS_FILE_TYPE_HTML;
246  }
247 
255  public function filterRecordOther($record) {
256  return $record['fileType'] === STATISTICS_FILE_TYPE_OTHER;
257  }
258 
268  public function getEmptyTimelineIntervals($startDate, $endDate, $timelineInterval) {
269 
270  if ($timelineInterval === STATISTICS_DIMENSION_MONTH) {
271  $dateFormat = 'Y-m';
272  $labelFormat = '%B %Y';
273  $interval = 'P1M';
274  } elseif ($timelineInterval === STATISTICS_DIMENSION_DAY) {
275  $dateFormat = 'Y-m-d';
276  $labelFormat = \Application::get()->getRequest()->getContext()->getLocalizedDateFormatLong();
277  $interval = 'P1D';
278  }
279 
280  $startDate = new \DateTime($startDate);
281  $endDate = new \DateTime($endDate);
282 
283  $timelineIntervals = [];
284  while ($startDate->format($dateFormat) <= $endDate->format($dateFormat)) {
285  $timelineIntervals[] = [
286  'date' => $startDate->format($dateFormat),
287  'label' => strftime($labelFormat, $startDate->getTimestamp()),
288  'value' => 0,
289  ];
290  $startDate->add(new \DateInterval($interval));
291  }
292 
293  return $timelineIntervals;
294  }
295 
302  protected function getQueryBuilder($args = []) {
303  $statsQB = new \PKP\Services\QueryBuilders\PKPStatsQueryBuilder();
304  $statsQB
305  ->filterByContexts($args['contextIds'])
306  ->before($args['dateEnd'])
307  ->after($args['dateStart']);
308 
309  if (!empty(($args['submissionIds']))) {
310  $statsQB->filterBySubmissions($args['submissionIds']);
311  }
312 
313  if (!empty($args['assocTypes'])) {
314  $statsQB->filterByAssocTypes($args['assocTypes']);
315  if (!empty($args['assocIds'])) {
316  $statsQB->filterByAssocIds($args['assocIds']);
317  }
318  }
319 
320  if (!empty($args['fileTypes'])) {
321  $statsQB->filterByFileTypes(($args['fileTypes']));
322  }
323 
324  \HookRegistry::call('Stats::queryBuilder', array($statsQB, $args));
325 
326  return $statsQB;
327  }
328 }
PKP\Services\PKPStatsService\getOrderedObjects
getOrderedObjects($groupBy, $orderDirection, $args=[])
Definition: PKPStatsService.inc.php:161
PKP\Services
PKP\Services\PKPStatsService\sumMetric
sumMetric($total, $record)
Definition: PKPStatsService.inc.php:210
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
PKP\Services\PKPStatsService\filterRecordHtml
filterRecordHtml($record)
Definition: PKPStatsService.inc.php:244
PKP\Services\PKPStatsService
Definition: PKPStatsService.inc.php:18
PKP\Services\PKPStatsService\filterRecordPdf
filterRecordPdf($record)
Definition: PKPStatsService.inc.php:233
PKP\Services\PKPStatsService\getTimeline
getTimeline($timelineInterval, $args=[])
Definition: PKPStatsService.inc.php:93
PKP\Services\PKPStatsService\getRecords
getRecords($args=[])
Definition: PKPStatsService.inc.php:35
PKP\Services\PKPStatsService\getQueryBuilder
getQueryBuilder($args=[])
Definition: PKPStatsService.inc.php:302
PKP\Services\PKPStatsService\filterRecordFile
filterRecordFile($record)
Definition: PKPStatsService.inc.php:222
PKP\Services\PKPStatsService\filterRecordOther
filterRecordOther($record)
Definition: PKPStatsService.inc.php:255
PKPApplication\get
static get()
Definition: PKPApplication.inc.php:235
HookRegistry\call
static call($hookName, $args=null)
Definition: HookRegistry.inc.php:86
PKP\Services\PKPStatsService\getEmptyTimelineIntervals
getEmptyTimelineIntervals($startDate, $endDate, $timelineInterval)
Definition: PKPStatsService.inc.php:268