ILIAS  release_4-3 Revision
 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 
31  const VIEW_RESULTS_NEVER = 2;
34 
35  function __construct($a_id = 0, $a_reference = true)
36  {
37  // default
38  $this->setOnline(false);
39  $this->setViewResults(self::VIEW_RESULTS_AFTER_VOTE);
41  $this->setVotingPeriod(false);
42 
43  parent::__construct($a_id, $a_reference);
44  }
45 
46  function initType()
47  {
48  $this->type = "poll";
49  }
50 
51  function setOnline($a_value)
52  {
53  $this->online = (bool)$a_value;
54  }
55 
56  function isOnline()
57  {
58  return $this->online;
59  }
60 
61  function setAccessType($a_value)
62  {
63  $this->access_type = (int)$a_value;
64  }
65 
66  function getAccessType()
67  {
68  return $this->access_type;
69  }
70 
71  function setAccessBegin($a_value)
72  {
73  $this->access_begin = (int)$a_value;
74  }
75 
76  function getAccessBegin()
77  {
78  return $this->access_begin;
79  }
80 
81  function setAccessEnd($a_value)
82  {
83  $this->access_end = (int)$a_value;
84  }
85 
86  function getAccessEnd()
87  {
88  return $this->access_end;
89  }
90 
91  function setAccessVisibility($a_value)
92  {
93  $this->access_visibility = (bool)$a_value;
94  }
95 
97  {
99  }
100 
101  function setQuestion($a_value)
102  {
103  $this->question = (string)$a_value;
104  }
105 
106  function getQuestion()
107  {
108  return $this->question;
109  }
110 
111  function setImage($a_value)
112  {
113  $this->image = (string)$a_value;
114  }
115 
116  function getImage()
117  {
118  return $this->image;
119  }
120 
121  function setViewResults($a_value)
122  {
123  $this->view_results = (int)$a_value;
124  }
125 
126  function getViewResults()
127  {
128  return $this->view_results;
129  }
130 
131  function setVotingPeriod($a_value)
132  {
133  $this->period = (bool)$a_value;
134  }
135 
136  function getVotingPeriod()
137  {
138  return $this->period;
139  }
140 
141  function setVotingPeriodBegin($a_value)
142  {
143  $this->period_begin = (int)$a_value;
144  }
145 
147  {
148  return $this->period_begin;
149  }
150 
151  function setVotingPeriodEnd($a_value)
152  {
153  $this->period_end = (int)$a_value;
154  }
155 
157  {
158  return $this->period_end;
159  }
160 
161  protected function doRead()
162  {
163  global $ilDB;
164 
165  $set = $ilDB->query("SELECT * FROM il_poll".
166  " WHERE id = ".$ilDB->quote($this->getId(), "integer"));
167  $row = $ilDB->fetchAssoc($set);
168  $this->setQuestion($row["question"]);
169  $this->setImage($row["image"]);
170  $this->setOnline($row["online_status"]);
171  $this->setViewResults($row["view_results"]);
172  $this->setVotingPeriod($row["period"]);
173  $this->setVotingPeriodBegin($row["period_begin"]);
174  $this->setVotingPeriodEnd($row["period_end"]);
175 
176  if($this->ref_id)
177  {
178  $activation = ilObjectActivation::getItem($this->ref_id);
179  $this->setAccessType($activation["timing_type"]);
180  $this->setAccessBegin($activation["timing_start"]);
181  $this->setAccessEnd($activation["timing_end"]);
182  $this->setAccessVisibility($activation["visible"]);
183  }
184  }
185 
186  protected function propertiesToDB()
187  {
188  $fields = array(
189  "question" => array("text", $this->getQuestion()),
190  "image" => array("text", $this->getImage()),
191  "online_status" => array("integer", $this->isOnline()),
192  "view_results" => array("integer", $this->getViewResults()),
193  "period" => array("integer", $this->getVotingPeriod()),
194  "period_begin" => array("integer", $this->getVotingPeriodBegin()),
195  "period_end" => array("integer", $this->getVotingPeriodEnd())
196  );
197 
198  return $fields;
199  }
200 
201  protected function doCreate()
202  {
203  global $ilDB;
204 
205  if($this->getId())
206  {
207  $fields = $this->propertiesToDB();
208  $fields["id"] = array("integer", $this->getId());
209 
210  $ilDB->insert("il_poll", $fields);
211 
212 
213  // object activation default entry will be created on demand
214 
215 
216  // block handling
217  include_once "Modules/Poll/classes/class.ilPollBlock.php";
218  $block = new ilPollBlock();
219  $block->setType("poll");
220  $block->setContextObjId($this->getId());
221  $block->setContextObjType("poll");
222  $block->create();
223  }
224  }
225 
226  protected function doUpdate()
227  {
228  global $ilDB;
229 
230  if($this->getId())
231  {
232  $fields = $this->propertiesToDB();
233 
234  $ilDB->update("il_poll", $fields,
235  array("id"=>array("integer", $this->getId())));
236 
237 
238  if($this->ref_id)
239  {
240  $activation = new ilObjectActivation();
241  $activation->setTimingType($this->getAccessType());
242  $activation->setTimingStart($this->getAccessBegin());
243  $activation->setTimingEnd($this->getAccessEnd());
244  $activation->toggleVisible($this->getAccessVisibility());
245  $activation->update($this->ref_id);
246  }
247 
248  }
249  }
250 
251  protected function doDelete()
252  {
253  global $ilDB;
254 
255  if($this->getId())
256  {
257  $this->deleteImage();
258  $this->deleteAllAnswers();
259 
260  if($this->ref_id)
261  {
263  }
264 
265  $ilDB->manipulate("DELETE FROM il_poll".
266  " WHERE id = ".$ilDB->quote($this->id, "integer"));
267  }
268  }
269 
278  public function doCloneObject(ilObjPoll $new_obj, $a_target_id, $a_copy_id = 0)
279  {
280  // question/image
281  $new_obj->setQuestion($this->getQuestion());
282  $image = $this->getImageFullPath();
283  if($image)
284  {
285  $image = array("tmp_name"=>$image,
286  "name"=>$this->getImage());
287  $new_obj->uploadImage($image, true);
288  }
289  $new_obj->setViewResults($this->getViewResults());
290  $new_obj->update();
291 
292  // answers
293  $answers = $this->getAnswers();
294  if($answers)
295  {
296  foreach($answers as $item)
297  {
298  $new_obj->saveAnswer($item["answer"]);
299  }
300  }
301 
302  return $new_obj;
303  }
304 
305 
306  //
307  // image
308  //
309 
315  function getImageFullPath($a_as_thumb = false)
316  {
317  $img = $this->getImage();
318  if($img)
319  {
320  $path = $this->initStorage($this->id);
321  if(!$a_as_thumb)
322  {
323  return $path.$img;
324  }
325  else
326  {
327  return $path."thb_".$img;
328  }
329  }
330  }
331 
335  public function deleteImage()
336  {
337  if($this->id)
338  {
339  include_once "Modules/Poll/classes/class.ilFSStoragePoll.php";
340  $storage = new ilFSStoragePoll($this->id);
341  $storage->delete();
342 
343  $this->setImage(null);
344  }
345  }
346 
354  public static function initStorage($a_id, $a_subdir = null)
355  {
356  include_once "Modules/Poll/classes/class.ilFSStoragePoll.php";
357  $storage = new ilFSStoragePoll($a_id);
358  $storage->create();
359 
360  $path = $storage->getAbsolutePath()."/";
361 
362  if($a_subdir)
363  {
364  $path .= $a_subdir."/";
365 
366  if(!is_dir($path))
367  {
368  mkdir($path);
369  }
370  }
371 
372  return $path;
373  }
374 
381  function uploadImage(array $a_upload, $a_clone = false)
382  {
383  if(!$this->id)
384  {
385  return false;
386  }
387 
388  $this->deleteImage();
389 
390  // #10074
391  $clean_name = preg_replace("/[^a-zA-Z0-9\_\.\-]/", "", $a_upload["name"]);
392 
393  $path = $this->initStorage($this->id);
394  $original = "org_".$this->id."_".$clean_name;
395  $thumb = "thb_".$this->id."_".$clean_name;
396  $processed = $this->id."_".$clean_name;
397 
398  $success = false;
399  if(!$a_clone)
400  {
401  $success = @move_uploaded_file($a_upload["tmp_name"], $path.$original);
402  }
403  else
404  {
405  $success = @copy($a_upload["tmp_name"], $path.$original);
406  }
407 
408  if($success)
409  {
410  chmod($path.$original, 0770);
411 
412  // take quality 100 to avoid jpeg artefacts when uploading jpeg files
413  // taking only frame [0] to avoid problems with animated gifs
414  $original_file = ilUtil::escapeShellArg($path.$original);
415  $thumb_file = ilUtil::escapeShellArg($path.$thumb);
416  $processed_file = ilUtil::escapeShellArg($path.$processed);
417  ilUtil::execConvert($original_file."[0] -geometry \"100x100>\" -quality 100 PNG:".$thumb_file);
418  ilUtil::execConvert($original_file."[0] -geometry \"".self::getImageSize().">\" -quality 100 PNG:".$processed_file);
419 
420  $this->setImage($processed);
421  return true;
422  }
423  return false;
424  }
425 
426  public static function getImageSize()
427  {
428  // :TODO:
429  return "300x300";
430  }
431 
432 
433  //
434  // Answer
435  //
436 
437  function getAnswers()
438  {
439  global $ilDB;
440 
441  $res = array();
442 
443  $sql = "SELECT * FROM il_poll_answer".
444  " WHERE poll_id = ".$ilDB->quote($this->getId(), "integer").
445  " ORDER BY pos ASC";
446  $set = $ilDB->query($sql);
447  while($row = $ilDB->fetchAssoc($set))
448  {
449  $res[] = $row;
450  }
451  return $res;
452  }
453 
454  function getAnswer($a_id)
455  {
456  global $ilDB;
457 
458  $sql = "SELECT * FROM il_poll_answer".
459  " WHERE id = ".$ilDB->quote($a_id, "integer");
460  $set = $ilDB->query($sql);
461  return (array)$ilDB->fetchAssoc($set);
462  }
463 
464  function saveAnswer($a_text, $a_pos = null)
465  {
466  global $ilDB;
467 
468  if(!trim($a_text))
469  {
470  return;
471  }
472 
473  $id = $ilDB->nextId("il_poll_answer");
474 
475  if(!$a_pos)
476  {
477  // append
478  $sql = "SELECT max(pos) pos".
479  " FROM il_poll_answer".
480  " WHERE poll_id = ".$ilDB->quote($this->getId(), "integer");
481  $set = $ilDB->query($sql);
482  $a_pos = $ilDB->fetchAssoc($set);
483  $a_pos = (int)$a_pos["pos"]+10;
484  }
485 
486  $fields = array(
487  "id" => array("integer", $id),
488  "poll_id" => array("integer", $this->getId()),
489  "answer" => array("text", trim($a_text)),
490  "pos" => array("integer", $a_pos)
491  );
492  $ilDB->insert("il_poll_answer", $fields);
493 
494  return $id;
495  }
496 
497  function updateAnswer($a_id, $a_text)
498  {
499  global $ilDB;
500 
501  $ilDB->update("il_poll_answer",
502  array("answer" => array("text", $a_text)),
503  array("id" => array("integer", $a_id)));
504  }
505 
507  {
508  $answers = $this->getAnswers();
509 
510  $pos = array();
511  foreach($answers as $item)
512  {
513  $pos[$item["id"]] = $item["pos"];
514  }
515 
516  $this->updateAnswerPositions($pos);
517  }
518 
519  function updateAnswerPositions(array $a_pos)
520  {
521  global $ilDB;
522 
523  asort($a_pos);
524 
525  $pos = 0;
526  foreach(array_keys($a_pos) as $id)
527  {
528  $pos += 10;
529 
530  $ilDB->update("il_poll_answer",
531  array("pos" => array("integer", $pos)),
532  array("id" => array("integer", $id)));
533  }
534  }
535 
536  function deleteAnswer($a_id)
537  {
538  global $ilDB;
539 
540  if($a_id)
541  {
542  $ilDB->manipulate("DELETE FROM il_poll_vote".
543  " WHERE answer_id = ".$ilDB->quote($this->getId(), "integer"));
544 
545  $ilDB->manipulate("DELETE FROM il_poll_answer".
546  " WHERE id = ".$ilDB->quote($a_id, "integer"));
547  }
548  }
549 
550  protected function deleteAllAnswers()
551  {
552  global $ilDB;
553 
554  if($this->getId())
555  {
556  $this->deleteAllVotes();
557 
558  $ilDB->manipulate("DELETE FROM il_poll_answer".
559  " WHERE poll_id = ".$ilDB->quote($this->getId(), "integer"));
560  }
561  }
562 
563  public function deleteAllVotes()
564  {
565  global $ilDB;
566 
567  if($this->getId())
568  {
569  $ilDB->manipulate("DELETE FROM il_poll_vote".
570  " WHERE poll_id = ".$ilDB->quote($this->getId(), "integer"));
571  }
572  }
573 
574  function saveAnswers(array $a_answers)
575  {
576  $existing = $this->getAnswers();
577 
578  $ids = array();
579  $pos = 0;
580  foreach($a_answers as $answer)
581  {
582  if(trim($answer))
583  {
584  // existing answer?
585  $found = false;
586  foreach($existing as $idx => $item)
587  {
588  if(trim($answer) == $item["answer"])
589  {
590  $found = true;
591  unset($existing[$idx]);
592 
593  $id = $item["id"];
594  }
595  }
596 
597  // create new answer
598  if(!$found)
599  {
600  $id = $this->saveAnswer($answer);
601  }
602 
603  // add existing answer id to order
604  if($id)
605  {
606  $ids[$id] = ++$pos;
607  }
608  }
609  }
610 
611  // remove obsolete answers
612  if(sizeof($existing))
613  {
614  foreach($existing as $item)
615  {
616  $this->deleteAnswer($item["id"]);
617  }
618  }
619 
620  // save current order
621  if(sizeof($ids))
622  {
623  $this->updateAnswerPositions($ids);
624  }
625  }
626 
627 
628  //
629  // votes
630  //
631 
632  function saveVote($a_user_id, $a_answer_id)
633  {
634  global $ilDB;
635 
636  if($this->hasUserVoted($a_user_id))
637  {
638  return;
639  }
640 
641  $fields = array("user_id" => array("integer", $a_user_id),
642  "poll_id" => array("integer", $this->getId()),
643  "answer_id" => array("integer", $a_answer_id));
644 
645  $ilDB->insert("il_poll_vote", $fields);
646  }
647 
648  function hasUserVoted($a_user_id)
649  {
650  global $ilDB;
651 
652  $sql = "SELECT user_id".
653  " FROM il_poll_vote".
654  " WHERE poll_id = ".$ilDB->quote($this->getId(), "integer").
655  " AND user_id = ".$ilDB->quote($a_user_id, "integer");
656  $set = $ilDB->query($sql);
657  return (bool)$ilDB->numRows($set);
658  }
659 
660  function countVotes()
661  {
662  global $ilDB;
663 
664  $sql = "SELECT count(*) cnt".
665  " FROM il_poll_vote".
666  " WHERE poll_id = ".$ilDB->quote($this->getId(), "integer");
667  $set = $ilDB->query($sql);
668  $row = $ilDB->fetchAssoc($set);
669  return (int)$row["cnt"];
670  }
671 
673  {
674  global $ilDB;
675 
676  $res = array();
677  $cnt = 0;
678 
679  $sql = "SELECT answer_id, count(*) cnt".
680  " FROM il_poll_vote".
681  " WHERE poll_id = ".$ilDB->quote($this->getId(), "integer").
682  " GROUP BY answer_id";
683  $set = $ilDB->query($sql);
684  while($row = $ilDB->fetchAssoc($set))
685  {
686  $cnt += $row["cnt"];
687  $res[$row["answer_id"]] = array("abs"=>$row["cnt"], "perc"=>0);
688  }
689 
690  foreach($res as $id => $item)
691  {
692  $res[$id]["perc"] = $item["abs"]/$cnt*100;
693  }
694 
695  return array("perc"=>$res, "total"=>$cnt);
696  }
697 }
698 
699 ?>