ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilWikiStat.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2014 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
82 {
83  const EVENT_PAGE_CREATED = 1;
84  const EVENT_PAGE_UPDATED = 2;
85  const EVENT_PAGE_READ = 3;
86  const EVENT_PAGE_DELETED = 4;
87  const EVENT_PAGE_RATING = 5;
88 
111 
122 
123  //
124  // WRITE
125  //
126 
135  public static function handleEvent($a_event, ilWikiPage $a_page_obj, $a_user_id = null, array $a_additional_data = null)
136  {
137  global $ilUser;
138 
139  if(!$a_user_id)
140  {
141  $a_user_id = $ilUser->getId();
142  }
143  if(!$a_user_id || $a_user_id == ANONYMOUS_USER_ID)
144  {
145  return;
146  }
147 
148  switch((int)$a_event)
149  {
150  case self::EVENT_PAGE_CREATED:
151  self::handlePageCreated($a_page_obj, $a_user_id);
152  break;
153 
154  case self::EVENT_PAGE_UPDATED:
155  self::handlePageUpdated($a_page_obj, $a_user_id, $a_additional_data);
156  break;
157 
158  case self::EVENT_PAGE_READ:
159  self::handlePageRead($a_page_obj, $a_user_id);
160  break;
161 
162  case self::EVENT_PAGE_DELETED:
163  self::handlePageDeletion($a_page_obj, $a_user_id);
164  break;
165 
166  case self::EVENT_PAGE_RATING:
167  self::handlePageRating($a_page_obj, $a_user_id);
168  break;
169 
170  default:
171  return;
172  }
173  }
174 
180  protected static function getTimestamp()
181  {
182  return date("Y-m-d H:00:00");
183  }
184 
195  protected static function writeData($a_table, array $a_primary, array $a_values)
196  {
197  global $ilDB;
198 
199  $tstamp = self::getTimestamp();
200  $a_primary["ts"] = array("timestamp", $tstamp);
201 
202  $ilDB->lockTables(array(0 => array('name' => $a_table, 'type' => ilDB::LOCK_WRITE)));
203 
204  $primary = array();
205  foreach($a_primary as $column => $value)
206  {
207  $primary[] = $column." = ".$ilDB->quote($value[1], $value[0]);
208  }
209  $primary = implode(" AND ", $primary);
210 
211  $set = $ilDB->query("SELECT ts FROM ".$a_table.
212  " WHERE ".$primary);
213 
214  $is_update = (bool)$ilDB->numRows($set);
215 
216  // update (current timeframe)
217  if($is_update)
218  {
219  $values = array();
220  foreach($a_values as $column => $value)
221  {
222  if($value[0] == "increment")
223  {
224  $values[] = $column." = ".$column."+1";
225  }
226  else if($value[0] == "decrement")
227  {
228  $values[] = $column." = ".$column."-1";
229  }
230  else
231  {
232  $values[] = $column." = ".$ilDB->quote($value[1], $value[0]);
233  }
234  }
235  $values = implode(", ", $values);
236 
237  $sql = "UPDATE ".$a_table.
238  " SET ".$values.
239  " WHERE ".$primary;
240  }
241  // insert (no entry yet for current time frame)
242  else
243  {
244  $a_values = array_merge($a_primary, $a_values);
245  $a_values["ts_day"] = array("text", substr($tstamp, 0, 10));
246  $a_values["ts_hour"] = array("integer", (int)substr($tstamp, 11, 2));
247 
248  $values = array();
249  foreach($a_values as $column => $value)
250  {
251  $columns[] = $column;
252  if($value[0] == "increment")
253  {
254  $value[0] = "integer";
255  }
256  else if($value[0] == "decrement")
257  {
258  $value[0] = "integer";
259  $value[1] = 0;
260  }
261  $values[] = $ilDB->quote($value[1], $value[0]);
262  }
263  $values = implode(", ", $values);
264  $columns = implode(", ", $columns);
265 
266  $sql = "INSERT INTO ".$a_table.
267  " (".$columns.")".
268  " VALUES (".$values.")";
269  }
270  $ilDB->manipulate($sql);
271 
272  $ilDB->unlockTables();
273 
274  return $is_update;
275  }
276 
283  protected static function writeStat($a_wiki_id, $a_values)
284  {
285  $primary = array(
286  "wiki_id" => array("integer", $a_wiki_id)
287  );
288  self::writeData("wiki_stat", $primary, $a_values);
289  }
290 
298  protected static function writeStatPage($a_wiki_id, $a_page_id, $a_values)
299  {
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 
315  protected static function writeStatPageUser($a_wiki_id, $a_page_id, $a_user_id, $a_values)
316  {
317  $primary = array(
318  "wiki_id" => array("integer", $a_wiki_id),
319  "page_id" => array("integer", $a_page_id),
320  "user_id" => array("integer", $a_user_id)
321  );
322  self::writeData("wiki_stat_page_user", $primary, $a_values);
323  }
324 
332  protected static function writeStatUser($a_wiki_id, $a_user_id, $a_values)
333  {
334  $primary = array(
335  "wiki_id" => array("integer", $a_wiki_id),
336  "user_id" => array("integer", $a_user_id)
337  );
338  self::writeData("wiki_stat_user", $primary, $a_values);
339  }
340 
347  protected static function countPages($a_wiki_id)
348  {
349  return sizeof(ilWikiPage::getAllPages($a_wiki_id));
350  }
351 
359  protected static function getAverageRating($a_wiki_id, $a_page_id = null)
360  {
361  include_once "Services/Rating/classes/class.ilRating.php";
362 
363  if(!$a_page_id)
364  {
366  $a_wiki_id,
367  "wiki");
368  }
369  else
370  {
372  $a_wiki_id,
373  "wiki",
374  $a_page_id,
375  "wpg");
376  }
377  }
378 
385  public static function handlePageCreated(ilWikiPage $a_page_obj, $a_user_id)
386  {
387  // wiki: num_pages (count)
388  self::writeStat($a_page_obj->getWikiId(),
389  array(
390  "num_pages" => array("integer", self::countPages($a_page_obj->getWikiId()))
391  ));
392 
393  // user: new_pages+1
394  self::writeStatUser($a_page_obj->getWikiId(), $a_user_id,
395  array(
396  "new_pages" => array("increment", 1)
397  ));
398  }
399 
407  public static function handlePageUpdated(ilWikiPage $a_page_obj, $a_user_id, array $a_page_data = null)
408  {
409  // page_user: changes+1
410  self::writeStatPageUser($a_page_obj->getWikiId(), $a_page_obj->getId(), $a_user_id,
411  array(
412  "changes" => array("increment", 1)
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  );
423  self::writeStatPage($a_page_obj->getWikiId(), $a_page_obj->getId(), $values);
424  }
425 
432  public static function handlePageRead(ilWikiPage $a_page_obj, $a_user_id)
433  {
434  // page_user: read_events+1
435  self::writeStatPageUser($a_page_obj->getWikiId(), $a_page_obj->getId(), $a_user_id,
436  array(
437  "read_events" => array("increment", 1)
438  ));
439  }
440 
447  public static function handlePageDeletion(ilWikiPage $a_page_obj, $a_user_id)
448  {
449  global $ilDB;
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);
458  $set = $ilDB->query($sql);
459 
460  // #15748
461  if($ilDB->numRows($set))
462  {
463  $data = $ilDB->fetchAssoc($set);
464 
465  // see self::handlePageUpdated()
466  $values = array(
467  "int_links" => array("integer", $data["int_links"]),
468  "ext_links" => array("integer", $data["ext_links"]),
469  "footnotes" => array("integer", $data["footnotes"]),
470  "num_words" => array("integer", $data["num_words"]),
471  "num_chars" => array("integer", $data["num_chars"]),
472  "num_ratings" => array("integer", $data["num_ratings"]),
473  "avg_rating" => array("integer", $data["avg_rating"]),
474  );
475  self::writeStatPage($a_page_obj->getWikiId(), $a_page_obj->getId(), $values);
476  }
477 
478  // mark all page entries as deleted
479  $ilDB->manipulate("UPDATE wiki_stat_page".
480  " SET deleted = ".$ilDB->quote(1, "integer").
481  " WHERE page_id = ".$ilDB->quote($a_page_obj->getId(), "integer").
482  " AND wiki_id = ".$ilDB->quote($a_page_obj->getWikiId(), "integer"));
483 
484  // wiki: del_pages+1, num_pages (count), avg_rating
485  $rating = self::getAverageRating($a_page_obj->getWikiId());
486  self::writeStat($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 
500  public static function handlePageRating(ilWikiPage $a_page_obj, $a_user_id)
501  {
502  // do page first!
503  $rating = self::getAverageRating($a_page_obj->getWikiId(), $a_page_obj->getId());
504 
505  // wiki_stat_page: num_ratings, avg_rating
506  self::writeStatPage($a_page_obj->getWikiId(), $a_page_obj->getId(),
507  array(
508  "num_ratings" => array("integer", $rating["cnt"]),
509  "avg_rating" => array("integer", $rating["avg"]*100),
510  ));
511 
512  $rating = self::getAverageRating($a_page_obj->getWikiId());
513 
514  // wiki_stat: avg_rating
515  $is_update = self::writeStat($a_page_obj->getWikiId(),
516  array(
517  "avg_rating" => array("integer", $rating["avg"]*100)
518  ));
519 
520  if(!$is_update)
521  {
522  // wiki: num_pages (count)
523  self::writeStat($a_page_obj->getWikiId(),
524  array(
525  "num_pages" => array("integer", self::countPages($a_page_obj->getWikiId()))
526  ));
527  }
528  }
529 
530 
531  //
532  // READ HELPER
533  //
534 
535  protected static function getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, $a_table, $a_field, $a_aggr_value, $a_sub_field = null, $a_sub_id = null, $a_build_full_period = false)
536  {
537  global $ilDB;
538 
539  $res = array();
540  $deleted = null;
541 
542  $sql = "SELECT ts_day, ".sprintf($a_aggr_value, $a_field)." ".$a_field;
543  if($a_table == "wiki_stat_page" && $a_sub_field)
544  {
545  $sql .= ", MAX(deleted) deleted";
546  }
547  $sql .= " FROM ".$a_table.
548  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
549  " AND ts_day >= ".$ilDB->quote($a_day_from, "text").
550  " AND ts_day <= ".$ilDB->quote($a_day_to, "text");
551  if(!$a_build_full_period)
552  {
553  // to build full period data we need all values in DB
554  $sql .= " AND ".$a_field." > ".$ilDB->quote(0, "integer").
555  " AND ".$a_field." IS NOT NULL";
556  }
557  if($a_sub_field)
558  {
559  $sql .= " AND ".$a_sub_field." = ".$ilDB->quote($a_sub_id, "integer");
560  }
561  $sql .= " GROUP BY ts_day".
562  " ORDER BY ts_day";
563  $set = $ilDB->query($sql);
564  while($row = $ilDB->fetchAssoc($set))
565  {
566  $res[$row["ts_day"]] = $row[$a_field];
567 
568  $deleted = max($row["deleted"], $deleted);
569  }
570 
571  if($a_build_full_period)
572  {
573  $period_first = $a_day_from;
574  $period_last = $a_day_to;
575 
576  // check if sub was deleted in period
577  if($a_table == "wiki_stat_page" && $a_sub_field && $deleted)
578  {
579  $sql = "SELECT MAX(ts_day) last_day, MIN(ts_day) first_day".
580  " FROM ".$a_table.
581  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
582  " AND ".$a_sub_field." = ".$ilDB->quote($a_sub_id, "integer");
583  $set = $ilDB->query($sql);
584  $row = $ilDB->fetchAssoc($set);
585  $last_day = $row["last_day"];
586  if($last_day < $period_last)
587  {
588  $period_last = $last_day;
589  }
590  $first_day = $row["first_day"];
591  if($first_day > $period_first)
592  {
593  $period_first = $first_day;
594  }
595  }
596 
597  $last_before_period = null;
598  if(!$res[$a_day_from])
599  {
600  $last_before_period = self::getWikiLast($a_wiki_id, $a_day_from, $a_table, $a_field, $a_sub_field, $a_sub_id);
601  }
602 
603  // no need to allow zero here as we are not building averages
604  self::buildFullPeriodData($res, $period_first, $period_last, $last_before_period);
605  }
606 
607  return $res;
608  }
609 
610  protected static function getWikiLast($a_wiki_id, $a_day_from, $a_table, $a_field, $a_sub_field = null, $a_sub_id = null)
611  {
612  global $ilDB;
613 
614  // get last existing value before period (zero is valid)
615  $sql = "SELECT MAX(".$a_field.") latest".
616  " FROM ".$a_table.
617  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
618  " AND ts_day < ".$ilDB->quote($a_day_from, "text");
619  if($a_sub_field)
620  {
621  $sql .= " AND ".$a_sub_field." = ".$ilDB->quote($a_sub_id, "integer");
622  }
623  $sql .= " GROUP BY ts_day".
624  " ORDER BY ts_day DESC";
625  $ilDB->setLimit(1);
626  $set = $ilDB->query($sql);
627  $last_before_period = $ilDB->fetchAssoc($set);
628  return $last_before_period["latest"];
629  }
630 
631  protected static function getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, $a_table, $a_field, $a_aggr_by, $a_aggr_value, $a_aggr_sub, $a_sub_field = null, $a_sub_id = null, $a_build_full_period = false)
632  {
633  global $ilDB;
634 
635  $res = array();
636 
637  if(!$a_build_full_period)
638  {
639  $sql = "SELECT ts_day, ".sprintf($a_aggr_value, $a_field)." ".$a_field.
640  " FROM (".
641  // subquery to build average per $a_aggr_by
642  " SELECT ts_day, ".sprintf($a_aggr_sub, $a_field)." ".$a_field.
643  " FROM ".$a_table.
644  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
645  " AND ts_day >= ".$ilDB->quote($a_day_from, "text").
646  " AND ts_day <= ".$ilDB->quote($a_day_to, "text").
647  " AND ".$a_field." > ".$ilDB->quote(0, "integer").
648  " AND ".$a_field." IS NOT NULL";
649  if($a_sub_field)
650  {
651  $sql .= " AND ".$a_sub_field." = ".$ilDB->quote($a_sub_id, "integer");
652  }
653  $sql .= " GROUP BY ts_day, ".$a_aggr_by.
654  ") aggr_sub".
655  " GROUP BY ts_day".
656  " ORDER BY ts_day";
657  $set = $ilDB->query($sql);
658  while($row = $ilDB->fetchAssoc($set))
659  {
660  $res[$row["ts_day"]] = $row[$a_field];
661  }
662  }
663  else
664  {
665  $tmp = $all_aggr_ids = $deleted_in_period = $first_day_in_period = array();
666 
667  if($a_table != "wiki_stat_page")
668  {
669  echo "can only build full period averages for wiki_stat_page";
670  exit();
671  }
672 
673  // as current period can be totally empty, gather existing subs
674  $sql = " SELECT *".
675  " FROM (".
676  " SELECT ".$a_aggr_by.", MAX(deleted) deleted, MAX(ts_day) last_day, MIN(ts_day) first_day".
677  " FROM ".$a_table.
678  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
679  " GROUP BY ".$a_aggr_by.
680  ") aggr_sub".
681  " WHERE first_day <= ".$ilDB->quote($a_day_to, "text"). // not created after period
682  " AND (last_day >= ".$ilDB->quote($a_day_from, "text"). // (deleted in/after period
683  " OR deleted = ".$ilDB->quote(0, "integer").")"; // or still existing)
684  $set = $ilDB->query($sql);
685  while($row = $ilDB->fetchAssoc($set))
686  {
687  $all_aggr_ids[] = $row[$a_aggr_by];
688 
689  // if deleted in period we need the last day
690  if($row["deleted"] && $row["last_day"] < $a_day_to)
691  {
692  $deleted_in_period[$row[$a_aggr_by]] = $row["last_day"];
693  }
694  // if created in period we need the first day
695  if($row["first_day"] > $a_day_from)
696  {
697  $first_day_in_period[$row[$a_aggr_by]] = $row["first_day"];
698  }
699  }
700 
701  // we need to build average manually after completing period data (zero is valid)
702  $sql = " SELECT ts_day, ".$a_aggr_by.", ".sprintf($a_aggr_sub, $a_field)." ".$a_field.
703  " FROM ".$a_table.
704  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
705  " AND ts_day >= ".$ilDB->quote($a_day_from, "text").
706  " AND ts_day <= ".$ilDB->quote($a_day_to, "text");
707  $sql .= " GROUP BY ts_day, ".$a_aggr_by;
708  $set = $ilDB->query($sql);
709  while($row = $ilDB->fetchAssoc($set))
710  {
711  if(!in_array($row[$a_aggr_by], $all_aggr_ids))
712  {
713  var_dump("unexpected wiki_stat_page_entry", $row);
714  }
715  $tmp[$row[$a_aggr_by]][$row["ts_day"]] = $row[$a_field];
716  }
717 
718  // build full period for each sub
719  foreach($all_aggr_ids as $aggr_by_id)
720  {
721  // last of entry of sub is before period
722  if(!is_array($tmp[$aggr_by_id]))
723  {
724  $tmp[$aggr_by_id] = array();
725  }
726 
727  // get last value before period to add missing entries in period
728  $last_before_period = null;
729  if(!$tmp[$aggr_by_id][$a_day_from])
730  {
731  $last_before_period = self::getWikiLast($a_wiki_id, $a_day_from, $a_table, $a_field, $a_aggr_by, $aggr_by_id);
732  }
733 
734  // if sub was created in period (see above), shorten period accordingly
735  $first_period_day = isset($first_day_in_period[$aggr_by_id])
736  ? $first_day_in_period[$aggr_by_id]
737  : $a_day_from;
738 
739  // if sub was deleted in period (see above), shorten period accordingly
740  $last_period_day = isset($deleted_in_period[$aggr_by_id])
741  ? $deleted_in_period[$aggr_by_id]
742  : $a_day_to;
743 
744  // allow zero as we need to correct number of valid subs per day (see below - AVG)
745  self::buildFullPeriodData($tmp[$aggr_by_id], $first_period_day, $last_period_day, $last_before_period, true);
746 
747  // distribute sub to days
748  foreach($tmp[$aggr_by_id] as $day => $value)
749  {
750  $res[$day][$aggr_by_id] = $value;
751  }
752  }
753 
754  // build average over subs
755  foreach($res as $day => $values)
756  {
757  switch($a_aggr_value)
758  {
759  case "AVG(%s)":
760  $res[$day] = array_sum($values)/sizeof($values);
761  break;
762 
763  case "SUM(%s)":
764  $res[$day] = array_sum($values);
765  break;
766 
767  default:
768  var_dump("unsupport aggr ".$a_aggr_value);
769  break;
770  }
771  }
772  }
773 
774  return $res;
775  }
776 
777  protected static function buildFullPeriodData(array &$a_res, $a_day_from, $a_day_to, $a_last_before_period, $a_allow_zero = false)
778  {
779  // build full data for period
780  $safety = 0;
781  $last = null;
782  $today = date("Y-m-d");
783  $current = explode("-", $a_day_from);
784  $current = date("Y-m-d", mktime(0, 0, 1, $current[1], $current[2], $current[0]));
785  while($current <= $a_day_to &&
786  ++$safety < 1000)
787  {
788  if(!isset($a_res[$current]))
789  {
790  if($current <= $today)
791  {
792  // last existing value in period
793  if($last !== null)
794  {
795  $a_res[$current] = $last;
796  }
797  // last existing value before period
798  else if($a_last_before_period || $a_allow_zero)
799  {
800  $a_res[$current] = $a_last_before_period;
801  }
802  }
803  }
804  else
805  {
806  $last = $a_res[$current];
807  }
808 
809  $current = explode("-", $current);
810  $current = date("Y-m-d", mktime(0, 0, 1, $current[1], $current[2]+1, $current[0]));
811  }
812  }
813 
814 
815  //
816  // READ WIKI
817  //
818 
819  protected static function getWikiNumPages($a_wiki_id, $a_day_from, $a_day_to)
820  {
821  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat", "num_pages", "MAX(%s)", null, null, true);
822  }
823 
824  protected static function getWikiNewPagesSum($a_wiki_id, $a_day_from, $a_day_to)
825  {
826  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_user", "new_pages", "SUM(%s)");
827  }
828 
829  protected static function getWikiNewPagesAvg($a_wiki_id, $a_day_from, $a_day_to)
830  {
831  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_user", "new_pages", "user_id", "AVG(%s)", "SUM(%s)");
832  }
833 
834  protected static function getWikiDeletedPages($a_wiki_id, $a_day_from, $a_day_to)
835  {
836  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat", "del_pages", "SUM(%s)");
837  }
838 
839  protected static function getWikiReadPages($a_wiki_id, $a_day_from, $a_day_to)
840  {
841  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page_user", "read_events", "SUM(%s)");
842  }
843 
844  protected static function getWikiEditPagesSum($a_wiki_id, $a_day_from, $a_day_to)
845  {
846  global $ilDB;
847 
848  $res = array();
849 
850  $sql = "SELECT ts_day, COUNT(DISTINCT(page_id)) num_changed_pages".
851  " FROM wiki_stat_page_user".
852  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
853  " AND ts_day >= ".$ilDB->quote($a_day_from, "text").
854  " AND ts_day <= ".$ilDB->quote($a_day_to, "text").
855  " AND changes > ".$ilDB->quote(0, "integer").
856  " AND changes IS NOT NULL".
857  " GROUP BY ts_day".
858  " ORDER BY ts_day";
859  $set = $ilDB->query($sql);
860  while($row = $ilDB->fetchAssoc($set))
861  {
862  $res[$row["ts_day"]] = $row["num_changed_pages"];
863  }
864 
865  return $res;
866  }
867 
868  protected static function getWikiEditPagesAvg($a_wiki_id, $a_day_from, $a_day_to)
869  {
870  global $ilDB;
871 
872  $res = array();
873 
874  $sql = "SELECT ts_day, AVG(num_changed_pages) num_changed_pages".
875  " FROM (".
876  // subquery to build average per user
877  " SELECT ts_day, COUNT(DISTINCT(page_id)) num_changed_pages".
878  " FROM wiki_stat_page_user".
879  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
880  " AND ts_day >= ".$ilDB->quote($a_day_from, "text").
881  " AND ts_day <= ".$ilDB->quote($a_day_to, "text").
882  " AND changes > ".$ilDB->quote(0, "integer").
883  " AND changes IS NOT NULL".
884  " GROUP BY ts_day, user_id".
885  ") aggr_user".
886  " GROUP BY ts_day".
887  " ORDER BY ts_day";
888  $set = $ilDB->query($sql);
889  while($row = $ilDB->fetchAssoc($set))
890  {
891  $res[$row["ts_day"]] = $row["num_changed_pages"];
892  }
893 
894  return $res;
895  }
896 
897  protected static function getWikiUserEditPages($a_wiki_id, $a_day_from, $a_day_to, $a_sub_field = null, $a_sub_id = null)
898  {
899  global $ilDB;
900 
901  $res = array();
902 
903  $sql = "SELECT ts_day, COUNT(DISTINCT(user_id)) num_changed_users".
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  if($a_sub_field)
911  {
912  $sql .= " AND ".$a_sub_field." = ".$ilDB->quote($a_sub_id, "integer");
913  }
914  $sql .= " GROUP BY ts_day".
915  " ORDER BY ts_day";
916  $set = $ilDB->query($sql);
917  while($row = $ilDB->fetchAssoc($set))
918  {
919  $res[$row["ts_day"]] = $row["num_changed_users"];
920  }
921 
922  return $res;
923  }
924 
925  protected static function getWikiUserEditPagesAvg($a_wiki_id, $a_day_from, $a_day_to)
926  {
927  global $ilDB;
928 
929  $res = array();
930 
931  $sql = "SELECT ts_day, AVG(num_changed_users) num_changed_users".
932  " FROM (".
933  // subquery to build average per page
934  " SELECT ts_day, COUNT(DISTINCT(user_id)) num_changed_users".
935  " FROM wiki_stat_page_user".
936  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
937  " AND ts_day >= ".$ilDB->quote($a_day_from, "text").
938  " AND ts_day <= ".$ilDB->quote($a_day_to, "text").
939  " AND changes > ".$ilDB->quote(0, "integer").
940  " AND changes IS NOT NULL".
941  " GROUP BY ts_day, page_id".
942  ") aggr_user".
943  " GROUP BY ts_day".
944  " ORDER BY ts_day";
945  $set = $ilDB->query($sql);
946  while($row = $ilDB->fetchAssoc($set))
947  {
948  $res[$row["ts_day"]] = $row["num_changed_users"];
949  }
950 
951  return $res;
952  }
953 
954  protected static function getWikiNumRating($a_wiki_id, $a_day_from, $a_day_to)
955  {
956  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_ratings", "SUM(%s)");
957  }
958 
959  protected static function getWikiNumRatingAvg($a_wiki_id, $a_day_from, $a_day_to)
960  {
961  return self::getWikiAggrSub($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_ratings", "page_id", "AVG(%s)", "SUM(%s)");
962  }
963 
964  protected static function getWikiRatingAvg($a_wiki_id, $a_day_from, $a_day_to)
965  {
966  $res = self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat", "avg_rating", "AVG(%s)");
967 
968  foreach(array_keys($res) as $day)
969  {
970  // int-to-float
971  $res[$day] = $res[$day]/100;
972  }
973 
974  return $res;
975  }
976 
977  protected static function getWikiInternalLinks($a_wiki_id, $a_day_from, $a_day_to)
978  {
979  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);
980  }
981 
982  protected static function getWikiInternalLinksAvg($a_wiki_id, $a_day_from, $a_day_to)
983  {
984  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);
985  }
986 
987  protected static function getWikiExternalLinks($a_wiki_id, $a_day_from, $a_day_to)
988  {
989  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);
990  }
991 
992  protected static function getWikiExternalLinksAvg($a_wiki_id, $a_day_from, $a_day_to)
993  {
994  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);
995  }
996 
997  protected static function getWikiWords($a_wiki_id, $a_day_from, $a_day_to)
998  {
999  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);
1000  }
1001 
1002  protected static function getWikiWordsAvg($a_wiki_id, $a_day_from, $a_day_to)
1003  {
1004  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);
1005  }
1006 
1007  protected static function getWikiCharacters($a_wiki_id, $a_day_from, $a_day_to)
1008  {
1009  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);
1010  }
1011 
1012  protected static function getWikiCharactersAvg($a_wiki_id, $a_day_from, $a_day_to)
1013  {
1014  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);
1015  }
1016 
1017  protected static function getWikiFootnotes($a_wiki_id, $a_day_from, $a_day_to)
1018  {
1019  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);
1020  }
1021 
1022  protected static function getWikiFootnotesAvg($a_wiki_id, $a_day_from, $a_day_to)
1023  {
1024  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);
1025  }
1026 
1027 
1028  //
1029  // READ PAGE
1030  //
1031 
1032  protected static function getWikiPageChanges($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1033  {
1034  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page_user", "changes", "SUM(%s)", "page_id", $a_page_id);
1035  }
1036 
1037  protected static function getWikiPageChangesAvg($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1038  {
1039  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);
1040  }
1041 
1042  protected static function getWikiPageUserEdit($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1043  {
1044  return self::getWikiUserEditPages($a_wiki_id, $a_day_from, $a_day_to, "page_id", $a_page_id);
1045  }
1046 
1047  protected static function getWikiPageRead($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1048  {
1049  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);
1050  }
1051 
1052  protected static function getWikiPageInternalLinks($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1053  {
1054  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);
1055  }
1056 
1057  protected static function getWikiPageExternalLinks($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1058  {
1059  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);
1060  }
1061 
1062  protected static function getWikiPageWords($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1063  {
1064  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);
1065  }
1066 
1067  protected static function getWikiPageCharacters($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1068  {
1069  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);
1070  }
1071 
1072  protected static function getWikiPageFootnotes($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1073  {
1074  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "footnotes", "MAX(%s)", "page_id", $a_page_id, true);
1075  }
1076 
1077  protected static function getWikiPageRatings($a_wiki_id, $a_page_id, $a_day_from, $a_day_to)
1078  {
1079  return self::getWikiAggr($a_wiki_id, $a_day_from, $a_day_to, "wiki_stat_page", "num_ratings", "SUM(%s)", "page_id", $a_page_id);
1080  }
1081 
1082 
1083  //
1084  // GUI HELPER
1085  //
1086 
1087  public static function getAvailableMonths($a_wiki_id)
1088  {
1089  global $ilDB;
1090 
1091  $res = array();
1092 
1093  // because of read_events this db table is updated most often
1094  $set = $ilDB->query("SELECT DISTINCT(SUBSTR(ts_day, 1, 7)) month".
1095  " FROM wiki_stat_page_user".
1096  " WHERE wiki_id = ".$ilDB->quote($a_wiki_id, "integer").
1097  " AND ts_day IS NOT NULL");
1098  while($row = $ilDB->fetchAssoc($set))
1099  {
1100  $res[] = $row["month"];
1101  }
1102 
1103  return $res;
1104  }
1105 
1106  public static function getFigures()
1107  {
1108  return array(
1109  self::KEY_FIGURE_WIKI_NUM_PAGES
1110  ,self::KEY_FIGURE_WIKI_NEW_PAGES
1111  ,self::KEY_FIGURE_WIKI_NEW_PAGES_AVG
1112  ,self::KEY_FIGURE_WIKI_EDIT_PAGES
1113  ,self::KEY_FIGURE_WIKI_EDIT_PAGES_AVG
1114  ,self::KEY_FIGURE_WIKI_DELETED_PAGES
1115  ,self::KEY_FIGURE_WIKI_READ_PAGES
1116  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES
1117  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES_AVG
1118  ,self::KEY_FIGURE_WIKI_NUM_RATING
1119  ,self::KEY_FIGURE_WIKI_NUM_RATING_AVG
1120  ,self::KEY_FIGURE_WIKI_RATING_AVG
1121  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS
1122  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS_AVG
1123  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS
1124  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS_AVG
1125  ,self::KEY_FIGURE_WIKI_WORDS
1126  ,self::KEY_FIGURE_WIKI_WORDS_AVG
1127  ,self::KEY_FIGURE_WIKI_CHARS
1128  ,self::KEY_FIGURE_WIKI_CHARS_AVG
1129  ,self::KEY_FIGURE_WIKI_FOOTNOTES
1130  ,self::KEY_FIGURE_WIKI_FOOTNOTES_AVG
1131  );
1132  }
1133 
1134  public static function getFiguresPage()
1135  {
1136  return array(
1137  self::KEY_FIGURE_WIKI_PAGE_CHANGES
1138  ,self::KEY_FIGURE_WIKI_PAGE_CHANGES_AVG
1139  ,self::KEY_FIGURE_WIKI_PAGE_USER_EDIT
1140  ,self::KEY_FIGURE_WIKI_PAGE_READ
1141  ,self::KEY_FIGURE_WIKI_PAGE_INTERNAL_LINKS
1142  ,self::KEY_FIGURE_WIKI_PAGE_EXTERNAL_LINKS
1143  ,self::KEY_FIGURE_WIKI_PAGE_WORDS
1144  ,self::KEY_FIGURE_WIKI_PAGE_CHARS
1145  ,self::KEY_FIGURE_WIKI_PAGE_FOOTNOTES
1146  ,self::KEY_FIGURE_WIKI_PAGE_RATINGS
1147  );
1148  }
1149 
1150  public static function getFigureTitle($a_figure)
1151  {
1152  global $lng;
1153 
1154  $map = array(
1155  // wiki
1156  self::KEY_FIGURE_WIKI_NUM_PAGES => $lng->txt("wiki_stat_num_pages")
1157  ,self::KEY_FIGURE_WIKI_NEW_PAGES => $lng->txt("wiki_stat_new_pages")
1158  ,self::KEY_FIGURE_WIKI_NEW_PAGES_AVG => $lng->txt("wiki_stat_new_pages_avg")
1159  ,self::KEY_FIGURE_WIKI_EDIT_PAGES => $lng->txt("wiki_stat_edit_pages")
1160  ,self::KEY_FIGURE_WIKI_EDIT_PAGES_AVG => $lng->txt("wiki_stat_edit_pages_avg")
1161  ,self::KEY_FIGURE_WIKI_DELETED_PAGES => $lng->txt("wiki_stat_deleted_pages")
1162  ,self::KEY_FIGURE_WIKI_READ_PAGES => $lng->txt("wiki_stat_read_pages")
1163  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES => $lng->txt("wiki_stat_user_edit_pages")
1164  ,self::KEY_FIGURE_WIKI_USER_EDIT_PAGES_AVG => $lng->txt("wiki_stat_user_edit_pages_avg")
1165  ,self::KEY_FIGURE_WIKI_NUM_RATING => $lng->txt("wiki_stat_num_rating")
1166  ,self::KEY_FIGURE_WIKI_NUM_RATING_AVG => $lng->txt("wiki_stat_num_rating_avg")
1167  ,self::KEY_FIGURE_WIKI_RATING_AVG => $lng->txt("wiki_stat_rating_avg")
1168  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS => $lng->txt("wiki_stat_internal_links")
1169  ,self::KEY_FIGURE_WIKI_INTERNAL_LINKS_AVG => $lng->txt("wiki_stat_internal_links_avg")
1170  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS => $lng->txt("wiki_stat_external_links")
1171  ,self::KEY_FIGURE_WIKI_EXTERNAL_LINKS_AVG => $lng->txt("wiki_stat_external_links_avg")
1172  ,self::KEY_FIGURE_WIKI_WORDS => $lng->txt("wiki_stat_words")
1173  ,self::KEY_FIGURE_WIKI_WORDS_AVG => $lng->txt("wiki_stat_words_avg")
1174  ,self::KEY_FIGURE_WIKI_CHARS => $lng->txt("wiki_stat_chars")
1175  ,self::KEY_FIGURE_WIKI_CHARS_AVG => $lng->txt("wiki_stat_chars_avg")
1176  ,self::KEY_FIGURE_WIKI_FOOTNOTES => $lng->txt("wiki_stat_footnotes")
1177  ,self::KEY_FIGURE_WIKI_FOOTNOTES_AVG => $lng->txt("wiki_stat_footnotes_avg")
1178  // page
1179  ,self::KEY_FIGURE_WIKI_PAGE_CHANGES => $lng->txt("wiki_stat_page_changes")
1180  ,self::KEY_FIGURE_WIKI_PAGE_CHANGES_AVG => $lng->txt("wiki_stat_page_changes_avg")
1181  ,self::KEY_FIGURE_WIKI_PAGE_USER_EDIT => $lng->txt("wiki_stat_page_user_edit")
1182  ,self::KEY_FIGURE_WIKI_PAGE_READ => $lng->txt("wiki_stat_page_read")
1183  ,self::KEY_FIGURE_WIKI_PAGE_INTERNAL_LINKS => $lng->txt("wiki_stat_page_internal_links")
1184  ,self::KEY_FIGURE_WIKI_PAGE_EXTERNAL_LINKS => $lng->txt("wiki_stat_page_external_links")
1185  ,self::KEY_FIGURE_WIKI_PAGE_WORDS => $lng->txt("wiki_stat_page_words")
1186  ,self::KEY_FIGURE_WIKI_PAGE_CHARS => $lng->txt("wiki_stat_page_characters")
1187  ,self::KEY_FIGURE_WIKI_PAGE_FOOTNOTES => $lng->txt("wiki_stat_page_footnotes")
1188  ,self::KEY_FIGURE_WIKI_PAGE_RATINGS => $lng->txt("wiki_stat_page_ratings")
1189  );
1190 
1191  return $map[$a_figure];
1192  }
1193 
1194  public static function getFigureData($a_wiki_id, $a_figure, $a_from, $a_to)
1195  {
1196  switch($a_figure)
1197  {
1198  case self::KEY_FIGURE_WIKI_NUM_PAGES:
1199  return self::getWikiNumPages($a_wiki_id, $a_from, $a_to);
1200 
1201  case self::KEY_FIGURE_WIKI_NEW_PAGES:
1202  return self::getWikiNewPagesSum($a_wiki_id, $a_from, $a_to);
1203 
1204  case self::KEY_FIGURE_WIKI_NEW_PAGES_AVG:
1205  return self::getWikiNewPagesAvg($a_wiki_id, $a_from, $a_to);
1206 
1207  case self::KEY_FIGURE_WIKI_EDIT_PAGES:
1208  return self::getWikiEditPagesSum($a_wiki_id, $a_from, $a_to);
1209 
1210  case self::KEY_FIGURE_WIKI_EDIT_PAGES_AVG:
1211  return self::getWikiEditPagesAvg($a_wiki_id, $a_from, $a_to);
1212 
1213  case self::KEY_FIGURE_WIKI_DELETED_PAGES:
1214  return self::getWikiDeletedPages($a_wiki_id, $a_from, $a_to);
1215 
1216  case self::KEY_FIGURE_WIKI_READ_PAGES:
1217  return self::getWikiReadPages($a_wiki_id, $a_from, $a_to);
1218 
1219  case self::KEY_FIGURE_WIKI_USER_EDIT_PAGES:
1220  return self::getWikiUserEditPages($a_wiki_id, $a_from, $a_to);
1221 
1222  case self::KEY_FIGURE_WIKI_USER_EDIT_PAGES_AVG:
1223  return self::getWikiUserEditPages($a_wiki_id, $a_from, $a_to);
1224 
1225  case self::KEY_FIGURE_WIKI_NUM_RATING:
1226  return self::getWikiNumRating($a_wiki_id, $a_from, $a_to);
1227 
1228  case self::KEY_FIGURE_WIKI_NUM_RATING_AVG:
1229  return self::getWikiNumRatingAvg($a_wiki_id, $a_from, $a_to);
1230 
1231  case self::KEY_FIGURE_WIKI_RATING_AVG:
1232  return self::getWikiRatingAvg($a_wiki_id, $a_from, $a_to);
1233 
1234  case self::KEY_FIGURE_WIKI_INTERNAL_LINKS:
1235  return self::getWikiInternalLinks($a_wiki_id, $a_from, $a_to);
1236 
1237  case self::KEY_FIGURE_WIKI_INTERNAL_LINKS_AVG:
1238  return self::getWikiInternalLinksAvg($a_wiki_id, $a_from, $a_to);
1239 
1240  case self::KEY_FIGURE_WIKI_EXTERNAL_LINKS:
1241  return self::getWikiExternalLinks($a_wiki_id, $a_from, $a_to);
1242 
1243  case self::KEY_FIGURE_WIKI_EXTERNAL_LINKS_AVG:
1244  return self::getWikiExternalLinksAvg($a_wiki_id, $a_from, $a_to);
1245 
1246  case self::KEY_FIGURE_WIKI_WORDS:
1247  return self::getWikiWords($a_wiki_id, $a_from, $a_to);
1248 
1249  case self::KEY_FIGURE_WIKI_WORDS_AVG:
1250  return self::getWikiWordsAvg($a_wiki_id, $a_from, $a_to);
1251 
1252  case self::KEY_FIGURE_WIKI_CHARS:
1253  return self::getWikiCharacters($a_wiki_id, $a_from, $a_to);
1254 
1255  case self::KEY_FIGURE_WIKI_CHARS_AVG:
1256  return self::getWikiCharactersAvg($a_wiki_id, $a_from, $a_to);
1257 
1258  case self::KEY_FIGURE_WIKI_FOOTNOTES:
1259  return self::getWikiFootnotes($a_wiki_id, $a_from, $a_to);
1260 
1261  case self::KEY_FIGURE_WIKI_FOOTNOTES_AVG:
1262  return self::getWikiFootnotesAvg($a_wiki_id, $a_from, $a_to);
1263  }
1264  }
1265 
1266  public static function getFigureDataPage($a_wiki_id, $a_page_id, $a_figure, $a_from, $a_to)
1267  {
1268  switch($a_figure)
1269  {
1270  case self::KEY_FIGURE_WIKI_PAGE_CHANGES:
1271  return self::getWikiPageChanges($a_wiki_id, $a_page_id, $a_from, $a_to);
1272 
1273  case self::KEY_FIGURE_WIKI_PAGE_CHANGES_AVG:
1274  return self::getWikiPageChangesAvg($a_wiki_id, $a_page_id, $a_from, $a_to);
1275 
1276  case self::KEY_FIGURE_WIKI_PAGE_USER_EDIT:
1277  return self::getWikiPageUserEdit($a_wiki_id, $a_page_id, $a_from, $a_to);
1278 
1279  case self::KEY_FIGURE_WIKI_PAGE_READ:
1280  return self::getWikiPageRead($a_wiki_id, $a_page_id, $a_from, $a_to);
1281 
1282  case self::KEY_FIGURE_WIKI_PAGE_INTERNAL_LINKS:
1283  return self::getWikiPageInternalLinks($a_wiki_id, $a_page_id, $a_from, $a_to);
1284 
1285  case self::KEY_FIGURE_WIKI_PAGE_EXTERNAL_LINKS:
1286  return self::getWikiPageExternalLinks($a_wiki_id, $a_page_id, $a_from, $a_to);
1287 
1288  case self::KEY_FIGURE_WIKI_PAGE_FOOTNOTES:
1289  return self::getWikiPageFootnotes($a_wiki_id, $a_page_id, $a_from, $a_to);
1290 
1291  case self::KEY_FIGURE_WIKI_PAGE_WORDS:
1292  return self::getWikiPageWords($a_wiki_id, $a_page_id, $a_from, $a_to);
1293 
1294  case self::KEY_FIGURE_WIKI_PAGE_CHARS:
1295  return self::getWikiPageCharacters($a_wiki_id, $a_page_id, $a_from, $a_to);
1296 
1297  case self::KEY_FIGURE_WIKI_PAGE_RATINGS:
1298  return self::getWikiPageRatings($a_wiki_id, $a_page_id, $a_from, $a_to);
1299  }
1300  }
1301 
1302  public static function getFigureOptions()
1303  {
1304  $res = array();
1305 
1306  foreach(self::getFigures() as $figure)
1307  {
1308  $res[$figure] = self::getFigureTitle($figure);
1309  }
1310 
1311  return $res;
1312  }
1313 
1314  public static function getFigureOptionsPage()
1315  {
1316  $res = array();
1317 
1318  foreach(self::getFiguresPage() as $figure)
1319  {
1320  $res[$figure] = self::getFigureTitle($figure);
1321  }
1322 
1323  return $res;
1324  }
1325 }
1326 
1327 ?>