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
5require_once "Services/Object/classes/class.ilObject2.php";
6require_once "Services/Object/classes/class.ilObjectActivation.php";
7
16class 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
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 {
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 {
212 }
213
214 public function setShowResultsAs($a_value)
215 {
216 $this->show_results_as = (int) $a_value;
217 }
218
219 public function getShowResultsAs()
220 {
222 }
223
224 protected function doRead()
225 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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}
$success
Definition: Utf8Test.php:86
An exception for terminatinating execution or to throw for unit testing.
static _getInstance($a_copy_id)
Get instance of copy wizard options.
static commentsActivated($a_rep_obj_id, $a_obj_id, $a_obj_type)
Are comments activated for object?
static activateComments($a_rep_obj_id, $a_obj_id, $a_obj_type, $a_activate=true)
Activate notes feature.
Class ilObjPoll.
setShowResultsAs($a_value)
const VIEW_RESULTS_ALWAYS
uploadImage(array $a_upload, $a_clone=false)
Upload new image file.
__construct($a_id=0, $a_reference=true)
Constructor @access public.
setNonAnonymous($a_value)
setImage($a_value)
setQuestion($a_value)
static initStorage($a_id, $a_subdir=null)
Init file system storage.
setVotingPeriodBegin($a_value)
const SHOW_RESULTS_AS_PIECHART
saveAnswer($a_text, $a_pos=null)
setAccessBegin($a_value)
const VIEW_RESULTS_AFTER_VOTE
setMaxNumberOfAnswers($a_value)
setVotingPeriod($a_value)
updateAnswerPositions(array $a_pos)
setAccessEnd($a_value)
const SHOW_RESULTS_AS_BARCHART
static getImageSize()
saveAnswers(array $a_answers)
setSortResultByVotes($a_value)
setAccessType($a_value)
const VIEW_RESULTS_AFTER_PERIOD
updateAnswer($a_id, $a_text)
const VIEW_RESULTS_NEVER
doCloneObject($new_obj, $a_target_id, $a_copy_id=0)
Clone poll.
saveVote($a_user_id, $a_answers)
deleteImage()
remove existing file
setOnline($a_value)
setVotingPeriodEnd($a_value)
setAccessVisibility($a_value)
getAnswer($a_id)
setShowComments($a_value)
hasUserVoted($a_user_id)
getImageFullPath($a_as_thumb=false)
Get image incl.
deleteAnswer($a_id)
setViewResults($a_value)
Class ilObject2 This is an intermediate progress of ilObject class.
getType()
get object type @access public
getId()
get object id @access public
Class ilObjectActivation.
static deleteAllEntries($a_ref_id)
Delete all db entries for ref id.
static getItem($a_ref_id)
Get item data.
Custom block for polls.
static escapeShellArg($a_arg)
static execConvert($args)
execute convert command
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB