1<?php
2
3/* Copyright (c) 1998-2011 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5require_once("./Services/COPage/classes/class.ilPageContent.php");
6
7/**
8* Class ilPCSection
9*
10* Section content object (see ILIAS DTD)
11*
12* @author Alex Killing <alex.killing@gmx.de>
13* @version $Id$
14*
15* @ingroup ServicesCOPage
16*/
17class ilPCSection extends ilPageContent
18{
19    /**
20     * @var ilAccessHandler
21     */
22    protected $access;
23
24    /**
25     * @var ilCtrl
26     */
27    protected $ctrl;
28
29    /**
30     * @var ilLanguage
31     */
32    protected $lng;
33
34    public $dom;
35    public $sec_node;
36
37    /**
38    * Init page content component.
39    */
40    public function init()
41    {
42        global $DIC;
43
44        $this->access = $DIC->access();
45        $this->ctrl = $DIC->ctrl();
46        $this->lng = $DIC->language();
47        $this->setType("sec");
48    }
49
50    /**
51    * Set node
52    */
53    public function setNode($a_node)
54    {
55        parent::setNode($a_node);		// this is the PageContent node
56        $this->sec_node = $a_node->first_child();		// this is the Section node
57    }
58
59    /**
60    * Create section node in xml.
61    *
62    * @param	object	$a_pg_obj		Page Object
63    * @param	string	$a_hier_id		Hierarchical ID
64    */
65    public function create(&$a_pg_obj, $a_hier_id, $a_pc_id = "")
66    {
67        $this->node = $this->createPageContentNode();
68        $a_pg_obj->insertContent($this, $a_hier_id, IL_INSERT_AFTER, $a_pc_id);
69        $this->sec_node = $this->dom->create_element("Section");
70        $this->sec_node = $this->node->append_child($this->sec_node);
71        $this->sec_node->set_attribute("Characteristic", "Block");
72    }
73
74    /**
75    * Set Characteristic of section
76    *
77    * @param	string	$a_char		Characteristic
78    */
79    public function setCharacteristic($a_char)
80    {
81        if (!empty($a_char)) {
82            $this->sec_node->set_attribute("Characteristic", $a_char);
83        } else {
84            if ($this->sec_node->has_attribute("Characteristic")) {
85                $this->sec_node->remove_attribute("Characteristic");
86            }
87        }
88    }
89
90    /**
91    * Get characteristic of section.
92    *
93    * @return	string		characteristic
94    */
95    public function getCharacteristic()
96    {
97        if (is_object($this->sec_node)) {
98            $char = $this->sec_node->get_attribute("Characteristic");
99            if (substr($char, 0, 4) == "ilc_") {
100                $char = substr($char, 4);
101            }
102            return $char;
103        }
104    }
105
106    /**
107     * Get lang vars needed for editing
108     * @return array array of lang var keys
109     */
110    public static function getLangVars()
111    {
112        return array("ed_insert_section");
113    }
114
115    /**
116     * After page has been updated (or created)
117     *
118     * @param object $a_page page object
119     * @param DOMDocument $a_domdoc dom document
120     * @param string $a_xml xml
121     * @param bool $a_creation true on creation, otherwise false
122     */
123    public static function afterPageUpdate($a_page, DOMDocument $a_domdoc, $a_xml, $a_creation)
124    {
125        include_once("./Services/COPage/classes/class.ilPCSection.php");
126        self::saveTimings($a_page);
127    }
128
129    /**
130     * Modify page content after xsl
131     *
132     * @param string $a_output
133     * @return string
134     */
135    public function modifyPageContentPostXsl($a_output, $a_mode)
136    {
137        $a_output = self::insertTimings($a_output);
138        $a_output = $this->handleAccess($a_output, $a_mode);
139
140        return $a_output;
141    }
142
143    /**
144     * Set activation from
145     *
146     * @param string $a_unix_ts unix ts activation from
147     */
148    public function setActiveFrom($a_unix_ts)
149    {
150        if ($a_unix_ts > 0) {
151            $this->sec_node->set_attribute("ActiveFrom", $a_unix_ts);
152        } else {
153            if ($this->sec_node->has_attribute("ActiveFrom")) {
154                $this->sec_node->remove_attribute("ActiveFrom");
155            }
156        }
157    }
158
159    /**
160     * Get activation from
161     *
162     * @return string unix ts activation from
163     */
164    public function getActiveFrom()
165    {
166        if (is_object($this->sec_node)) {
167            return $this->sec_node->get_attribute("ActiveFrom");
168        }
169
170        return "";
171    }
172
173    /**
174     * Set activation to
175     *
176     * @param string $a_unix_ts unix ts activation to
177     */
178    public function setActiveTo($a_unix_ts)
179    {
180        if ($a_unix_ts > 0) {
181            $this->sec_node->set_attribute("ActiveTo", $a_unix_ts);
182        } else {
183            if ($this->sec_node->has_attribute("ActiveTo")) {
184                $this->sec_node->remove_attribute("ActiveTo");
185            }
186        }
187    }
188
189    /**
190     * Get activation to
191     *
192     * @return string unix ts activation to
193     */
194    public function getActiveTo()
195    {
196        if (is_object($this->sec_node)) {
197            return $this->sec_node->get_attribute("ActiveTo");
198        }
199
200        return "";
201    }
202
203    /**
204     * Set attribute
205     *
206     * @param string $a_attr attribute
207     * @param string $a_val attribute value
208     */
209    protected function setAttribute($a_attr, $a_val)
210    {
211        if (!empty($a_val)) {
212            $this->sec_node->set_attribute($a_attr, $a_val);
213        } else {
214            if ($this->sec_node->has_attribute($a_attr)) {
215                $this->sec_node->remove_attribute($a_attr);
216            }
217        }
218    }
219
220    /**
221     * Get attribute
222     *
223     * @param string $a_attr attribute
224     * @return string attribute value
225     */
226    public function getAttribute($a_attr)
227    {
228        if (is_object($this->sec_node)) {
229            return $this->sec_node->get_attribute($a_attr);
230        }
231        return "";
232    }
233
234    /**
235     * Set permission
236     *
237     * @param string $a_val "read"|"write"|"visible"
238     */
239    public function setPermission($a_val)
240    {
241        $this->setAttribute("Permission", $a_val);
242    }
243
244    /**
245     * Get permission
246     *
247     * @return string
248     */
249    public function getPermission()
250    {
251        return $this->getAttribute("Permission");
252    }
253
254
255    /**
256     * Set permission ref id
257     *
258     * @param integer $a_ref_id ref id
259     */
260    public function setPermissionRefId($a_ref_id)
261    {
262        $this->setAttribute("PermissionRefId", "il__ref_" . $a_ref_id);
263    }
264
265    /**
266     * Get permission ref id
267     *
268     * @return int ref id
269     */
270    public function getPermissionRefId()
271    {
272        $id = explode("_", $this->getAttribute("PermissionRefId"));
273        if (in_array($id[1], array("", 0, IL_INST_ID))) {
274            return $id[3];
275        }
276        return "";
277    }
278
279    /**
280     * Set no link
281     */
282    public function setNoLink()
283    {
284        ilDOMUtil::deleteAllChildsByName($this->sec_node, array("IntLink", "ExtLink"));
285    }
286
287    /**
288     * Set link of area to an external one
289     * @param string $a_href
290     */
291    public function setExtLink($a_href)
292    {
293        $this->setNoLink();
294        if (trim($a_href) != "") {
295            $attributes = array("Href" => trim($a_href));
296            ilDOMUtil::setFirstOptionalElement(
297                $this->dom,
298                $this->sec_node,
299                "ExtLink",
300                array(""),
301                "",
302                $attributes
303            );
304        }
305    }
306
307    /**
308     * Set link of area to an internal one
309     */
310    public function setIntLink($a_type, $a_target, $a_target_frame)
311    {
312        $this->setNoLink();
313        $attributes = array("Type" => $a_type, "Target" => $a_target,
314            "TargetFrame" => $a_target_frame);
315        ilDOMUtil::setFirstOptionalElement(
316            $this->dom,
317            $this->sec_node,
318            "IntLink",
319            array(""),
320            "",
321            $attributes
322        );
323    }
324
325    /**
326     * Get link
327     *
328     * @param
329     * @return
330     */
331    public function getLink()
332    {
333        $childs = $this->sec_node->child_nodes();
334        foreach ($childs as $child) {
335            if ($child->node_name() == "ExtLink") {
336                return array("LinkType" => "ExtLink",
337                    "Href" => $child->get_attribute("Href"));
338            }
339            if ($child->node_name() == "IntLink") {
340                return array("LinkType" => "IntLink",
341                    "Target" => $child->get_attribute("Target"),
342                    "Type" => $child->get_attribute("Type"),
343                    "TargetFrame" => $child->get_attribute("TargetFrame"));
344            }
345        }
346        return array("LinkType" => "NoLink");
347    }
348
349
350    /**
351     * @param $a_html
352     * @param $a_mode
353     * @return mixed|string
354     */
355    public function handleAccess($a_html, $a_mode)
356    {
357        $ilAccess = $this->access;
358
359        while (($start = strpos($a_html, "{{{{{Section;Access;")) > 0) {
360            $end = strpos($a_html, "}}}}}", $start);
361            $access_attr = explode(";", substr($a_html, $start, $end - $start));
362            $id = explode("_", $access_attr[3]);
363            $section_nr = $access_attr[6];
364            $access = true;
365
366            if (in_array($id[1], array("", 0, IL_INST_ID)) && $id[3] > 0) {
367                $access = $ilAccess->checkAccess($access_attr[5], "", $id[3]);
368            }
369            $end_limiter = "{{{{{Section;AccessEnd;".$section_nr."}}}}}";
370            if ($access) {
371                $a_html = substr($a_html, 0, $start) . substr($a_html, $end + 5);
372                $a_html = str_replace($end_limiter, "", $a_html);
373            } else {
374                $end = strpos($a_html, $end_limiter, $start);
375                $a_html = substr($a_html, 0, $start) . substr($a_html, $end + strlen($end_limiter));
376            }
377        }
378
379        $a_html = str_replace("{{{{{Section;Access}}}}}", "", $a_html);
380
381        return $a_html;
382    }
383
384    /**
385     * Save timings
386     *
387     * @param ilPageObject $a_page  page object
388     */
389    public static function saveTimings($a_page)
390    {
391        global $DIC;
392
393        $ilDB = $DIC->database();
394
395        $ilDB->manipulate(
396            "DELETE FROM copg_section_timings WHERE " .
397            " page_id = " . $ilDB->quote($a_page->getId(), "integer") .
398            " AND parent_type = " . $ilDB->quote($a_page->getParentType(), "text")
399        );
400
401        $xml = $a_page->getXMLFromDom();
402
403        $doc = domxml_open_mem($xml);
404
405        // media aliases
406        $xpc = xpath_new_context($doc);
407        $path = "//Section";
408        $res = xpath_eval($xpc, $path);
409        for ($i = 0; $i < count($res->nodeset); $i++) {
410            $from = $res->nodeset[$i]->get_attribute("ActiveFrom");
411            if ($from != "") {
412                $ilDB->replace(
413                    "copg_section_timings",
414                    array(
415                        "page_id" => array("integer", $a_page->getId()),
416                        "parent_type" => array("text", $a_page->getParentType()),
417                        "unix_ts" => array("integer", $from)
418                        ),
419                    array()
420                );
421            }
422            $to = $res->nodeset[$i]->get_attribute("ActiveTo");
423            if ($to != "") {
424                $ilDB->replace(
425                    "copg_section_timings",
426                    array(
427                        "page_id" => array("integer", $a_page->getId()),
428                        "parent_type" => array("text", $a_page->getParentType()),
429                        "unix_ts" => array("integer", $to)
430                    ),
431                    array()
432                );
433            }
434        }
435    }
436
437    /**
438     * Get page cache update trigger string
439     *
440     * @param ilPageObject $a_page
441     * @return string trigger string
442     */
443    public static function getCacheTriggerString($a_page)
444    {
445        global $DIC;
446
447        $ilDB = $DIC->database();
448
449        $set = $ilDB->query(
450            "SELECT * FROM copg_section_timings " .
451            " WHERE page_id = " . $ilDB->quote($a_page->getId(), "integer") .
452            " AND parent_type = " . $ilDB->quote($a_page->getParentType(), "text")
453        );
454        $str = "1";     // changed to 1 to force cache miss for #24277
455        $current_ts = new ilDateTime(time(), IL_CAL_UNIX);
456        $current_ts = $current_ts->get(IL_CAL_UNIX);
457        while ($rec = $ilDB->fetchAssoc($set)) {
458            $unix_ts = $rec["unix_ts"];
459            if ($unix_ts < $current_ts) {
460                $unix_ts .= "a";
461            }
462            $str .= "-" . $unix_ts;
463        }
464
465        return $str;
466    }
467
468    /**
469     * Insert timings (in edit mode)
470     *
471     * @param string $a_html html
472     * @return string htmls
473     */
474    public function insertTimings($a_html)
475    {
476        $ilCtrl = $this->ctrl;
477        $lng = $this->lng;
478
479        $c_pos = 0;
480        $start = strpos($a_html, "{{{{{Section;ActiveFrom");
481        if (is_int($start)) {
482            $end = strpos($a_html, "}}}}}", $start);
483        }
484        $i = 1;
485        while ($end > 0) {
486            $param = substr($a_html, $start + 13, $end - $start - 13);
487            $param = explode(";", $param);
488            $from = $param[1];
489            $to = $param[3];
490            $html = "";
491            if ($from != "") {
492                ilDatePresentation::setUseRelativeDates(false);
493                $from = new ilDateTime($from, IL_CAL_UNIX);
494                $html .= $lng->txt("cont_active_from") . ": " . ilDatePresentation::formatDate($from);
495            }
496            if ($to != "") {
497                $to = new ilDateTime($to, IL_CAL_UNIX);
498                $html .= " " . $lng->txt("cont_active_to") . ": " . ilDatePresentation::formatDate($to);
499            }
500
501            $h2 = substr($a_html, 0, $start) .
502                $html .
503                substr($a_html, $end + 5);
504            $a_html = $h2;
505            $i++;
506
507            $start = strpos($a_html, "{{{{{Section;ActiveFrom;", $start + 5);
508            $end = 0;
509            if (is_int($start)) {
510                $end = strpos($a_html, "}}}}}", $start);
511            }
512        }
513        return $a_html;
514    }
515}
516