19 import(
'classes.statistics.StatisticsHelper');
43 function &
getMetrics($metricType, $columns = array(), $filters = array(), $orderBy = array(), $range =
null, $nonAdditive =
true) {
48 if (is_scalar($metricType)) $metricType = array($metricType);
49 if (is_scalar($columns)) $columns = array($columns);
50 if (!(is_array($filters) && is_array($orderBy)))
return $nullVar;
53 foreach ($metricType as $metricTypeElement) {
54 if (!is_string($metricTypeElement))
return $nullVar;
56 $validColumns = array(
57 STATISTICS_DIMENSION_CONTEXT_ID,
58 STATISTICS_DIMENSION_PKP_SECTION_ID,
59 STATISTICS_DIMENSION_ASSOC_OBJECT_ID,
60 STATISTICS_DIMENSION_ASSOC_OBJECT_TYPE,
61 STATISTICS_DIMENSION_SUBMISSION_ID,
62 STATISTICS_DIMENSION_REPRESENTATION_ID,
63 STATISTICS_DIMENSION_FILE_TYPE,
64 STATISTICS_DIMENSION_ASSOC_TYPE,
65 STATISTICS_DIMENSION_ASSOC_ID,
66 STATISTICS_DIMENSION_COUNTRY,
67 STATISTICS_DIMENSION_REGION,
68 STATISTICS_DIMENSION_CITY,
69 STATISTICS_DIMENSION_MONTH,
70 STATISTICS_DIMENSION_DAY,
71 STATISTICS_DIMENSION_METRIC_TYPE
76 $metricKey = array_search(STATISTICS_METRIC, $columns);
77 if ($metricKey !==
false) unset($columns[$metricKey]);
79 if (count(array_diff($columns, $validColumns)) > 0)
return $nullVar;
80 $validColumns[] = STATISTICS_METRIC;
81 foreach ($filters as $filterColumn => $value) {
82 if (!in_array($filterColumn, $validColumns))
return $nullVar;
84 $validDirections = array(STATISTICS_ORDER_ASC, STATISTICS_ORDER_DESC);
85 foreach ($orderBy as $orderColumn => $direction) {
86 if (!in_array($orderColumn, $validColumns))
return $nullVar;
87 if (!in_array($direction, $validDirections))
return $nullVar;
93 if (empty($metricType))
return $nullVar;
94 if (count($metricType) !== 1 && $nonAdditive) {
95 if (!in_array(STATISTICS_DIMENSION_METRIC_TYPE, $columns)) {
96 array_push($columns, STATISTICS_DIMENSION_METRIC_TYPE);
101 $filters[STATISTICS_DIMENSION_METRIC_TYPE] = $metricType;
104 if (empty($columns)) {
105 $selectClause =
'SELECT SUM(metric) AS metric';
108 $selectedColumns = implode(
', ', $columns);
109 $selectClause =
"SELECT $selectedColumns, SUM(metric) AS metric";
110 $groupByClause =
"GROUP BY $selectedColumns";
118 foreach ($filters as $column => $values) {
121 if ($column === STATISTICS_METRIC) {
122 $havingClause =
'HAVING ';
123 $currentClause =& $havingClause;
125 if ($isFirst && $column) {
126 $whereClause =
'WHERE ';
129 $whereClause .=
' AND ';
131 $currentClause =& $whereClause;
134 if (is_object($values)) {
135 $values = (array) $values;
138 if (is_array($values) && isset($values[
'from'])) {
140 if (!isset($values[
'to']))
return $nullVar;
141 $currentClause .=
"($column BETWEEN ? AND ?)";
142 $params[] = $values[
'from'];
143 $params[] = $values[
'to'];
147 if (is_array($values) && count($values) === 1) {
148 $values = array_pop($values);
150 if (is_scalar($values)) {
151 $currentClause .=
"$column = ?";
153 } elseif (count($values)) {
154 $placeholders = array_pad(array(), count($values),
'?');
155 $placeholders = implode(
', ', $placeholders);
156 $currentClause .=
"$column IN ($placeholders)";
157 foreach ($values as $value) {
162 $currentClause .=
'1=0';
166 unset($currentClause);
171 $currentTime = array(
172 STATISTICS_YESTERDAY => date(
'Ymd', strtotime(
'-1 day', time())),
173 STATISTICS_CURRENT_MONTH => date(
'Ym', time()));
174 foreach ($currentTime as $constant => $time) {
175 $currentTimeKeys = array_keys($params, $constant);
176 foreach ($currentTimeKeys as $key) {
177 $params[$key] = $time;
183 if (count($orderBy) > 0) {
185 foreach ($orderBy as $orderColumn => $direction) {
187 $orderByClause =
'ORDER BY ';
189 $orderByClause .=
', ';
191 $orderByClause .=
"$orderColumn $direction";
197 $sql =
"$selectClause FROM metrics $whereClause $groupByClause $havingClause $orderByClause";
198 if (is_a($range,
'DBResultRange')) $result = $this->
retrieveRange($sql, $params, $range);
199 else $result = $this->
retrieve($sql, $params);
202 $returner = $result->GetAll();
216 $params = array($assocType, $assocId, $metricType);
217 $result = $this->
retrieve(
'SELECT load_id FROM metrics WHERE assoc_type = ? AND assoc_id = ? AND metric_type = ? GROUP BY load_id', $params);
220 while (!$result->EOF) {
221 $row = $result->FetchRow();
222 $loadIds[] = $row[
'load_id'];
235 $result = $this->
retrieve(
'SELECT load_id FROM metrics WHERE metric_type = ? LIMIT 1', array($metricType));
236 $row = $result->GetRowAssoc();
250 $this->
update(
'DELETE FROM metrics WHERE load_id = ?', $loadId);
260 $this->
update(
'DELETE FROM metrics WHERE metric_type = ? AND day IS NOT NULL AND day <= ?', array($metricType, $toDate));
270 $recordToStore = array();
273 $requiredDimensions = array(
'load_id',
'assoc_type',
'assoc_id',
'metric_type');
274 foreach ($requiredDimensions as $requiredDimension) {
275 if (!isset($record[$requiredDimension])) {
276 throw new Exception(
'Cannot load record: missing dimension "' . $requiredDimension .
'".');
278 $recordToStore[$requiredDimension] = $record[$requiredDimension];
280 $assocType = $recordToStore[
'assoc_type'] = (int)$recordToStore[
'assoc_type'];
281 $assocId = $recordToStore[
'assoc_id'] = (int)$recordToStore[
'assoc_id'];
283 list($contextId, $pkpSectionId, $assocObjType,
284 $assocObjId, $submissionId, $representationId) = $this->
foreignKeyLookup($assocType, $assocId);
286 $recordToStore[
'context_id'] = $contextId;
287 $recordToStore[
'pkp_section_id'] = $pkpSectionId;
288 $recordToStore[
'assoc_object_type'] = $assocObjType;
289 $recordToStore[
'assoc_object_id'] = $assocObjId;
290 $recordToStore[
'submission_id'] = $submissionId;
291 $recordToStore[
'representation_id'] = $representationId;
294 if (isset($record[
'file_type']) && $record[
'file_type']) $recordToStore[
'file_type'] = (int)$record[
'file_type'];
297 if (isset($record[
'day'])) {
299 throw new Exception(
'Cannot load record: invalid date.');
301 $recordToStore[
'day'] = $record[
'day'];
302 $recordToStore[
'month'] = substr($record[
'day'], 0, 6);
303 if (isset($record[
'month']) && $recordToStore[
'month'] != $record[
'month']) {
304 throw new Exception(
'Cannot load record: invalid month.');
306 } elseif (isset($record[
'month'])) {
308 throw new Exception(
'Cannot load record: invalid month.');
310 $recordToStore[
'month'] = $record[
'month'];
312 throw new Exception(
'Cannot load record: Missing time dimension.');
316 if (isset($record[
'country_id'])) $recordToStore[
'country_id'] = (string)$record[
'country_id'];
317 if (isset($record[
'region'])) $recordToStore[
'region'] = (
string)$record[
'region'];
318 if (isset($record[
'city'])) $recordToStore[
'city'] = (
string)$record[
'city'];
321 if (!isset($record[
'metric'])) {
322 throw new Exception(
'Cannot load record: metric is missing.');
324 if (!is_numeric($record[
'metric'])) {
325 throw new Exception(
'Cannot load record: invalid metric.');
327 $recordToStore[
'metric'] = (int) $record[
'metric'];
330 $fields = implode(
', ', array_keys($recordToStore));
331 $placeholders = implode(
', ', array_pad(array(), count($recordToStore),
'?'));
332 $params = array_values($recordToStore);
333 return $this->
update(
"INSERT INTO metrics ($fields) VALUES ($placeholders)", $params);
349 $contextId = $sectionId = $submissionId = $assocObjectType = $assocObjectId = $representationId =
null;
352 $isRepresentation =
false;
355 case ASSOC_TYPE_SUBMISSION_FILE:
356 case ASSOC_TYPE_SUBMISSION_FILE_COUNTER_OTHER:
358 $submissionFile = $submissionFileDao->getLatestRevision($assocId);
359 if ($submissionFile) {
361 $submissionId = $submissionFile->getSubmissionId();
362 if ($submissionFile->getAssocType() == ASSOC_TYPE_REPRESENTATION) {
363 $representationId = $submissionFile->getAssocId();
365 throw new Exception(
'Cannot load record: submission file is not associated with a representation object.');
368 throw new Exception(
'Cannot load record: invalid submission file id.');
371 case ASSOC_TYPE_REPRESENTATION:
372 if (!$isFile) $representationId = $assocId;
374 $representation = $representationDao->getById($representationId);
375 if ($representation) {
376 if (!$isFile) $isRepresentation =
true;
378 $contextId = $representation->getContextId();
379 $publication =
Services::get(
'publication')->get($representation->getData(
'publicationId'));
380 $submissionId = $publication->getData(
'submissionId');
382 throw new Exception(
'Cannot load record: invalid representation id.');
385 case ASSOC_TYPE_SUBMISSION:
386 if (!$isFile && !$isRepresentation) $submissionId = $assocId;
388 $submission = $submissionDao->getById($submissionId);
390 $contextId = $submission->getContextId();
391 $submissionId = $submission->getId();
392 $sectionId = $submission->getSectionId();
394 throw new Exception(
'Cannot load record: invalid submission id.');
396 list($assocObjectType, $assocObjectId) = $this->
getAssocObjectInfo($submissionId, $contextId);
398 case ASSOC_TYPE_SECTION:
400 $section = $sectionDao->getById($assocId);
402 $sectionId = $section->getId();
403 $contextId = $section->getContextId();
405 throw new Exception(
'Cannot load record: invalid section id.');
410 $context = $contextDao->getById($assocId);
412 throw new Exception(
'Cannot load record: invalid context id.');
414 $contextId = $assocId;
418 return array($contextId, $sectionId, $assocObjectType, $assocObjectId, $submissionId, $representationId);
431 return array(
null,
null);