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