ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilObjPoll.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 require_once "Services/Object/classes/class.ilObject2.php";
6 require_once "Services/Object/classes/class.ilObjectActivation.php";
7 
16 class ilObjPoll extends ilObject2
17 {
18  protected $online; // [bool]
19  protected $access_type; // [int]
20  protected $access_begin; // [timestamp]
21  protected $access_end; // [timestamp]
22  protected $access_visibility; // [bool]
23  protected $question; // [string]
24  protected $image; // [string]
25  protected $view_results; // [int]
26  protected $period; // [bool]
27  protected $period_begin; // [timestamp]
28  protected $period_end; // [timestamp]
29 
30  // 4.5
31  protected $max_number_answers = 1; // [int]
32  protected $result_sort_by_votes = false; // [bool]
33  protected $mode_non_anonymous = false; // [bool]
34  protected $show_comments = false; //[bool]
35  protected $show_results_as = 1; //[int]
36 
38  const VIEW_RESULTS_NEVER = 2;
41 
44 
45  public function __construct($a_id = 0, $a_reference = true)
46  {
47  global $DIC;
48 
49  $this->db = $DIC->database();
50  // default
51  $this->setOnline(false);
52  $this->setViewResults(self::VIEW_RESULTS_AFTER_VOTE);
54  $this->setVotingPeriod(false);
55 
56  parent::__construct($a_id, $a_reference);
57  }
58 
59  public function initType()
60  {
61  $this->type = "poll";
62  }
63 
64  public function setOnline($a_value)
65  {
66  $this->online = (bool) $a_value;
67  }
68 
69  public function isOnline()
70  {
71  return $this->online;
72  }
73 
74  public function setAccessType($a_value)
75  {
76  $this->access_type = (int) $a_value;
77  }
78 
79  public function getAccessType()
80  {
81  return $this->access_type;
82  }
83 
84  public function setAccessBegin($a_value)
85  {
86  $this->access_begin = (int) $a_value;
87  }
88 
89  public function getAccessBegin()
90  {
91  return $this->access_begin;
92  }
93 
94  public function setAccessEnd($a_value)
95  {
96  $this->access_end = (int) $a_value;
97  }
98 
99  public function getAccessEnd()
100  {
101  return $this->access_end;
102  }
103 
104  public function setAccessVisibility($a_value)
105  {
106  $this->access_visibility = (bool) $a_value;
107  }
108 
109  public function getAccessVisibility()
110  {
112  }
113 
114  public function setQuestion($a_value)
115  {
116  $this->question = (string) $a_value;
117  }
118 
119  public function getQuestion()
120  {
121  return $this->question;
122  }
123 
124  public function setImage($a_value)
125  {
126  $this->image = (string) $a_value;
127  }
128 
129  public function getImage()
130  {
131  return $this->image;
132  }
133 
134  public function setViewResults($a_value)
135  {
136  $this->view_results = (int) $a_value;
137  }
138 
139  public function getViewResults()
140  {
141  return $this->view_results;
142  }
143 
144  public function setVotingPeriod($a_value)
145  {
146  $this->period = (bool) $a_value;
147  }
148 
149  public function getVotingPeriod()
150  {
151  return $this->period;
152  }
153 
154  public function setVotingPeriodBegin($a_value)
155  {
156  $this->period_begin = (int) $a_value;
157  }
158 
159  public function getVotingPeriodBegin()
160  {
161  return $this->period_begin;
162  }
163 
164  public function setVotingPeriodEnd($a_value)
165  {
166  $this->period_end = (int) $a_value;
167  }
168 
169  public function getVotingPeriodEnd()
170  {
171  return $this->period_end;
172  }
173 
174  public function setMaxNumberOfAnswers($a_value)
175  {
176  $this->max_number_answers = (int) $a_value;
177  }
178 
179  public function getMaxNumberOfAnswers()
180  {
182  }
183 
184  public function setSortResultByVotes($a_value)
185  {
186  $this->result_sort_by_votes = (bool) $a_value;
187  }
188 
189  public function getSortResultByVotes()
190  {
192  }
193 
194  public function setNonAnonymous($a_value)
195  {
196  $this->mode_non_anonymous = (bool) $a_value;
197  }
198 
199  public function getNonAnonymous()
200  {
202  }
203 
204  public function setShowComments($a_value)
205  {
206  $this->show_comments = (bool) $a_value;
207  }
208 
209  public function getShowComments()
210  {
211  return $this->show_comments;
212  }
213 
214  public function setShowResultsAs($a_value)
215  {
216  $this->show_results_as = (int) $a_value;
217  }
218 
219  public function getShowResultsAs()
220  {
221  return $this->show_results_as;
222  }
223 
224  protected function doRead()
225  {
226  $ilDB = $this->db;
227 
228  $set = $ilDB->query("SELECT * FROM il_poll" .
229  " WHERE id = " . $ilDB->quote($this->getId(), "integer"));
230  $row = $ilDB->fetchAssoc($set);
231  $this->setQuestion($row["question"]);
232  $this->setImage($row["image"]);
233  $this->setOnline($row["online_status"]);
234  $this->setViewResults($row["view_results"]);
235  $this->setVotingPeriod($row["period"]);
236  $this->setVotingPeriodBegin($row["period_begin"]);
237  $this->setVotingPeriodEnd($row["period_end"]);
238  $this->setMaxNumberOfAnswers($row["max_answers"]);
239  $this->setSortResultByVotes($row["result_sort"]);
240  $this->setNonAnonymous($row["non_anon"]);
241  $this->setShowResultsAs($row["show_results_as"]);
242 
243  // #14661
244  include_once("./Services/Notes/classes/class.ilNote.php");
245  $this->setShowComments(ilNote::commentsActivated($this->getId(), 0, $this->getType()));
246 
247  if ($this->ref_id) {
248  $activation = ilObjectActivation::getItem($this->ref_id);
249  $this->setAccessType($activation["timing_type"]);
251  // default entry values should not be loaded if not activated
252  $this->setAccessBegin($activation["timing_start"]);
253  $this->setAccessEnd($activation["timing_end"]);
254  $this->setAccessVisibility($activation["visible"]);
255  }
256  }
257  }
258 
259  protected function propertiesToDB()
260  {
261  $fields = array(
262  "question" => array("text", $this->getQuestion()),
263  "image" => array("text", $this->getImage()),
264  "online_status" => array("integer", $this->isOnline()),
265  "view_results" => array("integer", $this->getViewResults()),
266  "period" => array("integer", $this->getVotingPeriod()),
267  "period_begin" => array("integer", $this->getVotingPeriodBegin()),
268  "period_end" => array("integer", $this->getVotingPeriodEnd()),
269  "max_answers" => array("integer", $this->getMaxNumberOfAnswers()),
270  "result_sort" => array("integer", $this->getSortResultByVotes()),
271  "non_anon" => array("integer", $this->getNonAnonymous()),
272  "show_results_as" => array("integer", $this->getShowResultsAs()),
273  );
274 
275  return $fields;
276  }
277 
278  protected function doCreate()
279  {
280  $ilDB = $this->db;
281 
282  if ($this->getId()) {
283  $fields = $this->propertiesToDB();
284  $fields["id"] = array("integer", $this->getId());
285 
286  $ilDB->insert("il_poll", $fields);
287 
288 
289  // object activation default entry will be created on demand
290 
291 
292  // block handling
293  include_once "Modules/Poll/classes/class.ilPollBlock.php";
294  $block = new ilPollBlock();
295  $block->setType("poll");
296  $block->setContextObjId($this->getId());
297  $block->setContextObjType("poll");
298  $block->create();
299  }
300  }
301 
302  protected function doUpdate()
303  {
304  $ilDB = $this->db;
305 
306  if ($this->getId()) {
307  $fields = $this->propertiesToDB();
308 
309  $ilDB->update(
310  "il_poll",
311  $fields,
312  array("id"=>array("integer", $this->getId()))
313  );
314 
315  // #14661
316  include_once("./Services/Notes/classes/class.ilNote.php");
317  ilNote::activateComments($this->getId(), 0, $this->getType(), $this->getShowComments());
318 
319  if ($this->ref_id) {
320  $activation = new ilObjectActivation();
321  $activation->setTimingType($this->getAccessType());
322  $activation->setTimingStart($this->getAccessBegin());
323  $activation->setTimingEnd($this->getAccessEnd());
324  $activation->toggleVisible($this->getAccessVisibility());
325  $activation->update($this->ref_id);
326  }
327  }
328  }
329 
330  protected function doDelete()
331  {
332  $ilDB = $this->db;
333 
334  if ($this->getId()) {
335  $this->deleteImage();
336  $this->deleteAllAnswers();
337 
338  if ($this->ref_id) {
340  }
341 
342  $ilDB->manipulate("DELETE FROM il_poll" .
343  " WHERE id = " . $ilDB->quote($this->id, "integer"));
344  }
345  }
346 
355  public function doCloneObject($new_obj, $a_target_id, $a_copy_id = 0)
356  {
357  assert($new_obj instanceof ilObjPoll);
358 
359  // question/image
360  $new_obj->setQuestion($this->getQuestion());
361  $image = $this->getImageFullPath();
362  if ($image) {
363  $image = array("tmp_name"=>$image,
364  "name"=>$this->getImage());
365  $new_obj->uploadImage($image, true);
366  }
367 
368  //copy online status if object is not the root copy object
369  $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
370 
371  if (!$cp_options->isRootNode($this->getRefId())) {
372  $new_obj->setOnline($this->isOnline());
373  }
374 
375  $new_obj->setViewResults($this->getViewResults());
376  $new_obj->setShowComments($this->getShowComments());
377  $new_obj->setShowResultsAs($this->getShowResultsAs());
378  $new_obj->update();
379 
380  // answers
381  $answers = $this->getAnswers();
382  if ($answers) {
383  foreach ($answers as $item) {
384  $new_obj->saveAnswer($item["answer"]);
385  }
386  }
387 
388  return $new_obj;
389  }
390 
391 
392  //
393  // image
394  //
395 
401  public function getImageFullPath($a_as_thumb = false)
402  {
403  $img = $this->getImage();
404  if ($img) {
405  $path = $this->initStorage($this->id);
406  if (!$a_as_thumb) {
407  return $path . $img;
408  } else {
409  return $path . "thb_" . $img;
410  }
411  }
412  }
413 
417  public function deleteImage()
418  {
419  if ($this->id) {
420  include_once "Modules/Poll/classes/class.ilFSStoragePoll.php";
421  $storage = new ilFSStoragePoll($this->id);
422  $storage->delete();
423 
424  $this->setImage(null);
425  }
426  }
427 
435  public static function initStorage($a_id, $a_subdir = null)
436  {
437  include_once "Modules/Poll/classes/class.ilFSStoragePoll.php";
438  $storage = new ilFSStoragePoll($a_id);
439  $storage->create();
440 
441  $path = $storage->getAbsolutePath() . "/";
442 
443  if ($a_subdir) {
444  $path .= $a_subdir . "/";
445 
446  if (!is_dir($path)) {
447  mkdir($path);
448  }
449  }
450 
451  return $path;
452  }
453 
460  public function uploadImage(array $a_upload, $a_clone = false)
461  {
462  if (!$this->id) {
463  return false;
464  }
465 
466  $this->deleteImage();
467 
468  // #10074
469  $clean_name = preg_replace("/[^a-zA-Z0-9\_\.\-]/", "", $a_upload["name"]);
470 
471  $path = $this->initStorage($this->id);
472  $original = "org_" . $this->id . "_" . $clean_name;
473  $thumb = "thb_" . $this->id . "_" . $clean_name;
474  $processed = $this->id . "_" . $clean_name;
475 
476  $success = false;
477  if (!$a_clone) {
478  $success = ilUtil::moveUploadedFile($a_upload["tmp_name"], $original, $path . $original);
479  } else {
480  $success = copy($a_upload["tmp_name"], $path . $original);
481  }
482 
483  if ($success) {
484  chmod($path . $original, 0770);
485 
486  // take quality 100 to avoid jpeg artefacts when uploading jpeg files
487  // taking only frame [0] to avoid problems with animated gifs
488  $original_file = ilUtil::escapeShellArg($path . $original);
489  $thumb_file = ilUtil::escapeShellArg($path . $thumb);
490  $processed_file = ilUtil::escapeShellArg($path . $processed);
491  ilUtil::execConvert($original_file . "[0] -geometry \"100x100>\" -quality 100 PNG:" . $thumb_file);
492  ilUtil::execConvert($original_file . "[0] -geometry \"" . self::getImageSize() . ">\" -quality 100 PNG:" . $processed_file);
493 
494  $this->setImage($processed);
495  return true;
496  }
497  return false;
498  }
499 
500  public static function getImageSize()
501  {
502  // :TODO:
503  return "300x300";
504  }
505 
506 
507  //
508  // Answer
509  //
510 
511  public function getAnswers()
512  {
513  $ilDB = $this->db;
514 
515  $res = array();
516 
517  $sql = "SELECT * FROM il_poll_answer" .
518  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer") .
519  " ORDER BY pos ASC";
520  $set = $ilDB->query($sql);
521  while ($row = $ilDB->fetchAssoc($set)) {
522  $res[] = $row;
523  }
524  return $res;
525  }
526 
527  public function getAnswer($a_id)
528  {
529  $ilDB = $this->db;
530 
531  $sql = "SELECT * FROM il_poll_answer" .
532  " WHERE id = " . $ilDB->quote($a_id, "integer");
533  $set = $ilDB->query($sql);
534  return (array) $ilDB->fetchAssoc($set);
535  }
536 
537  public function saveAnswer($a_text, $a_pos = null)
538  {
539  $ilDB = $this->db;
540 
541  if (!trim($a_text)) {
542  return;
543  }
544 
545  $id = $ilDB->nextId("il_poll_answer");
546 
547  if (!$a_pos) {
548  // append
549  $sql = "SELECT max(pos) pos" .
550  " FROM il_poll_answer" .
551  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer");
552  $set = $ilDB->query($sql);
553  $a_pos = $ilDB->fetchAssoc($set);
554  $a_pos = (int) $a_pos["pos"]+10;
555  }
556 
557  $fields = array(
558  "id" => array("integer", $id),
559  "poll_id" => array("integer", $this->getId()),
560  "answer" => array("text", trim($a_text)),
561  "pos" => array("integer", $a_pos)
562  );
563  $ilDB->insert("il_poll_answer", $fields);
564 
565  return $id;
566  }
567 
568  public function updateAnswer($a_id, $a_text)
569  {
570  $ilDB = $this->db;
571 
572  $ilDB->update(
573  "il_poll_answer",
574  array("answer" => array("text", $a_text)),
575  array("id" => array("integer", $a_id))
576  );
577  }
578 
579  public function rebuildAnswerPositions()
580  {
581  $answers = $this->getAnswers();
582 
583  $pos = array();
584  foreach ($answers as $item) {
585  $pos[$item["id"]] = $item["pos"];
586  }
587 
588  $this->updateAnswerPositions($pos);
589  }
590 
591  public function updateAnswerPositions(array $a_pos)
592  {
593  $ilDB = $this->db;
594 
595  asort($a_pos);
596 
597  $pos = 0;
598  foreach (array_keys($a_pos) as $id) {
599  $pos += 10;
600 
601  $ilDB->update(
602  "il_poll_answer",
603  array("pos" => array("integer", $pos)),
604  array("id" => array("integer", $id))
605  );
606  }
607  }
608 
609  public function deleteAnswer($a_id)
610  {
611  $ilDB = $this->db;
612 
613  if ($a_id) {
614  $ilDB->manipulate("DELETE FROM il_poll_vote" .
615  " WHERE answer_id = " . $ilDB->quote($this->getId(), "integer"));
616 
617  $ilDB->manipulate("DELETE FROM il_poll_answer" .
618  " WHERE id = " . $ilDB->quote($a_id, "integer"));
619  }
620  }
621 
622  protected function deleteAllAnswers()
623  {
624  $ilDB = $this->db;
625 
626  if ($this->getId()) {
627  $this->deleteAllVotes();
628 
629  $ilDB->manipulate("DELETE FROM il_poll_answer" .
630  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer"));
631  }
632  }
633 
634  public function deleteAllVotes()
635  {
636  $ilDB = $this->db;
637 
638  if ($this->getId()) {
639  $ilDB->manipulate("DELETE FROM il_poll_vote" .
640  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer"));
641  }
642  }
643 
644  public function saveAnswers(array $a_answers)
645  {
646  $existing = $this->getAnswers();
647 
648  $ids = array();
649  $pos = 0;
650  foreach ($a_answers as $answer) {
651  if (trim($answer)) {
652  // existing answer?
653  $found = false;
654  foreach ($existing as $idx => $item) {
655  if (trim($answer) == $item["answer"]) {
656  $found = true;
657  unset($existing[$idx]);
658 
659  $id = $item["id"];
660  }
661  }
662 
663  // create new answer
664  if (!$found) {
665  $id = $this->saveAnswer($answer);
666  }
667 
668  // add existing answer id to order
669  if ($id) {
670  $ids[$id] = ++$pos;
671  }
672  }
673  }
674 
675  // remove obsolete answers
676  if (sizeof($existing)) {
677  foreach ($existing as $item) {
678  $this->deleteAnswer($item["id"]);
679  }
680  }
681 
682  // save current order
683  if (sizeof($ids)) {
684  $this->updateAnswerPositions($ids);
685  }
686 
687  return sizeof($ids);
688  }
689 
690 
691  //
692  // votes
693  //
694 
695  public function saveVote($a_user_id, $a_answers)
696  {
697  $ilDB = $this->db;
698 
699  if ($this->hasUserVoted($a_user_id)) {
700  return;
701  }
702 
703  if (!is_array($a_answers)) {
704  $a_answers = array($a_answers);
705  }
706 
707  foreach ($a_answers as $answer_id) {
708  $fields = array("user_id" => array("integer", $a_user_id),
709  "poll_id" => array("integer", $this->getId()),
710  "answer_id" => array("integer", $answer_id));
711  $ilDB->insert("il_poll_vote", $fields);
712  }
713  }
714 
715  public function hasUserVoted($a_user_id)
716  {
717  $ilDB = $this->db;
718 
719  $sql = "SELECT user_id" .
720  " FROM il_poll_vote" .
721  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer") .
722  " AND user_id = " . $ilDB->quote($a_user_id, "integer");
723  $ilDB->setLimit(1);
724  $set = $ilDB->query($sql);
725  return (bool) $ilDB->numRows($set);
726  }
727 
728  public function countVotes()
729  {
730  $ilDB = $this->db;
731 
732  $sql = "SELECT COUNT(DISTINCT(user_id)) cnt" .
733  " FROM il_poll_vote" .
734  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer");
735  $set = $ilDB->query($sql);
736  $row = $ilDB->fetchAssoc($set);
737  return (int) $row["cnt"];
738  }
739 
740  public function getVotePercentages()
741  {
742  $ilDB = $this->db;
743 
744  $res = array();
745  $cnt = 0;
746 
747  $sql = "SELECT answer_id, count(*) cnt" .
748  " FROM il_poll_vote" .
749  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer") .
750  " GROUP BY answer_id";
751  $set = $ilDB->query($sql);
752  while ($row = $ilDB->fetchAssoc($set)) {
753  $cnt += $row["cnt"];
754  $res[$row["answer_id"]] = array("abs"=>$row["cnt"], "perc"=>0);
755  }
756 
757  foreach ($res as $id => $item) {
758  $res[$id]["perc"] = $item["abs"]/$cnt*100;
759  }
760 
761  return array("perc"=>$res, "total"=>$this->countVotes());
762  }
763 
764  public function getVotesByUsers()
765  {
766  $ilDB = $this->db;
767 
768  $res = array();
769 
770  $sql = "SELECT answer_id, user_id, firstname, lastname, login" .
771  " FROM il_poll_vote" .
772  " JOIN usr_data ON (usr_data.usr_id = il_poll_vote.user_id)" .
773  " WHERE poll_id = " . $ilDB->quote($this->getId(), "integer");
774  $set = $ilDB->query($sql);
775  while ($row = $ilDB->fetchAssoc($set)) {
776  if (!isset($res[$row["user_id"]])) {
777  $res[$row["user_id"]] = $row;
778  }
779  $res[$row["user_id"]]["answers"][] = $row["answer_id"];
780  }
781 
782  return $res;
783  }
784 }
deleteImage()
remove existing file
Add rich text string
const VIEW_RESULTS_AFTER_PERIOD
hasUserVoted($a_user_id)
const VIEW_RESULTS_AFTER_VOTE
const VIEW_RESULTS_NEVER
getImageFullPath($a_as_thumb=false)
Get image incl.
updateAnswer($a_id, $a_text)
setAccessEnd($a_value)
global $DIC
Definition: saml.php:7
setVotingPeriod($a_value)
const VIEW_RESULTS_ALWAYS
setAccessVisibility($a_value)
setAccessType($a_value)
static getItem($a_ref_id)
Get item data.
const SHOW_RESULTS_AS_PIECHART
setSortResultByVotes($a_value)
setQuestion($a_value)
setShowResultsAs($a_value)
setOnline($a_value)
setShowComments($a_value)
getAnswer($a_id)
saveAnswer($a_text, $a_pos=null)
setMaxNumberOfAnswers($a_value)
setAccessBegin($a_value)
const SHOW_RESULTS_AS_BARCHART
setImage($a_value)
saveVote($a_user_id, $a_answers)
Generate an image
static _getInstance($a_copy_id)
Get instance of copy wizard options.
$success
Definition: Utf8Test.php:86
foreach($_POST as $key=> $value) $res
static execConvert($args)
execute convert command
static getImageSize()
updateAnswerPositions(array $a_pos)
uploadImage(array $a_upload, $a_clone=false)
Upload new image file.
Create styles array
The data for the language used.
static initStorage($a_id, $a_subdir=null)
Init file system storage.
static deleteAllEntries($a_ref_id)
Delete all db entries for ref id.
Class ilObjPoll.
saveAnswers(array $a_answers)
static commentsActivated($a_rep_obj_id, $a_obj_id, $a_obj_type)
Are comments activated for object?
Custom block for polls.
doCloneObject($new_obj, $a_target_id, $a_copy_id=0)
Clone poll.
static activateComments($a_rep_obj_id, $a_obj_id, $a_obj_type, $a_activate=true)
Activate notes feature.
static escapeShellArg($a_arg)
__construct($a_id=0, $a_reference=true)
global $ilDB
Class ilObject2 This is an intermediate progress of ilObject class.
setNonAnonymous($a_value)
setViewResults($a_value)
setVotingPeriodBegin($a_value)
Class ilObjectActivation.
setVotingPeriodEnd($a_value)
deleteAnswer($a_id)