ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilWikiStat.php
Go to the documentation of this file.
1 <?php
2 
94 {
95  public const EVENT_PAGE_CREATED = 1;
96  public const EVENT_PAGE_UPDATED = 2;
97  public const EVENT_PAGE_READ = 3;
98  public const EVENT_PAGE_DELETED = 4;
99  public const EVENT_PAGE_RATING = 5;
100 
101  public const KEY_FIGURE_WIKI_NUM_PAGES = 1;
102  public const KEY_FIGURE_WIKI_NEW_PAGES = 2;
104  public const KEY_FIGURE_WIKI_EDIT_PAGES = 4;
107  public const KEY_FIGURE_WIKI_READ_PAGES = 7;
110  public const KEY_FIGURE_WIKI_NUM_RATING = 10;
112  public const KEY_FIGURE_WIKI_RATING_AVG = 12;
117  public const KEY_FIGURE_WIKI_WORDS = 17;
118  public const KEY_FIGURE_WIKI_WORDS_AVG = 18;
119  public const KEY_FIGURE_WIKI_CHARS = 19;
120  public const KEY_FIGURE_WIKI_CHARS_AVG = 20;
121  public const KEY_FIGURE_WIKI_FOOTNOTES = 21;
122  public const KEY_FIGURE_WIKI_FOOTNOTES_AVG = 22;
123 
124  public const KEY_FIGURE_WIKI_PAGE_CHANGES = 23;
127  public const KEY_FIGURE_WIKI_PAGE_READ = 26;
130  public const KEY_FIGURE_WIKI_PAGE_WORDS = 29;
131  public const KEY_FIGURE_WIKI_PAGE_CHARS = 30;
133  public const KEY_FIGURE_WIKI_PAGE_RATINGS = 32;
134 
135  //
136  // WRITE
137  //
138 
142  public static function handleEvent(
143  int $a_event,
144  ilWikiPage $a_page_obj,
145  ?int $a_user_id = null,
146  array $a_additional_data = null
147  ): void {
148  global $DIC;
149 
150  $ilUser = $DIC->user();
151 
152  if (!$a_user_id) {
153  $a_user_id = $ilUser->getId();
154  }
155  if (!$a_user_id || $a_user_id === ANONYMOUS_USER_ID) {
156  return;
157  }
158 
159  switch ($a_event) {
160  case self::EVENT_PAGE_CREATED:
161  self::handlePageCreated($a_page_obj, $a_user_id);
162  break;
163 
164  case self::EVENT_PAGE_UPDATED:
165  self::handlePageUpdated($a_page_obj, $a_user_id, $a_additional_data);
166  break;
167 
168  case self::EVENT_PAGE_READ:
169  self::handlePageRead($a_page_obj, $a_user_id);
170  break;
171 
172  case self::EVENT_PAGE_DELETED:
173  self::handlePageDeletion($a_page_obj, $a_user_id);
174  break;
175 
176  case self::EVENT_PAGE_RATING:
177  self::handlePageRating($a_page_obj, $a_user_id);
178  break;
179 
180  default:
181  }
182  }
183 
187  protected static function getTimestamp(): string
188  {
189  return date("Y-m-d H:00:00");
190  }
191 
198  protected static function writeData(
199  string $a_table,
200  array $a_primary,
201  array $a_values
202  ): bool {
203  global $DIC;
204 
205  $ilDB = $DIC->database();
206 
207  $tstamp = self::getTimestamp();
208  $a_primary["ts"] = array("timestamp", $tstamp);
209 
210  $ilAtomQuery = $ilDB->buildAtomQuery();
211  $ilAtomQuery->addTableLock($a_table);
212 
213  $ilAtomQuery->addQueryCallable(
214  function (ilDBInterface $ilDB) use ($a_table, $a_primary, $a_values, $tstamp, &$is_update) {
215  $primary = array();
216  foreach ($a_primary as $column => $value) {
217  $primary[] = $column . " = " . $ilDB->quote($value[1], $value[0]);
218  }
219  $primary = implode(" AND ", $primary);
220 
221  $set = $ilDB->query("SELECT ts FROM " . $a_table .
222  " WHERE " . $primary);
223 
224  $is_update = (bool) $ilDB->numRows($set);
225 
226  // update (current timeframe)
227  if ($is_update) {
228  $values = array();
229  foreach ($a_values as $column => $value) {
230  if ($value[0] === "increment") {
231  $values[] = $column . " = " . $column . "+1";
232  } elseif ($value[0] === "decrement") {
233  $values[] = $column . " = " . $column . "-1";
234  } else {
235  $values[] = $column . " = " . $ilDB->quote($value[1], $value[0]);
236  }
237  }
238  $values = implode(", ", $values);
239 
240  $sql = "UPDATE " . $a_table .
241  " SET " . $values .
242  " WHERE " . $primary;
243  }
244  // insert (no entry yet for current time frame)
245  else {
246  $a_values = array_merge($a_primary, $a_values);
247  $a_values["ts_day"] = array("text", substr($tstamp, 0, 10));
248  $a_values["ts_hour"] = array("integer", (int) substr($tstamp, 11, 2));
249 
250  $values = array();
251  foreach ($a_values as $column => $value) {
252  $columns[] = $column;
253  if ($value[0] === "increment") {
254  $value[0] = "integer";
255  } elseif ($value[0] === "decrement") {
256  $value[0] = "integer";
257  $value[1] = 0;
258  }
259  $values[] = $ilDB->quote($value[1], $value[0]);
260  }
261  $values = implode(", ", $values);
262  $columns = implode(", ", $columns);
263 
264  $sql = "INSERT INTO " . $a_table .
265  " (" . $columns . ")" .
266  " VALUES (" . $values . ")";
267  }
268  $ilDB->manipulate($sql);
269  }
270  );
271  $ilAtomQuery->run();
272 
273  return $is_update;
274  }
275 
279  protected static function writeStat(
280  string $a_wiki_id,
281  array $a_values
282  ): bool {
283  $primary = array(
284  "wiki_id" => array("integer", $a_wiki_id)
285  );
286  return self::writeData("wiki_stat", $primary, $a_values);
287  }
288 
295  protected static function writeStatPage(
296  int $a_wiki_id,
297  int $a_page_id,
298  array $a_values
299  ): void {
300  $primary = array(
301  "wiki_id" => array("integer", $a_wiki_id),
302  "page_id" => array("integer", $a_page_id),
303  );
304  self::writeData("wiki_stat_page", $primary, $a_values);
305  }
306 
310  protected static function writeStatPageUser(
311  int $a_wiki_id,
312  int $a_page_id,
313  int $a_user_id,
314  array $a_values
315  ): void {
316  $primary = array(
317  "wiki_id" => array("integer", $a_wiki_id),
318  "page_id" => array("integer", $a_page_id),
319  "user_id" => array("integer", $a_user_id)
320  );
321  self::writeData("wiki_stat_page_user", $primary, $a_values);
322  }
323 
327  protected static function writeStatUser(
328  int $a_wiki_id,
329  int $a_user_id,
330  array $a_values
331  ): void {
332  $primary = array(
333  "wiki_id" => array("integer", $a_wiki_id),
334  "user_id" => array("integer", $a_user_id)
335  );
336  self::writeData("wiki_stat_user", $primary, $a_values);
337  }
338 
342  protected static function countPages(
343  int $a_wiki_id
344  ): int {
345  return count(ilWikiPage::getAllWikiPages($a_wiki_id));
346  }
347 
351  protected static function getAverageRating(
352  int $a_wiki_id,
353  ?int $a_page_id = null
354  ): array {
355  if (!$a_page_id) {
357  $a_wiki_id,
358  "wiki"
359  );
360  } else {
362  $a_wiki_id,
363  "wiki",
364  $a_page_id,
365  "wpg"
366  );
367  }
368  }
369 
373  public static function handlePageCreated(
374  ilWikiPage $a_page_obj,
375  int $a_user_id
376  ): void {
377  // wiki: num_pages (count)
378  self::writeStat(
379  $a_page_obj->getWikiId(),
380  array(
381  "num_pages" => array("integer", self::countPages($a_page_obj->getWikiId())),
382  "del_pages" => array("integer", 0),
383  "avg_rating" => array("integer", 0)
384  )
385  );
386 
387  // user: new_pages+1
388  self::writeStatUser(
389  $a_page_obj->getWikiId(),
390  $a_user_id,
391  array(
392  "new_pages" => array("increment", 1)
393  )
394  );
395  }
396 
400  public static function handlePageUpdated(
401  ilWikiPage $a_page_obj,
402  int $a_user_id,
403  array $a_page_data = null
404  ): void {
405  // page_user: changes+1
406  self::writeStatPageUser(
407  $a_page_obj->getWikiId(),
408  $a_page_obj->getId(),
409  $a_user_id,
410  array(
411  "changes" => array("increment", 1)
412  )
413  );
414 
415  // page: see ilWikiPage::afterUpdate()
416  $values = array(
417  "int_links" => array("integer", $a_page_data["int_links"]),
418  "ext_links" => array("integer", $a_page_data["ext_links"]),
419  "footnotes" => array("integer", $a_page_data["footnotes"]),
420  "num_words" => array("integer", $a_page_data["num_words"]),
421  "num_chars" => array("integer", $a_page_data["num_chars"]),
422  "num_ratings" => array("integer", 0),
423  "avg_rating" => array("integer", 0)
424  );
425  self::writeStatPage($a_page_obj->getWikiId(), $a_page_obj->getId(), $values);
426  }
427 
428  public static function handlePageRead(
429  ilWikiPage $a_page_obj,
430  int $a_user_id
431  ): void {
432  // page_user: read_events+1
433  self::writeStatPageUser(
434  $a_page_obj->getWikiId(),
435  $a_page_obj->getId(),
436  $a_user_id,
437  array(
438  "read_events" => array("increment", 1)
439  )
440  );
441  }
442 
443  public static function handlePageDeletion(
444  ilWikiPage $a_page_obj,
445  int $a_user_id
446  ): void {
447  global $DIC;
448 
449  $ilDB = $DIC->database();
450 
451  // copy last entry to have deletion timestamp
452  $sql = "SELECT * " .
453  " FROM wiki_stat_page" .
454  " WHERE wiki_id = " . $ilDB->quote($a_page_obj->getWikiId(), "integer") .
455  " AND page_id = " . $ilDB->quote($a_page_obj->getId(), "integer") .
456  " ORDER BY ts DESC";
457  $ilDB->setLimit(1, 0);
458  $set = $ilDB->query($sql);
459 
460  // #15748
461  if ($ilDB->numRows($set)) {
462  $data = $ilDB->fetchAssoc($set);
463 
464  // see self::handlePageUpdated()
465  $values = array(
466  "int_links" => array("integer", $data["int_links"]),
467  "ext_links" => array("integer", $data["ext_links"]),
468  "footnotes" => array("integer", $data["footnotes"]),
469  "num_words" => array("integer", $data["num_words"]),
470  "num_chars" => array("integer", $data["num_chars"]),
471  "num_ratings" => array("integer", $data["num_ratings"]),
472  "avg_rating" => array("integer", $data["avg_rating"]),
473  );
474  self::writeStatPage($a_page_obj->getWikiId(), $a_page_obj->getId(), $values);
475  }
476 
477  // mark all page entries as deleted
478  $ilDB->manipulate("UPDATE wiki_stat_page" .
479  " SET deleted = " . $ilDB->quote(1, "integer") .
480  " WHERE page_id = " . $ilDB->quote($a_page_obj->getId(), "integer") .
481  " AND wiki_id = " . $ilDB->quote($a_page_obj->getWikiId(), "integer"));
482 
483  // wiki: del_pages+1, num_pages (count), avg_rating
484  $rating = self::getAverageRating($a_page_obj->getWikiId());
485  self::writeStat(
486  $a_page_obj->getWikiId(),
487  array(
488  "del_pages" => array("increment", 1),
489  "num_pages" => array("integer", self::countPages($a_page_obj->getWikiId())),
490  "avg_rating" => array("integer", $rating["avg"] * 100)
491  )
492  );
493  }
494 
495  public static function handlePageRating(
496  ilWikiPage $a_page_obj,
497  int $a_user_id
498  ): void {
499  // do page first!
500  $rating = self::getAverageRating($a_page_obj->getWikiId(), $a_page_obj->getId());
501 
502  // wiki_stat_page: num_ratings, avg_rating
503  self::writeStatPage(
504  $a_page_obj->getWikiId(),
505  $a_page_obj->getId(),
506  array(
507  "num_ratings" => array("integer", $rating["cnt"]),
508  "avg_rating" => array("integer", $rating["avg"] * 100),
509  )
510  );
511 
512  $rating = self::getAverageRating($a_page_obj->getWikiId());
513 
514  // wiki_stat: avg_rating
515  $is_update = self::writeStat(
516  $a_page_obj->getWikiId(),
517  array(
518  "avg_rating" => array("integer", $rating["avg"] * 100)
519  )
520  );
521 
522  if (!$is_update) {
523  // wiki: num_pages (count)
524  self::writeStat(
525  $a_page_obj->getWikiId(),
526  array(
527  "num_pages" => array("integer", self::countPages($a_page_obj->getWikiId()))
528  )
529  );
530  }
531  }
532 
533 
534  //
535  // READ HELPER
536  //
537 
538  protected static function getWikiAggr(
539  int $a_wiki_id,
540  string $a_day_from,
541  string $a_day_to,
542  string $a_table,
543  string $a_field,
544  string $a_aggr_value,
545  ?string $a_sub_field = null,
546  ?int $a_sub_id = null,
547  bool $a_build_full_period = false
548  ): array {
549  global $DIC;
550 
551  $ilDB = $DIC->database();
552 
553  $res = array();
554  $deleted = null;
555 
556  $sql = "SELECT ts_day, " . sprintf($a_aggr_value, $a_field) . " " . $a_field;
557  if ($a_table === "wiki_stat_page" && $a_sub_field) {
558  $sql .= ", MAX(deleted) deleted";
559  }
560  $sql .= " FROM " . $a_table .
561  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
562  " AND ts_day >= " . $ilDB->quote($a_day_from, "text") .
563  " AND ts_day <= " . $ilDB->quote($a_day_to, "text");
564  if (!$a_build_full_period) {
565  // to build full period data we need all values in DB
566  $sql .= " AND " . $a_field . " > " . $ilDB->quote(0, "integer") .
567  " AND " . $a_field . " IS NOT NULL";
568  }
569  if ($a_sub_field) {
570  $sql .= " AND " . $a_sub_field . " = " . $ilDB->quote($a_sub_id, "integer");
571  }
572  $sql .= " GROUP BY ts_day" .
573  " ORDER BY ts_day";
574  $set = $ilDB->query($sql);
575  while ($row = $ilDB->fetchAssoc($set)) {
576  $res[$row["ts_day"]] = $row[$a_field];
577 
578  $deleted = max(($row["deleted"] ?? 0), $deleted);
579  }
580 
581  if ($a_build_full_period) {
582  $period_first = $a_day_from;
583  $period_last = $a_day_to;
584 
585  // check if sub was deleted in period
586  if ($a_table === "wiki_stat_page" && $a_sub_field && $deleted) {
587  $sql = "SELECT MAX(ts_day) last_day, MIN(ts_day) first_day" .
588  " FROM " . $a_table .
589  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
590  " AND " . $a_sub_field . " = " . $ilDB->quote($a_sub_id, "integer");
591  $set = $ilDB->query($sql);
592  $row = $ilDB->fetchAssoc($set);
593  $last_day = $row["last_day"];
594  if ($last_day < $period_last) {
595  $period_last = $last_day;
596  }
597  $first_day = $row["first_day"];
598  if ($first_day > $period_first) {
599  $period_first = $first_day;
600  }
601  }
602 
603  $last_before_period = null;
604  if (!($res[$a_day_from] ?? false)) {
605  $last_before_period = self::getWikiLast($a_wiki_id, $a_day_from, $a_table, $a_field, $a_sub_field, $a_sub_id);
606  }
607 
608  // no need to allow zero here as we are not building averages
609  self::buildFullPeriodData($res, $period_first, $period_last, $last_before_period);
610  }
611 
612  return $res;
613  }
614 
615  protected static function getWikiLast(
616  int $a_wiki_id,
617  string $a_day_from,
618  string $a_table,
619  string $a_field,
620  ?string $a_sub_field = null,
621  ?int $a_sub_id = null
622  ): int {
623  global $DIC;
624 
625  $ilDB = $DIC->database();
626 
627  // get last existing value before period (zero is valid)
628  $sql = "SELECT MAX(" . $a_field . ") latest" .
629  " FROM " . $a_table .
630  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
631  " AND ts_day < " . $ilDB->quote($a_day_from, "text");
632  if ($a_sub_field) {
633  $sql .= " AND " . $a_sub_field . " = " . $ilDB->quote($a_sub_id, "integer");
634  }
635  $sql .= " GROUP BY ts_day" .
636  " ORDER BY ts_day DESC";
637  $ilDB->setLimit(1, 0);
638  $set = $ilDB->query($sql);
639  $last_before_period = $ilDB->fetchAssoc($set);
640  return (int) ($last_before_period["latest"] ?? 0);
641  }
642 
643  protected static function getWikiAggrSub(
644  int $a_wiki_id,
645  string $a_day_from,
646  string $a_day_to,
647  string $a_table,
648  string $a_field,
649  string $a_aggr_by,
650  string $a_aggr_value,
651  string $a_aggr_sub,
652  ?string $a_sub_field = null,
653  ?int $a_sub_id = null,
654  bool $a_build_full_period = false
655  ): array {
656  global $DIC;
657 
658  $ilDB = $DIC->database();
659 
660  $res = array();
661 
662  if (!$a_build_full_period) {
663  $sql = "SELECT ts_day, " . sprintf($a_aggr_value, $a_field) . " " . $a_field .
664  " FROM (" .
665  // subquery to build average per $a_aggr_by
666  " SELECT ts_day, " . sprintf($a_aggr_sub, $a_field) . " " . $a_field .
667  " FROM " . $a_table .
668  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
669  " AND ts_day >= " . $ilDB->quote($a_day_from, "text") .
670  " AND ts_day <= " . $ilDB->quote($a_day_to, "text") .
671  " AND " . $a_field . " > " . $ilDB->quote(0, "integer") .
672  " AND " . $a_field . " IS NOT NULL";
673  if ($a_sub_field) {
674  $sql .= " AND " . $a_sub_field . " = " . $ilDB->quote($a_sub_id, "integer");
675  }
676  $sql .= " GROUP BY ts_day, " . $a_aggr_by .
677  ") aggr_sub" .
678  " GROUP BY ts_day" .
679  " ORDER BY ts_day";
680  $set = $ilDB->query($sql);
681  while ($row = $ilDB->fetchAssoc($set)) {
682  $res[$row["ts_day"]] = $row[$a_field];
683  }
684  } else {
685  $tmp = $all_aggr_ids = $deleted_in_period = $first_day_in_period = array();
686 
687  if ($a_table !== "wiki_stat_page") {
688  echo "can only build full period averages for wiki_stat_page";
689  exit();
690  }
691 
692  // as current period can be totally empty, gather existing subs
693  $sql = " SELECT *" .
694  " FROM (" .
695  " SELECT " . $a_aggr_by . ", MAX(deleted) deleted, MAX(ts_day) last_day, MIN(ts_day) first_day" .
696  " FROM " . $a_table .
697  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
698  " GROUP BY " . $a_aggr_by .
699  ") aggr_sub" .
700  " WHERE first_day <= " . $ilDB->quote($a_day_to, "text") . // not created after period
701  " AND (last_day >= " . $ilDB->quote($a_day_from, "text") . // (deleted in/after period
702  " OR deleted = " . $ilDB->quote(0, "integer") . ")"; // or still existing)
703  $set = $ilDB->query($sql);
704  while ($row = $ilDB->fetchAssoc($set)) {
705  $all_aggr_ids[] = $row[$a_aggr_by];
706 
707  // if deleted in period we need the last day
708  if ($row["deleted"] && $row["last_day"] < $a_day_to) {
709  $deleted_in_period[$row[$a_aggr_by]] = $row["last_day"];
710  }
711  // if created in period we need the first day
712  if ($row["first_day"] > $a_day_from) {
713  $first_day_in_period[$row[$a_aggr_by]] = $row["first_day"];
714  }
715  }
716 
717  // we need to build average manually after completing period data (zero is valid)
718  $sql = " SELECT ts_day, " . $a_aggr_by . ", " . sprintf($a_aggr_sub, $a_field) . " " . $a_field .
719  " FROM " . $a_table .
720  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
721  " AND ts_day >= " . $ilDB->quote($a_day_from, "text") .
722  " AND ts_day <= " . $ilDB->quote($a_day_to, "text");
723  $sql .= " GROUP BY ts_day, " . $a_aggr_by;
724  $set = $ilDB->query($sql);
725  while ($row = $ilDB->fetchAssoc($set)) {
726  if (!in_array($row[$a_aggr_by], $all_aggr_ids)) {
727  throw new ilWikiException("Unexpected wiki_stat_page_entry: " . print_r($row, true));
728  }
729  $tmp[$row[$a_aggr_by]][$row["ts_day"]] = $row[$a_field];
730  }
731 
732  // build full period for each sub
733  foreach ($all_aggr_ids as $aggr_by_id) {
734  // last of entry of sub is before period
735  if (!isset($tmp[$aggr_by_id])) {
736  $tmp[$aggr_by_id] = array();
737  }
738 
739  // get last value before period to add missing entries in period
740  $last_before_period = null;
741  if (!($tmp[$aggr_by_id][$a_day_from] ?? false)) {
742  $last_before_period = self::getWikiLast($a_wiki_id, $a_day_from, $a_table, $a_field, $a_aggr_by, $aggr_by_id);
743  }
744 
745  // if sub was created in period (see above), shorten period accordingly
746  $first_period_day = $first_day_in_period[$aggr_by_id] ?? $a_day_from;
747 
748  // if sub was deleted in period (see above), shorten period accordingly
749  $last_period_day = $deleted_in_period[$aggr_by_id] ?? $a_day_to;
750 
751  // allow zero as we need to correct number of valid subs per day (see below - AVG)
752  self::buildFullPeriodData($tmp[$aggr_by_id], $first_period_day, $last_period_day, $last_before_period, true);
753 
754  // distribute sub to days
755  foreach ($tmp[$aggr_by_id] as $day => $value) {
756  $res[$day][$aggr_by_id] = $value;
757  }
758  }
759 
760  // build average over subs
761  foreach ($res as $day => $values) {
762  switch ($a_aggr_value) {
763  case "AVG(%s)":
764  $res[$day] = array_sum($values) / count($values);
765  break;
766 
767  case "SUM(%s)":
768  $res[$day] = array_sum($values);
769  break;
770 
771  default:
772  throw new ilWikiException("Wiki: unsupport aggr " . $a_aggr_value);
773  break;
774  }
775  }
776  }
777 
778  return $res;
779  }
780 
781  protected static function buildFullPeriodData(
782  array &$a_res,
783  string $a_day_from,
784  string $a_day_to,
785  ?int $a_last_before_period = null,
786  bool $a_allow_zero = false
787  ): void {
788  // build full data for period
789  $safety = 0;
790  $last = null;
791  $today = date("Y-m-d");
792  $current = explode("-", $a_day_from);
793  $current = date("Y-m-d", mktime(0, 0, 1, $current[1], $current[2], $current[0]));
794  while ($current <= $a_day_to &&
795  ++$safety < 1000) {
796  if (!isset($a_res[$current])) {
797  if ($current <= $today) {
798  // last existing value in period
799  if ($last !== null) {
800  $a_res[$current] = $last;
801  }
802  // last existing value before period
803  elseif ($a_last_before_period || $a_allow_zero) {
804  $a_res[$current] = $a_last_before_period;
805  }
806  }
807  } else {
808  $last = $a_res[$current];
809  }
810 
811  $current = explode("-", $current);
812  $current = date("Y-m-d", mktime(0, 0, 1, $current[1], $current[2] + 1, $current[0]));
813  }
814  }
815 
816 
817  //
818  // READ WIKI
819  //
820 
821  protected static function getWikiNumPages(
822  int $a_wiki_id,
823  string $a_day_from,
824  string $a_day_to
825  ): array {
826  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat", "num_pages", "MAX(%s)", null, null, true);
827  }
828 
829  protected static function getWikiNewPagesSum(
830  int $a_wiki_id,
831  string $a_day_from,
832  string $a_day_to
833  ): array {
834  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_user", "new_pages", "SUM(%s)");
835  }
836 
837  protected static function getWikiNewPagesAvg(
838  int $a_wiki_id,
839  string $a_day_from,
840  string $a_day_to
841  ): array {
842  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_user", "new_pages", "user_id", "AVG(%s)", "SUM(%s)");
843  }
844 
845  protected static function getWikiDeletedPages(
846  int $a_wiki_id,
847  string $a_day_from,
848  string $a_day_to
849  ): array {
850  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat", "del_pages", "SUM(%s)");
851  }
852 
853  protected static function getWikiReadPages(
854  int $a_wiki_id,
855  string $a_day_from,
856  string $a_day_to
857  ): array {
858  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page_user", "read_events", "SUM(%s)");
859  }
860 
861  protected static function getWikiEditPagesSum(
862  int $a_wiki_id,
863  string $a_day_from,
864  string $a_day_to
865  ): array {
866  global $DIC;
867 
868  $ilDB = $DIC->database();
869 
870  $res = array();
871 
872  $sql = "SELECT ts_day, COUNT(DISTINCT(page_id)) num_changed_pages" .
873  " FROM wiki_stat_page_user" .
874  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
875  " AND ts_day >= " . $ilDB->quote($a_day_from, "text") .
876  " AND ts_day <= " . $ilDB->quote($a_day_to, "text") .
877  " AND changes > " . $ilDB->quote(0, "integer") .
878  " AND changes IS NOT NULL" .
879  " GROUP BY ts_day" .
880  " ORDER BY ts_day";
881  $set = $ilDB->query($sql);
882  while ($row = $ilDB->fetchAssoc($set)) {
883  $res[$row["ts_day"]] = $row["num_changed_pages"];
884  }
885 
886  return $res;
887  }
888 
889  protected static function getWikiEditPagesAvg(
890  int $a_wiki_id,
891  string $a_day_from,
892  string $a_day_to
893  ): array {
894  global $DIC;
895 
896  $ilDB = $DIC->database();
897 
898  $res = array();
899 
900  $sql = "SELECT ts_day, AVG(num_changed_pages) num_changed_pages" .
901  " FROM (" .
902  // subquery to build average per user
903  " SELECT ts_day, COUNT(DISTINCT(page_id)) num_changed_pages" .
904  " FROM wiki_stat_page_user" .
905  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
906  " AND ts_day >= " . $ilDB->quote($a_day_from, "text") .
907  " AND ts_day <= " . $ilDB->quote($a_day_to, "text") .
908  " AND changes > " . $ilDB->quote(0, "integer") .
909  " AND changes IS NOT NULL" .
910  " GROUP BY ts_day, user_id" .
911  ") aggr_user" .
912  " GROUP BY ts_day" .
913  " ORDER BY ts_day";
914  $set = $ilDB->query($sql);
915  while ($row = $ilDB->fetchAssoc($set)) {
916  $res[$row["ts_day"]] = $row["num_changed_pages"];
917  }
918 
919  return $res;
920  }
921 
922  protected static function getWikiUserEditPages(
923  int $a_wiki_id,
924  string $a_day_from,
925  string $a_day_to,
926  ?string $a_sub_field = null,
927  ?int $a_sub_id = null
928  ): array {
929  global $DIC;
930 
931  $ilDB = $DIC->database();
932 
933  $res = array();
934 
935  $sql = "SELECT ts_day, COUNT(DISTINCT(user_id)) num_changed_users" .
936  " FROM wiki_stat_page_user" .
937  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
938  " AND ts_day >= " . $ilDB->quote($a_day_from, "text") .
939  " AND ts_day <= " . $ilDB->quote($a_day_to, "text") .
940  " AND changes > " . $ilDB->quote(0, "integer") .
941  " AND changes IS NOT NULL";
942  if ($a_sub_field) {
943  $sql .= " AND " . $a_sub_field . " = " . $ilDB->quote($a_sub_id, "integer");
944  }
945  $sql .= " GROUP BY ts_day" .
946  " ORDER BY ts_day";
947  $set = $ilDB->query($sql);
948  while ($row = $ilDB->fetchAssoc($set)) {
949  $res[$row["ts_day"]] = $row["num_changed_users"];
950  }
951 
952  return $res;
953  }
954 
955  protected static function getWikiUserEditPagesAvg(
956  int $a_wiki_id,
957  string $a_day_from,
958  string $a_day_to
959  ): array {
960  global $DIC;
961 
962  $ilDB = $DIC->database();
963 
964  $res = array();
965 
966  $sql = "SELECT ts_day, AVG(num_changed_users) num_changed_users" .
967  " FROM (" .
968  // subquery to build average per page
969  " SELECT ts_day, COUNT(DISTINCT(user_id)) num_changed_users" .
970  " FROM wiki_stat_page_user" .
971  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
972  " AND ts_day >= " . $ilDB->quote($a_day_from, "text") .
973  " AND ts_day <= " . $ilDB->quote($a_day_to, "text") .
974  " AND changes > " . $ilDB->quote(0, "integer") .
975  " AND changes IS NOT NULL" .
976  " GROUP BY ts_day, page_id" .
977  ") aggr_user" .
978  " GROUP BY ts_day" .
979  " ORDER BY ts_day";
980  $set = $ilDB->query($sql);
981  while ($row = $ilDB->fetchAssoc($set)) {
982  $res[$row["ts_day"]] = $row["num_changed_users"];
983  }
984 
985  return $res;
986  }
987 
988  protected static function getWikiNumRating(
989  int $a_wiki_id,
990  string $a_day_from,
991  string $a_day_to
992  ): array {
993  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_ratings", "SUM(%s)");
994  }
995 
996  protected static function getWikiNumRatingAvg(
997  int $a_wiki_id,
998  string $a_day_from,
999  string $a_day_to
1000  ): array {
1001  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_ratings", "page_id", "AVG(%s)", "SUM(%s)");
1002  }
1003 
1004  protected static function getWikiRatingAvg(
1005  int $a_wiki_id,
1006  string $a_day_from,
1007  string $a_day_to
1008  ): array {
1009  $res = self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat", "avg_rating", "AVG(%s)");
1010 
1011  foreach (array_keys($res) as $day) {
1012  // int-to-float
1013  $res[$day] /= 100;
1014  }
1015 
1016  return $res;
1017  }
1018 
1019  protected static function getWikiInternalLinks(
1020  int $a_wiki_id,
1021  string $a_day_from,
1022  string $a_day_to
1023  ): array {
1024  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "int_links", "page_id", "SUM(%s)", "MAX(%s)", null, null, true);
1025  }
1026 
1027  protected static function getWikiInternalLinksAvg(
1028  int $a_wiki_id,
1029  string $a_day_from,
1030  string $a_day_to
1031  ): array {
1032  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "int_links", "page_id", "AVG(%s)", "MAX(%s)", null, null, true);
1033  }
1034 
1035  protected static function getWikiExternalLinks(
1036  int $a_wiki_id,
1037  string $a_day_from,
1038  string $a_day_to
1039  ): array {
1040  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "ext_links", "page_id", "SUM(%s)", "MAX(%s)", null, null, true);
1041  }
1042 
1043  protected static function getWikiExternalLinksAvg(
1044  int $a_wiki_id,
1045  string $a_day_from,
1046  string $a_day_to
1047  ): array {
1048  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "ext_links", "page_id", "AVG(%s)", "MAX(%s)", null, null, true);
1049  }
1050 
1051  protected static function getWikiWords(
1052  int $a_wiki_id,
1053  string $a_day_from,
1054  string $a_day_to
1055  ): array {
1056  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_words", "page_id", "SUM(%s)", "MAX(%s)", null, null, true);
1057  }
1058 
1059  protected static function getWikiWordsAvg(
1060  int $a_wiki_id,
1061  string $a_day_from,
1062  string $a_day_to
1063  ): array {
1064  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_words", "page_id", "AVG(%s)", "MAX(%s)", null, null, true);
1065  }
1066 
1067  protected static function getWikiCharacters(
1068  int $a_wiki_id,
1069  string $a_day_from,
1070  string $a_day_to
1071  ): array {
1072  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_chars", "page_id", "SUM(%s)", "MAX(%s)", null, null, true);
1073  }
1074 
1075  protected static function getWikiCharactersAvg(
1076  int $a_wiki_id,
1077  string $a_day_from,
1078  string $a_day_to
1079  ): array {
1080  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_chars", "page_id", "AVG(%s)", "MAX(%s)", null, null, true);
1081  }
1082 
1083  protected static function getWikiFootnotes(
1084  int $a_wiki_id,
1085  string $a_day_from,
1086  string $a_day_to
1087  ): array {
1088  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "footnotes", "page_id", "SUM(%s)", "MAX(%s)", null, null, true);
1089  }
1090 
1091  protected static function getWikiFootnotesAvg(
1092  int $a_wiki_id,
1093  string $a_day_from,
1094  string $a_day_to
1095  ): array {
1096  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "footnotes", "page_id", "AVG(%s)", "MAX(%s)", null, null, true);
1097  }
1098 
1099 
1100  //
1101  // READ PAGE
1102  //
1103 
1104  protected static function getWikiPageChanges(
1105  int $a_wiki_id,
1106  int $a_page_id,
1107  string $a_day_from,
1108  string $a_day_to
1109  ): array {
1110  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page_user", "changes", "SUM(%s)", "page_id", $a_page_id);
1111  }
1112 
1113  protected static function getWikiPageChangesAvg(
1114  int $a_wiki_id,
1115  int $a_page_id,
1116  string $a_day_from,
1117  string $a_day_to
1118  ): array {
1119  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page_user", "changes", "user_id", "AVG(%s)", "SUM(%s)", "page_id", $a_page_id);
1120  }
1121 
1122  protected static function getWikiPageUserEdit(
1123  int $a_wiki_id,
1124  int $a_page_id,
1125  string $a_day_from,
1126  string $a_day_to
1127  ): array {
1128  return self::getWikiUserEditPages($a_wiki_id, $a_day_from, $a_day_to, "page_id", $a_page_id);
1129  }
1130 
1131  protected static function getWikiPageRead(
1132  int $a_wiki_id,
1133  int $a_page_id,
1134  string $a_day_from,
1135  string $a_day_to
1136  ): array {
1137  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page_user", "read_events", "SUM(%s)", "page_id", $a_page_id);
1138  }
1139 
1140  protected static function getWikiPageInternalLinks(
1141  int $a_wiki_id,
1142  int $a_page_id,
1143  string $a_day_from,
1144  string $a_day_to
1145  ): array {
1146  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "int_links", "MAX(%s)", "page_id", $a_page_id, true);
1147  }
1148 
1149  protected static function getWikiPageExternalLinks(
1150  int $a_wiki_id,
1151  int $a_page_id,
1152  string $a_day_from,
1153  string $a_day_to
1154  ): array {
1155  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "ext_links", "MAX(%s)", "page_id", $a_page_id, true);
1156  }
1157 
1158  protected static function getWikiPageWords(
1159  int $a_wiki_id,
1160  int $a_page_id,
1161  string $a_day_from,
1162  string $a_day_to
1163  ): array {
1164  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_words", "MAX(%s)", "page_id", $a_page_id, true);
1165  }
1166 
1167  protected static function getWikiPageCharacters(
1168  int $a_wiki_id,
1169  int $a_page_id,
1170  string $a_day_from,
1171  string $a_day_to
1172  ): array {
1173  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_chars", "MAX(%s)", "page_id", $a_page_id, true);
1174  }
1175 
1176  protected static function getWikiPageFootnotes(
1177  int $a_wiki_id,
1178  int $a_page_id,
1179  string $a_day_from,
1180  string $a_day_to
1181  ): array {
1182  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "footnotes", "MAX(%s)", "page_id", $a_page_id, true);
1183  }
1184 
1185  protected static function getWikiPageRatings(
1186  int $a_wiki_id,
1187  int $a_page_id,
1188  string $a_day_from,
1189  string $a_day_to
1190  ): array {
1191  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_ratings", "SUM(%s)", "page_id", $a_page_id);
1192  }
1193 
1194 
1195  //
1196  // GUI HELPER
1197  //
1198 
1199  public static function getAvailableMonths(
1200  int $a_wiki_id
1201  ): array {
1202  global $DIC;
1203 
1204  $ilDB = $DIC->database();
1205 
1206  $res = array();
1207 
1208  // because of read_events this db table is updated most often
1209  $set = $ilDB->query("SELECT DISTINCT(SUBSTR(ts_day, 1, 7)) " . $ilDB->quoteIdentifier("month") .
1210  " FROM wiki_stat_page_user" .
1211  " WHERE wiki_id = " . $ilDB->quote($a_wiki_id, "integer") .
1212  " AND ts_day IS NOT NULL");
1213  while ($row = $ilDB->fetchAssoc($set)) {
1214  $res[] = $row["month"];
1215  }
1216 
1217  return $res;
1218  }
1219 
1220  public static function getFigures(): array
1221  {
1222  return array(
1223  self::KEY_FIGURE_WIKI_NUM_PAGES
1224  ,self::KEY_FIGURE_WIKI_NEW_PAGES
1225  ,self::KEY_FIGURE_WIKI_NEW_PAGES_AVG
1226  ,self::KEY_FIGURE_WIKI_EDIT_PAGES
1227  ,self::KEY_FIGURE_WIKI_EDIT_PAGES_AVG
1228  ,self::KEY_FIGURE_WIKI_DELETED_PAGES
1229  ,self::KEY_FIGURE_WIKI_READ_PAGES
1230  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES
1231  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES_AVG
1232  ,self::KEY_FIGURE_WIKI_NUM_RATING
1233  ,self::KEY_FIGURE_WIKI_NUM_RATING_AVG
1234  ,self::KEY_FIGURE_WIKI_RATING_AVG
1235  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS
1236  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS_AVG
1237  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS
1238  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS_AVG
1239  ,self::KEY_FIGURE_WIKI_WORDS
1240  ,self::KEY_FIGURE_WIKI_WORDS_AVG
1241  ,self::KEY_FIGURE_WIKI_CHARS
1242  ,self::KEY_FIGURE_WIKI_CHARS_AVG
1243  ,self::KEY_FIGURE_WIKI_FOOTNOTES
1244  ,self::KEY_FIGURE_WIKI_FOOTNOTES_AVG
1245  );
1246  }
1247 
1248  public static function getFiguresPage(): array
1249  {
1250  return array(
1251  self::KEY_FIGURE_WIKI_PAGE_CHANGES
1252  ,self::KEY_FIGURE_WIKI_PAGE_CHANGES_AVG
1253  ,self::KEY_FIGURE_WIKI_PAGE_USER_EDIT
1254  ,self::KEY_FIGURE_WIKI_PAGE_READ
1255  ,self::KEY_FIGURE_WIKI_PAGE_INTERNAL_LINKS
1256  ,self::KEY_FIGURE_WIKI_PAGE_EXTERNAL_LINKS
1257  ,self::KEY_FIGURE_WIKI_PAGE_WORDS
1258  ,self::KEY_FIGURE_WIKI_PAGE_CHARS
1259  ,self::KEY_FIGURE_WIKI_PAGE_FOOTNOTES
1260  ,self::KEY_FIGURE_WIKI_PAGE_RATINGS
1261  );
1262  }
1263 
1264  public static function getFigureTitle(
1265  int $a_figure
1266  ): string {
1267  global $DIC;
1268 
1269  $lng = $DIC->language();
1270 
1271  $map = array(
1272  // wiki
1273  self::KEY_FIGURE_WIKI_NUM_PAGES => $lng->txt("wiki_stat_num_pages")
1274  ,self::KEY_FIGURE_WIKI_NEW_PAGES => $lng->txt("wiki_stat_new_pages")
1275  ,self::KEY_FIGURE_WIKI_NEW_PAGES_AVG => $lng->txt("wiki_stat_new_pages_avg")
1276  ,self::KEY_FIGURE_WIKI_EDIT_PAGES => $lng->txt("wiki_stat_edit_pages")
1277  ,self::KEY_FIGURE_WIKI_EDIT_PAGES_AVG => $lng->txt("wiki_stat_edit_pages_avg")
1278  ,self::KEY_FIGURE_WIKI_DELETED_PAGES => $lng->txt("wiki_stat_deleted_pages")
1279  ,self::KEY_FIGURE_WIKI_READ_PAGES => $lng->txt("wiki_stat_read_pages")
1280  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES => $lng->txt("wiki_stat_user_edit_pages")
1281  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES_AVG => $lng->txt("wiki_stat_user_edit_pages_avg")
1282  ,self::KEY_FIGURE_WIKI_NUM_RATING => $lng->txt("wiki_stat_num_rating")
1283  ,self::KEY_FIGURE_WIKI_NUM_RATING_AVG => $lng->txt("wiki_stat_num_rating_avg")
1284  ,self::KEY_FIGURE_WIKI_RATING_AVG => $lng->txt("wiki_stat_rating_avg")
1285  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS => $lng->txt("wiki_stat_internal_links")
1286  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS_AVG => $lng->txt("wiki_stat_internal_links_avg")
1287  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS => $lng->txt("wiki_stat_external_links")
1288  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS_AVG => $lng->txt("wiki_stat_external_links_avg")
1289  ,self::KEY_FIGURE_WIKI_WORDS => $lng->txt("wiki_stat_words")
1290  ,self::KEY_FIGURE_WIKI_WORDS_AVG => $lng->txt("wiki_stat_words_avg")
1291  ,self::KEY_FIGURE_WIKI_CHARS => $lng->txt("wiki_stat_chars")
1292  ,self::KEY_FIGURE_WIKI_CHARS_AVG => $lng->txt("wiki_stat_chars_avg")
1293  ,self::KEY_FIGURE_WIKI_FOOTNOTES => $lng->txt("wiki_stat_footnotes")
1294  ,self::KEY_FIGURE_WIKI_FOOTNOTES_AVG => $lng->txt("wiki_stat_footnotes_avg")
1295  // page
1296  ,self::KEY_FIGURE_WIKI_PAGE_CHANGES => $lng->txt("wiki_stat_page_changes")
1297  ,self::KEY_FIGURE_WIKI_PAGE_CHANGES_AVG => $lng->txt("wiki_stat_page_changes_avg")
1298  ,self::KEY_FIGURE_WIKI_PAGE_USER_EDIT => $lng->txt("wiki_stat_page_user_edit")
1299  ,self::KEY_FIGURE_WIKI_PAGE_READ => $lng->txt("wiki_stat_page_read")
1300  ,self::KEY_FIGURE_WIKI_PAGE_INTERNAL_LINKS => $lng->txt("wiki_stat_page_internal_links")
1301  ,self::KEY_FIGURE_WIKI_PAGE_EXTERNAL_LINKS => $lng->txt("wiki_stat_page_external_links")
1302  ,self::KEY_FIGURE_WIKI_PAGE_WORDS => $lng->txt("wiki_stat_page_words")
1303  ,self::KEY_FIGURE_WIKI_PAGE_CHARS => $lng->txt("wiki_stat_page_characters")
1304  ,self::KEY_FIGURE_WIKI_PAGE_FOOTNOTES => $lng->txt("wiki_stat_page_footnotes")
1305  ,self::KEY_FIGURE_WIKI_PAGE_RATINGS => $lng->txt("wiki_stat_page_ratings")
1306  );
1307 
1308  return $map[$a_figure];
1309  }
1310 
1311  public static function getFigureData(
1312  int $a_wiki_id,
1313  int $a_figure,
1314  string $a_from,
1315  string $a_to
1316  ): array {
1317  switch ($a_figure) {
1318  case self::KEY_FIGURE_WIKI_NUM_PAGES:
1319  return self::getWikiNumPages($a_wiki_id, $a_from, $a_to);
1320 
1321  case self::KEY_FIGURE_WIKI_NEW_PAGES:
1322  return self::getWikiNewPagesSum($a_wiki_id, $a_from, $a_to);
1323 
1324  case self::KEY_FIGURE_WIKI_NEW_PAGES_AVG:
1325  return self::getWikiNewPagesAvg($a_wiki_id, $a_from, $a_to);
1326 
1327  case self::KEY_FIGURE_WIKI_EDIT_PAGES:
1328  return self::getWikiEditPagesSum($a_wiki_id, $a_from, $a_to);
1329 
1330  case self::KEY_FIGURE_WIKI_EDIT_PAGES_AVG:
1331  return self::getWikiEditPagesAvg($a_wiki_id, $a_from, $a_to);
1332 
1333  case self::KEY_FIGURE_WIKI_DELETED_PAGES:
1334  return self::getWikiDeletedPages($a_wiki_id, $a_from, $a_to);
1335 
1336  case self::KEY_FIGURE_WIKI_READ_PAGES:
1337  return self::getWikiReadPages($a_wiki_id, $a_from, $a_to);
1338 
1339  case self::KEY_FIGURE_WIKI_USER_EDIT_PAGES:
1340  return self::getWikiUserEditPages($a_wiki_id, $a_from, $a_to);
1341 
1342  case self::KEY_FIGURE_WIKI_USER_EDIT_PAGES_AVG:
1343  return self::getWikiUserEditPagesAvg($a_wiki_id, $a_from, $a_to);
1344 
1345  case self::KEY_FIGURE_WIKI_NUM_RATING:
1346  return self::getWikiNumRating($a_wiki_id, $a_from, $a_to);
1347 
1348  case self::KEY_FIGURE_WIKI_NUM_RATING_AVG:
1349  return self::getWikiNumRatingAvg($a_wiki_id, $a_from, $a_to);
1350 
1351  case self::KEY_FIGURE_WIKI_RATING_AVG:
1352  return self::getWikiRatingAvg($a_wiki_id, $a_from, $a_to);
1353 
1354  case self::KEY_FIGURE_WIKI_INTERNAL_LINKS:
1355  return self::getWikiInternalLinks($a_wiki_id, $a_from, $a_to);
1356 
1357  case self::KEY_FIGURE_WIKI_INTERNAL_LINKS_AVG:
1358  return self::getWikiInternalLinksAvg($a_wiki_id, $a_from, $a_to);
1359 
1360  case self::KEY_FIGURE_WIKI_EXTERNAL_LINKS:
1361  return self::getWikiExternalLinks($a_wiki_id, $a_from, $a_to);
1362 
1363  case self::KEY_FIGURE_WIKI_EXTERNAL_LINKS_AVG:
1364  return self::getWikiExternalLinksAvg($a_wiki_id, $a_from, $a_to);
1365 
1366  case self::KEY_FIGURE_WIKI_WORDS:
1367  return self::getWikiWords($a_wiki_id, $a_from, $a_to);
1368 
1369  case self::KEY_FIGURE_WIKI_WORDS_AVG:
1370  return self::getWikiWordsAvg($a_wiki_id, $a_from, $a_to);
1371 
1372  case self::KEY_FIGURE_WIKI_CHARS:
1373  return self::getWikiCharacters($a_wiki_id, $a_from, $a_to);
1374 
1375  case self::KEY_FIGURE_WIKI_CHARS_AVG:
1376  return self::getWikiCharactersAvg($a_wiki_id, $a_from, $a_to);
1377 
1378  case self::KEY_FIGURE_WIKI_FOOTNOTES:
1379  return self::getWikiFootnotes($a_wiki_id, $a_from, $a_to);
1380 
1381  case self::KEY_FIGURE_WIKI_FOOTNOTES_AVG:
1382  return self::getWikiFootnotesAvg($a_wiki_id, $a_from, $a_to);
1383  }
1384  return [];
1385  }
1386 
1387  public static function getFigureDataPage(
1388  int $a_wiki_id,
1389  int $a_page_id,
1390  int $a_figure,
1391  string $a_from,
1392  string $a_to
1393  ): array {
1394  switch ($a_figure) {
1395  case self::KEY_FIGURE_WIKI_PAGE_CHANGES:
1396  return self::getWikiPageChanges($a_wiki_id, $a_page_id, $a_from, $a_to);
1397 
1398  case self::KEY_FIGURE_WIKI_PAGE_CHANGES_AVG:
1399  return self::getWikiPageChangesAvg($a_wiki_id, $a_page_id, $a_from, $a_to);
1400 
1401  case self::KEY_FIGURE_WIKI_PAGE_USER_EDIT:
1402  return self::getWikiPageUserEdit($a_wiki_id, $a_page_id, $a_from, $a_to);
1403 
1404  case self::KEY_FIGURE_WIKI_PAGE_READ:
1405  return self::getWikiPageRead($a_wiki_id, $a_page_id, $a_from, $a_to);
1406 
1407  case self::KEY_FIGURE_WIKI_PAGE_INTERNAL_LINKS:
1408  return self::getWikiPageInternalLinks($a_wiki_id, $a_page_id, $a_from, $a_to);
1409 
1410  case self::KEY_FIGURE_WIKI_PAGE_EXTERNAL_LINKS:
1411  return self::getWikiPageExternalLinks($a_wiki_id, $a_page_id, $a_from, $a_to);
1412 
1413  case self::KEY_FIGURE_WIKI_PAGE_FOOTNOTES:
1414  return self::getWikiPageFootnotes($a_wiki_id, $a_page_id, $a_from, $a_to);
1415 
1416  case self::KEY_FIGURE_WIKI_PAGE_WORDS:
1417  return self::getWikiPageWords($a_wiki_id, $a_page_id, $a_from, $a_to);
1418 
1419  case self::KEY_FIGURE_WIKI_PAGE_CHARS:
1420  return self::getWikiPageCharacters($a_wiki_id, $a_page_id, $a_from, $a_to);
1421 
1422  case self::KEY_FIGURE_WIKI_PAGE_RATINGS:
1423  return self::getWikiPageRatings($a_wiki_id, $a_page_id, $a_from, $a_to);
1424  }
1425  return [];
1426  }
1427 
1428  public static function getFigureOptions(): array
1429  {
1430  $res = array();
1431 
1432  foreach (self::getFigures() as $figure) {
1433  $res[$figure] = self::getFigureTitle($figure);
1434  }
1435 
1436  return $res;
1437  }
1438 
1439  public static function getFigureOptionsPage(): array
1440  {
1441  $res = array();
1442 
1443  foreach (self::getFiguresPage() as $figure) {
1444  $res[$figure] = self::getFigureTitle($figure);
1445  }
1446 
1447  return $res;
1448  }
1449 }
static getFigureTitle(int $a_figure)
$res
Definition: ltiservices.php:69
const KEY_FIGURE_WIKI_PAGE_USER_EDIT
static getFigures()
static getWikiAggrSub(int $a_wiki_id, string $a_day_from, string $a_day_to, string $a_table, string $a_field, string $a_aggr_by, string $a_aggr_value, string $a_aggr_sub, ?string $a_sub_field=null, ?int $a_sub_id=null, bool $a_build_full_period=false)
const KEY_FIGURE_WIKI_NUM_RATING
static getWikiInternalLinks(int $a_wiki_id, string $a_day_from, string $a_day_to)
static getWikiNumRating(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_WORDS
exit
Definition: login.php:28
const KEY_FIGURE_WIKI_FOOTNOTES
const KEY_FIGURE_WIKI_USER_EDIT_PAGES
const KEY_FIGURE_WIKI_PAGE_RATINGS
numRows(ilDBStatement $statement)
const ANONYMOUS_USER_ID
Definition: constants.php:27
const KEY_FIGURE_WIKI_USER_EDIT_PAGES_AVG
const KEY_FIGURE_WIKI_PAGE_READ
const KEY_FIGURE_WIKI_FOOTNOTES_AVG
static getWikiNumRatingAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
$lng
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getAverageRating(int $a_wiki_id, ?int $a_page_id=null)
Get average rating for wiki or wiki page.
static getWikiPageChangesAvg(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_NEW_PAGES_AVG
const KEY_FIGURE_WIKI_PAGE_INTERNAL_LINKS
static getWikiPageExternalLinks(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
static getWikiEditPagesAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_INTERNAL_LINKS
static getWikiCharacters(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_NUM_RATING_AVG
const KEY_FIGURE_WIKI_NUM_PAGES
static getWikiWords(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_PAGE_CHARS
static getWikiLast(int $a_wiki_id, string $a_day_from, string $a_table, string $a_field, ?string $a_sub_field=null, ?int $a_sub_id=null)
const KEY_FIGURE_WIKI_PAGE_EXTERNAL_LINKS
const KEY_FIGURE_WIKI_EXTERNAL_LINKS_AVG
const KEY_FIGURE_WIKI_PAGE_FOOTNOTES
quote($value, string $type)
static handlePageCreated(ilWikiPage $a_page_obj, int $a_user_id)
Handle wiki page creation.
const EVENT_PAGE_READ
static getAllWikiPages(int $a_wiki_id)
static getWikiFootnotesAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_EXTERNAL_LINKS
static getWikiPageInternalLinks(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
global $DIC
Definition: feed.php:28
static getFigureDataPage(int $a_wiki_id, int $a_page_id, int $a_figure, string $a_from, string $a_to)
static getWikiPageCharacters(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
static getWikiCharactersAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
static handlePageRating(ilWikiPage $a_page_obj, int $a_user_id)
static getTimestamp()
Get current time frame (hourly)
static getWikiAggr(int $a_wiki_id, string $a_day_from, string $a_day_to, string $a_table, string $a_field, string $a_aggr_value, ?string $a_sub_field=null, ?int $a_sub_id=null, bool $a_build_full_period=false)
static handlePageRead(ilWikiPage $a_page_obj, int $a_user_id)
static writeStatPageUser(int $a_wiki_id, int $a_page_id, int $a_user_id, array $a_values)
Write data to wiki_stat_page_user.
static getWikiPageFootnotes(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
static getWikiEditPagesSum(int $a_wiki_id, string $a_day_from, string $a_day_to)
static getWikiReadPages(int $a_wiki_id, string $a_day_from, string $a_day_to)
static getFiguresPage()
static getFigureData(int $a_wiki_id, int $a_figure, string $a_from, string $a_to)
static getWikiPageUserEdit(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
static getFigureOptions()
static handlePageDeletion(ilWikiPage $a_page_obj, int $a_user_id)
static writeData(string $a_table, array $a_primary, array $a_values)
Write data to DB.
static getWikiPageWords(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_INTERNAL_LINKS_AVG
const EVENT_PAGE_RATING
query(string $query)
Run a (read-only) Query on the database.
const EVENT_PAGE_CREATED
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static writeStat(string $a_wiki_id, array $a_values)
Write data to wiki_stat.
const KEY_FIGURE_WIKI_RATING_AVG
static getAvailableMonths(int $a_wiki_id)
const KEY_FIGURE_WIKI_EDIT_PAGES_AVG
static getWikiRatingAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getWikiExternalLinks(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_CHARS
static writeStatUser(int $a_wiki_id, int $a_user_id, array $a_values)
Write to wiki_stat_user.
static countPages(int $a_wiki_id)
Count pages in wiki.
static getWikiPageRead(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
static getWikiNewPagesAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
static writeStatPage(int $a_wiki_id, int $a_page_id, array $a_values)
Write data to wiki_stat_page.
static getWikiNumPages(int $a_wiki_id, string $a_day_from, string $a_day_to)
static getWikiUserEditPagesAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
static getWikiPageRatings(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
static getWikiNewPagesSum(int $a_wiki_id, string $a_day_from, string $a_day_to)
static buildFullPeriodData(array &$a_res, string $a_day_from, string $a_day_to, ?int $a_last_before_period=null, bool $a_allow_zero=false)
static getWikiInternalLinksAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_NEW_PAGES
static handleEvent(int $a_event, ilWikiPage $a_page_obj, ?int $a_user_id=null, array $a_additional_data=null)
Handle wiki page event.
$ilUser
Definition: imgupload.php:34
static getWikiWordsAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_EDIT_PAGES
const KEY_FIGURE_WIKI_CHARS_AVG
static getWikiPageChanges(int $a_wiki_id, int $a_page_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_PAGE_WORDS
static getFigureOptionsPage()
static getOverallRatingForObject(int $a_obj_id, string $a_obj_type, int $a_sub_obj_id=null, string $a_sub_obj_type=null, int $a_category_id=null)
Get overall rating for an object.
manipulate(string $query)
Run a (write) Query on the database.
const KEY_FIGURE_WIKI_READ_PAGES
static handlePageUpdated(ilWikiPage $a_page_obj, int $a_user_id, array $a_page_data=null)
Handle wiki page update.
const KEY_FIGURE_WIKI_WORDS_AVG
static getWikiExternalLinksAvg(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_DELETED_PAGES
static getWikiUserEditPages(int $a_wiki_id, string $a_day_from, string $a_day_to, ?string $a_sub_field=null, ?int $a_sub_id=null)
static getWikiDeletedPages(int $a_wiki_id, string $a_day_from, string $a_day_to)
const KEY_FIGURE_WIKI_PAGE_CHANGES
const KEY_FIGURE_WIKI_PAGE_CHANGES_AVG
const EVENT_PAGE_DELETED
static getWikiFootnotes(int $a_wiki_id, string $a_day_from, string $a_day_to)
const EVENT_PAGE_UPDATED