1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5include_once("./Services/Block/classes/class.ilBlockGUI.php");
6include_once("./Modules/Poll/classes/class.ilObjPoll.php");
7
8/**
9* BlockGUI class for polls.
10*
11* @author Jörg Lützenkirchen
12* @version $Id$
13*
14* @ilCtrl_IsCalledBy ilPollBlockGUI: ilColumnGUI
15* @ingroup ModulesPoll
16*/
17class ilPollBlockGUI extends ilBlockGUI
18{
19    public static $block_type = "poll";
20
21    protected $poll_block; // [ilPollBlock]
22
23    public static $js_init = false;
24
25    /**
26     * Constructor
27     */
28    public function __construct()
29    {
30        global $DIC;
31
32        $this->lng = $DIC->language();
33        $this->ctrl = $DIC->ctrl();
34        $this->user = $DIC->user();
35        $this->access = $DIC->access();
36        $lng = $DIC->language();
37
38        parent::__construct();
39
40        $lng->loadLanguageModule("poll");
41        $this->setRowTemplate("tpl.block.html", "Modules/Poll");
42    }
43
44    /**
45     * @inheritdoc
46     */
47    public function getBlockType() : string
48    {
49        return self::$block_type;
50    }
51
52    /**
53     * @inheritdoc
54     */
55    protected function isRepositoryObject() : bool
56    {
57        return true;
58    }
59
60    /**
61     * Get repository object GUI name
62     *
63     * @return string
64     */
65    protected function getRepositoryObjectGUIName()
66    {
67        return "ilobjpollgui";
68    }
69
70    /**
71     * Get Screen Mode for current command.
72     */
73    public static function getScreenMode()
74    {
75        return IL_SCREEN_SIDE;
76    }
77
78    /**
79     * Do most of the initialisation.
80     */
81    public function setBlock($a_block)
82    {
83        $this->setBlockId($a_block->getId());
84        $this->poll_block = $a_block;
85    }
86
87    /**
88     * execute command
89     */
90    public function executeCommand()
91    {
92        $ilCtrl = $this->ctrl;
93
94        $next_class = $ilCtrl->getNextClass();
95        $cmd = $ilCtrl->getCmd("getHTML");
96
97        switch ($next_class) {
98            default:
99                return $this->$cmd();
100        }
101    }
102
103    public function fillRow($a_poll)
104    {
105        $ilCtrl = $this->ctrl;
106        $lng = $this->lng;
107        $ilUser = $this->user;
108        $tpl = $this->main_tpl;
109
110
111        // handle messages
112
113        $mess = $this->poll_block->getMessage($ilUser->getId());
114        if ($mess) {
115            $this->tpl->setVariable("TXT_QUESTION", $mess);
116            return;
117        }
118
119
120        // nested form problem
121        if (!$_SESSION["il_cont_admin_panel"]) {
122            // vote
123
124            if ($this->poll_block->mayVote($ilUser->getId())) {
125                $this->tpl->setCurrentBlock("mode_info_bl");
126                if ($this->poll_block->getPoll()->getNonAnonymous()) {
127                    $mode_info = $lng->txt("poll_non_anonymous_warning");
128                } else {
129                    $mode_info = $lng->txt("poll_anonymous_warning");
130                }
131                $this->tpl->setVariable("MODE_INFO", $mode_info);
132                $this->tpl->parseCurrentBlock();
133
134                $is_multi_answer = ($this->poll_block->getPoll()->getMaxNumberOfAnswers() > 1);
135
136                if (isset($_SESSION["last_poll_vote"][$this->poll_block->getPoll()->getId()])) {
137                    $last_vote = $_SESSION["last_poll_vote"][$this->poll_block->getPoll()->getId()];
138                    unset($_SESSION["last_poll_vote"][$this->poll_block->getPoll()->getId()]);
139
140                    if ($is_multi_answer) {
141                        $error = sprintf(
142                            $lng->txt("poll_vote_error_multi"),
143                            $this->poll_block->getPoll()->getMaxNumberOfAnswers()
144                        );
145                    } else {
146                        $error = $lng->txt("poll_vote_error_single");
147                    }
148
149                    $this->tpl->setCurrentBlock("error_bl");
150                    $this->tpl->setVariable("FORM_ERROR", $error);
151                    $this->tpl->parseCurrentBlock();
152                }
153
154                $this->tpl->setCurrentBlock("answer");
155                foreach ($a_poll->getAnswers() as $item) {
156                    if (!$is_multi_answer) {
157                        $this->tpl->setVariable("ANSWER_INPUT", "radio");
158                        $this->tpl->setVariable("ANSWER_NAME", "aw");
159                    } else {
160                        $this->tpl->setVariable("ANSWER_INPUT", "checkbox");
161                        $this->tpl->setVariable("ANSWER_NAME", "aw[]");
162
163                        if (is_array($last_vote) && in_array($item["id"], $last_vote)) {
164                            $this->tpl->setVariable("ANSWER_STATUS", 'checked="checked"');
165                        }
166                    }
167                    $this->tpl->setVariable("VALUE_ANSWER", $item["id"]);
168                    $this->tpl->setVariable("TXT_ANSWER_VOTE", nl2br($item["answer"]));
169                    $this->tpl->parseCurrentBlock();
170                }
171
172                $ilCtrl->setParameterByClass(
173                    $this->getRepositoryObjectGUIName(),
174                    "ref_id",
175                    $this->getRefId()
176                );
177                $url = $ilCtrl->getLinkTargetByClass(
178                    array("ilrepositorygui", $this->getRepositoryObjectGUIName()),
179                    "vote"
180                );
181                $ilCtrl->clearParametersByClass($this->getRepositoryObjectGUIName());
182
183                $url .= "#poll" . $a_poll->getID();
184
185                $this->tpl->setVariable("URL_FORM", $url);
186                $this->tpl->setVariable("CMD_FORM", "vote");
187                $this->tpl->setVariable("TXT_SUBMIT", $lng->txt("poll_vote"));
188
189                if ($this->poll_block->getPoll()->getVotingPeriod()) {
190                    $this->tpl->setVariable(
191                        "TXT_VOTING_END_PERIOD",
192                        sprintf(
193                            $lng->txt("poll_voting_period_info"),
194                            ilDatePresentation::formatDate(new ilDateTime($this->poll_block->getPoll()->getVotingPeriodEnd(), IL_CAL_UNIX))
195                        )
196                    );
197                }
198            }
199
200
201            // result
202            if ($this->poll_block->maySeeResults($ilUser->getId())) {
203                if (!$this->poll_block->mayNotResultsYet($ilUser->getId())) {
204                    $answers = array();
205                    foreach ($a_poll->getAnswers() as $item) {
206                        $answers[$item["id"]] = $item["answer"];
207                    }
208
209                    $perc = $this->poll_block->getPoll()->getVotePercentages();
210                    $total = $perc["total"];
211                    $perc = $perc["perc"];
212
213                    $this->tpl->setVariable("TOTAL_ANSWERS", sprintf($lng->txt("poll_population"), $total));
214
215                    if ($total) {
216                        // sort results by votes / original position
217                        if ($this->poll_block->getPoll()->getSortResultByVotes()) {
218                            $order = array_keys(ilUtil::sortArray($perc, "abs", "desc", true, true));
219
220                            foreach (array_keys($answers) as $answer_id) {
221                                if (!in_array($answer_id, $order)) {
222                                    $order[] = $answer_id;
223                                }
224                            }
225                        } else {
226                            $order = array_keys($answers);
227                        }
228
229                        // pie chart
230                        if ($this->poll_block->showResultsAs() == ilObjPoll::SHOW_RESULTS_AS_PIECHART) {
231                            include_once("./Services/Chart/classes/class.ilChart.php");
232
233                            $chart = ilChart::getInstanceByType(ilCHart::TYPE_PIE, "poll_results_pie_" . $this->getRefId());
234                            $chart->setSize("100%", 200);
235                            $chart->setAutoResize(true);
236
237                            $chart_data = $chart->getDataInstance();
238
239                            foreach ($order as $answer_id) {
240                                $chart_data->addPoint(
241                                    round($perc[$answer_id]["perc"]),
242                                    nl2br($answers[$answer_id])
243                                );
244                            }
245
246                            // disable legend, use inner labels - currently not preferred
247                            // $chart_data->setLabelRadius(0.8);
248
249                            $chart->addData($chart_data);
250
251                            $pie_legend_id = "poll_legend_" . $this->getRefId();
252                            $legend = new ilChartLegend();
253                            $legend->setContainer($pie_legend_id);
254                            $chart->setLegend($legend);
255
256                            $this->tpl->setVariable("PIE_LEGEND_ID", $pie_legend_id);
257                            $this->tpl->setVariable("PIE_CHART", $chart->getHTML());
258                        } // bar chart
259                        else {
260                            include_once "Services/UIComponent/ProgressBar/classes/class.ilProgressBar.php";
261
262                            $this->tpl->setCurrentBlock("answer_result");
263                            foreach ($order as $answer_id) {
264                                $pbar = ilProgressBar::getInstance();
265                                $pbar->setCurrent(round($perc[$answer_id]["perc"]));
266                                $this->tpl->setVariable("PERC_ANSWER_RESULT", $pbar->render());
267                                $this->tpl->setVariable("TXT_ANSWER_RESULT", nl2br($answers[$answer_id]));
268                                $this->tpl->parseCurrentBlock();
269                            }
270                        }
271                    }
272                } else {
273                    $rel = ilDatePresentation::useRelativeDates();
274                    ilDatePresentation::setUseRelativeDates(false);
275                    $end = $this->poll_block->getPoll()->getVotingPeriodEnd();
276                    $end = ilDatePresentation::formatDate(new ilDateTime($end, IL_CAL_UNIX));
277                    ilDatePresentation::setUseRelativeDates($rel);
278
279                    // #14607
280                    $info = "";
281                    if ($this->poll_block->getPoll()->hasUserVoted($ilUser->getId())) {
282                        $info .= $lng->txt("poll_block_message_already_voted") . " ";
283                    }
284
285                    $this->tpl->setVariable("TOTAL_ANSWERS", $info .
286                        sprintf($lng->txt("poll_block_results_available_on"), $end));
287                }
288            } elseif ($this->poll_block->getPoll()->hasUserVoted($ilUser->getId())) {
289                $this->tpl->setVariable("TOTAL_ANSWERS", $lng->txt("poll_block_message_already_voted"));
290            }
291        }
292
293        if (!$this->poll_block->mayVote($ilUser->getId()) && !$this->poll_block->getPoll()->hasUserVoted($ilUser->getId())) {
294            if ($this->poll_block->getPoll()->getVotingPeriod()) {
295                $this->tpl->setVariable(
296                    "TXT_VOTING_PERIOD",
297                    sprintf(
298                        $lng->txt("poll_voting_period_full_info"),
299                        ilDatePresentation::formatDate(new ilDateTime($this->poll_block->getPoll()->getVotingPeriodBegin(), IL_CAL_UNIX)),
300                        ilDatePresentation::formatDate(new ilDateTime($this->poll_block->getPoll()->getVotingPeriodEnd(), IL_CAL_UNIX))
301                    )
302                );
303            }
304        } else {
305            $this->tpl->setVariable("TXT_QUESTION", nl2br(trim($a_poll->getQuestion())));
306
307            $img = $a_poll->getImageFullPath();
308            if ($img) {
309                require_once('./Services/WebAccessChecker/classes/class.ilWACSignedPath.php');
310                $this->tpl->setVariable("URL_IMAGE", ilWACSignedPath::signFile($img));
311            }
312        }
313
314
315        $this->tpl->setVariable("ANCHOR_ID", $a_poll->getID());
316        //$this->tpl->setVariable("TXT_QUESTION", nl2br(trim($a_poll->getQuestion())));
317
318        $desc = trim($a_poll->getDescription());
319        if ($desc) {
320            $this->tpl->setVariable("TXT_DESC", nl2br($desc));
321        }
322
323
324        if ($this->poll_block->showComments()) {
325            $this->tpl->setCurrentBlock("comment_link");
326            $this->tpl->setVariable("LANG_COMMENTS", $lng->txt('poll_comments'));
327            $this->tpl->setVariable("COMMENT_JSCALL", $this->commentJSCall());
328            $this->tpl->setVariable("COMMENTS_COUNT_ID", $this->getRefId());
329
330            $comments_count = $this->getNumberOfComments($this->getRefId());
331
332            if ($comments_count > 0) {
333                $this->tpl->setVariable("COMMENTS_COUNT", "(" . $comments_count . ")");
334            }
335
336            if (!self::$js_init) {
337                $redraw_url = $ilCtrl->getLinkTarget(
338                    $this,
339                    "getNumberOfCommentsForRedraw",
340                    "",
341                    true,
342                    false
343                );
344                $this->tpl->setVariable("COMMENTS_REDRAW_URL", $redraw_url);
345
346                $tpl->addJavaScript("Modules/Poll/js/ilPoll.js");
347                self::$js_init = true;
348            }
349        }
350    }
351
352    /**
353     * Get block HTML code.
354     */
355    public function getHTML()
356    {
357        $ilCtrl = $this->ctrl;
358        $lng = $this->lng;
359        $ilAccess = $this->access;
360        $ilUser = $this->user;
361
362        $this->poll_block->setRefId($this->getRefId());
363        $this->may_write = $ilAccess->checkAccess("write", "", $this->getRefId());
364        $this->has_content = $this->poll_block->hasAnyContent($ilUser->getId(), $this->getRefId());
365
366        #22078 and 22079 it always contains something.
367        /*if(!$this->may_write && !$this->has_content)
368        {
369            return "";
370        }*/
371
372        $poll_obj = $this->poll_block->getPoll();
373        $this->setTitle($poll_obj->getTitle());
374        $this->setData(array($poll_obj));
375
376        $ilCtrl->setParameterByClass(
377            $this->getRepositoryObjectGUIName(),
378            "ref_id",
379            $this->getRefId()
380        );
381
382        if (!$this->poll_block->getMessage($ilUser->getId())) {
383            // notification
384            include_once "./Services/Notification/classes/class.ilNotification.php";
385            if (ilNotification::hasNotification(ilNotification::TYPE_POLL, $ilUser->getId(), $this->poll_block->getPoll()->getId())) {
386                $this->addBlockCommand(
387                    $ilCtrl->getLinkTargetByClass(
388                        array("ilrepositorygui", $this->getRepositoryObjectGUIName()),
389                        "unsubscribe"
390                    ),
391                    $lng->txt("poll_notification_unsubscribe")
392                );
393            } else {
394                $this->addBlockCommand(
395                    $ilCtrl->getLinkTargetByClass(
396                        array("ilrepositorygui", $this->getRepositoryObjectGUIName()),
397                        "subscribe"
398                    ),
399                    $lng->txt("poll_notification_subscribe")
400                );
401            }
402        }
403
404        if ($this->may_write) {
405            // edit
406            $this->addBlockCommand(
407                $ilCtrl->getLinkTargetByClass(
408                    array("ilrepositorygui", $this->getRepositoryObjectGUIName()),
409                    "render"
410                ),
411                $lng->txt("edit_content")
412            );
413            $this->addBlockCommand(
414                $ilCtrl->getLinkTargetByClass(
415                    array("ilrepositorygui", $this->getRepositoryObjectGUIName()),
416                    "edit"
417                ),
418                $lng->txt("settings")
419            );
420        }
421
422        $ilCtrl->clearParametersByClass($this->getRepositoryObjectGUIName());
423
424        return parent::getHTML();
425    }
426
427    /**
428     * Builds JavaScript Call to open CommentLayer via html link
429     *
430     * @return string jsCall
431     */
432    private function commentJSCall()
433    {
434        include_once("./Services/Notes/classes/class.ilNoteGUI.php");
435        include_once("./Services/Object/classes/class.ilCommonActionDispatcherGUI.php");
436
437        $refId = $this->getRefId();
438        $objectId = ilObject2::_lookupObjectId($refId);
439
440        $ajaxHash = ilCommonActionDispatcherGUI::buildAjaxHash(
441            ilCommonActionDispatcherGUI::TYPE_REPOSITORY,
442            $refId,
443            "poll",
444            $objectId
445        );
446
447
448        $comment = new ilNoteGUI();
449        $jsCall = $comment->getListCommentsJSCall($ajaxHash, "ilPoll.redrawComments(" . $refId . ");");
450
451        return $jsCall;
452    }
453
454    /**
455     * Returns comment count for JS Redraw
456     */
457    public function getNumberOfCommentsForRedraw()
458    {
459        $number = $this->getNumberOfComments($_GET["poll_id"]);
460
461        if ($number > 0) {
462            echo "(" . $number . ")";
463        } else {
464            echo "";
465        }
466
467        exit();
468    }
469
470    /**
471     * Get comment count
472     *
473     * @param int $ref_id
474     * @return int
475     */
476    public function getNumberOfComments($ref_id)
477    {
478        include_once("./Services/Notes/classes/class.ilNote.php");
479
480        $obj_id = ilObject2::_lookupObjectId($ref_id);
481        $number = ilNote::_countNotesAndComments($obj_id);
482
483        if (count($number) == 0) {
484            return 0;
485        }
486
487        return $number[$obj_id][IL_NOTE_PUBLIC];
488    }
489
490    /**
491     * Fill data section
492     */
493    public function fillDataSection()
494    {
495        $this->setDataSection($this->getLegacyContent());
496    }
497
498    //
499    // New rendering
500    //
501
502    protected $new_rendering = true;
503
504
505    /**
506     * @inheritdoc
507     */
508    protected function getLegacyContent() : string
509    {
510        $this->tpl = new ilTemplate(
511            $this->getRowTemplateName(),
512            true,
513            true,
514            $this->getRowTemplateDir()
515        );
516        $this->fillRow(current($this->getData()));
517        return $this->tpl->get();
518    }
519}
520