1<?php
2
3/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5require_once("./Services/COPage/classes/class.ilPageContent.php");
6
7/**
8* Class ilPCPlugged
9* Plugged content object (see ILIAS DTD)
10*
11* @author Alex Killing <alex.killing@gmx.de>
12* @version $Id$
13*
14* @ingroup ServicesCOPage
15*/
16class ilPCPlugged extends ilPageContent
17{
18    /**
19     * @var ilLanguage
20     */
21    protected $lng;
22
23    /**
24     * @var ilPluginAdmin
25     */
26    protected $plugin_admin;
27
28    public $dom;
29    public $plug_node;
30
31    /**
32    * Init page content component.
33    */
34    public function init()
35    {
36        global $DIC;
37
38        $this->lng = $DIC->language();
39        $this->plugin_admin = $DIC["ilPluginAdmin"];
40        $this->setType("plug");
41    }
42
43    /**
44    * Set node
45    */
46    public function setNode($a_node)
47    {
48        parent::setNode($a_node);		// this is the PageContent node
49        $this->plug_node = $a_node->first_child();		// this is the Plugged node
50    }
51
52    /**
53    * Create plugged node in xml.
54    *
55    * @param	object	$a_pg_obj		Page Object
56    * @param	string	$a_hier_id		Hierarchical ID
57    */
58    public function create(
59        $a_pg_obj,
60        $a_hier_id,
61        $a_pc_id,
62        $a_plugin_name,
63        $a_plugin_version
64    ) {
65        $this->node = $this->createPageContentNode();
66        $a_pg_obj->insertContent($this, $a_hier_id, IL_INSERT_AFTER, $a_pc_id);
67        $this->plug_node = $this->dom->create_element("Plugged");
68        $this->plug_node = $this->node->append_child($this->plug_node);
69        $this->plug_node->set_attribute("PluginName", $a_plugin_name);
70        $this->plug_node->set_attribute("PluginVersion", $a_plugin_version);
71    }
72
73    /**
74    * Set properties of plugged component.
75    *
76    * @param	array	$a_properties		component properties
77    */
78    public function setProperties($a_properties)
79    {
80        if (!is_object($this->plug_node)) {
81            return;
82        }
83
84        // delete properties
85        $children = $this->plug_node->child_nodes();
86        for ($i = 0; $i < count($children); $i++) {
87            $this->plug_node->remove_child($children[$i]);
88        }
89        // set properties
90        foreach ($a_properties as $key => $value) {
91            $prop_node = $this->dom->create_element("PluggedProperty");
92            $prop_node = $this->plug_node->append_child($prop_node);
93            $prop_node->set_attribute("Name", $key);
94            if ($value != "") {
95                $prop_node->set_content($value);
96            }
97        }
98    }
99
100    /**
101    * Get properties of plugged component
102    *
103    * @return	string		characteristic
104    */
105    public function getProperties()
106    {
107        $properties = array();
108
109        if (is_object($this->plug_node)) {
110            // delete properties
111            $children = $this->plug_node->child_nodes();
112            for ($i = 0; $i < count($children); $i++) {
113                if ($children[$i]->node_name() == "PluggedProperty") {
114                    $properties[$children[$i]->get_attribute("Name")] =
115                        $children[$i]->get_content();
116                }
117            }
118        }
119
120        return $properties;
121    }
122
123    /**
124    * Set version of plugged component
125    *
126    * @param	string	$a_version		version
127    */
128    public function setPluginVersion($a_version)
129    {
130        if (!empty($a_version)) {
131            $this->plug_node->set_attribute("PluginVersion", $a_version);
132        } else {
133            if ($this->plug_node->has_attribute("PluginVersion")) {
134                $this->plug_node->remove_attribute("PluginVersion");
135            }
136        }
137    }
138
139    /**
140    * Get version of plugged component
141    *
142    * @return	string		version
143    */
144    public function getPluginVersion()
145    {
146        if (is_object($this->plug_node)) {
147            return $this->plug_node->get_attribute("PluginVersion");
148        }
149    }
150
151    /**
152    * Set name of plugged component
153    *
154    * @param	string	$a_name		name
155    */
156    public function setPluginName($a_name)
157    {
158        if (!empty($a_name)) {
159            $this->plug_node->set_attribute("PluginName", $a_name);
160        } else {
161            if ($this->plug_node->has_attribute("PluginName")) {
162                $this->plug_node->remove_attribute("PluginName");
163            }
164        }
165    }
166
167    /**
168    * Get name of plugged component
169    *
170    * @return	string		name
171    */
172    public function getPluginName()
173    {
174        if (is_object($this->plug_node)) {
175            return $this->plug_node->get_attribute("PluginName");
176        }
177    }
178
179    /**
180     * Handle copied plugged content. This function must, e.g. create copies of
181     * objects referenced within the content (e.g. question objects)
182     *
183     * @param ilPageObject	$a_page			the current page object
184     * @param DOMDocument 	$a_domdoc 		dom document
185     */
186    public static function handleCopiedPluggedContent(ilPageObject $a_page, DOMDocument $a_domdoc)
187    {
188        global $DIC;
189        $ilPluginAdmin = $DIC['ilPluginAdmin'];
190
191        $xpath = new DOMXPath($a_domdoc);
192        $nodes = $xpath->query("//Plugged");
193
194        /** @var DOMElement $node */
195        foreach ($nodes as $node) {
196            $plugin_name = $node->getAttribute('PluginName');
197            $plugin_version = $node->getAttribute('PluginVersion');
198
199            if ($ilPluginAdmin->isActive(IL_COMP_SERVICE, "COPage", "pgcp", $plugin_name)) {
200                /** @var ilPageComponentPlugin $plugin_obj */
201                $plugin_obj = $ilPluginAdmin->getPluginObject(IL_COMP_SERVICE, "COPage", "pgcp", $plugin_name);
202                $plugin_obj->setPageObj($a_page);
203
204                $properties = array();
205                /** @var DOMElement $child */
206                foreach ($node->childNodes as $child) {
207                    $properties[$child->getAttribute('Name')] = $child->nodeValue;
208                }
209
210                // let the plugin copy additional content
211                // and allow it to modify the saved parameters
212                $plugin_obj->onClone($properties, $plugin_version);
213
214                foreach ($node->childNodes as $child) {
215                    $node->removeChild($child);
216                }
217                foreach ($properties as $name => $value) {
218                    $child = new DOMElement('PluggedProperty', $value);
219                    $node->appendChild($child);
220                    $child->setAttribute('Name', $name);
221                }
222            }
223        }
224    }
225
226    /**
227     * Handle deleted plugged content. This function must, e.g. delete
228     * objects referenced within the content (e.g. question objects)
229     *
230     * @param ilPageObject	$a_page			the current page object
231     * @param DOMDocument 	$a_node 		dom node
232     */
233    public static function handleDeletedPluggedNode(ilPageObject $a_page, DOMNode $a_node)
234    {
235        global $DIC;
236        $ilPluginAdmin = $DIC['ilPluginAdmin'];
237
238        $plugin_name = $a_node->getAttribute('PluginName');
239        $plugin_version = $a_node->getAttribute('PluginVersion');
240
241        if ($ilPluginAdmin->isActive(IL_COMP_SERVICE, "COPage", "pgcp", $plugin_name)) {
242            /** @var ilPageComponentPlugin $plugin_obj */
243            $plugin_obj = $ilPluginAdmin->getPluginObject(IL_COMP_SERVICE, "COPage", "pgcp", $plugin_name);
244            $plugin_obj->setPageObj($a_page);
245
246            $properties = array();
247            /** @var DOMElement $child */
248            foreach ($a_node->childNodes as $child) {
249                $properties[$child->getAttribute('Name')] = $child->nodeValue;
250            }
251
252            // let the plugin delete additional content
253            $plugin_obj->onDelete($properties, $plugin_version);
254        }
255    }
256
257
258    /**
259     * @inheritDoc
260     */
261    public function modifyPageContentPostXsl($a_html, $a_mode, $a_abstract_only = false)
262    {
263        $lng = $this->lng;
264        $ilPluginAdmin = $this->plugin_admin;
265
266        $c_pos = 0;
267        $start = strpos($a_html, "{{{{{Plugged<pl");
268        //echo htmlentities($a_html)."-";
269        if (is_int($start)) {
270            $end = strpos($a_html, "}}}}}", $start);
271        }
272        $i = 1;
273
274        while ($end > 0) {
275            $param = substr($a_html, $start + 5, $end - $start - 5);
276            $param = str_replace(' xmlns:xhtml="http://www.w3.org/1999/xhtml"', "", $param);
277            $param = explode("<pl/>", $param);
278            //var_dump($param); exit;
279            $plugin_name = $param[1];
280            $plugin_version = $param[2];
281            $properties = array();
282
283            for ($i = 3; $i < count($param); $i += 2) {
284                $properties[$param[$i]] = $param[$i + 1];
285            }
286
287            // get html from plugin
288            if ($a_mode == "edit") {
289                $plugin_html = '<div class="ilBox">' . $lng->txt("content_plugin_not_activated") . " (" . $plugin_name . ")</div>";
290            }
291            if ($ilPluginAdmin->isActive(IL_COMP_SERVICE, "COPage", "pgcp", $plugin_name)) {
292                $plugin_obj = $ilPluginAdmin->getPluginObject(
293                    IL_COMP_SERVICE,
294                    "COPage",
295                    "pgcp",
296                    $plugin_name
297                );
298                $plugin_obj->setPageObj($this->getPage());
299                $gui_obj = $plugin_obj->getUIClassInstance();
300                $plugin_html = $gui_obj->getElementHTML($a_mode, $properties, $plugin_version);
301            }
302
303            $a_html = substr($a_html, 0, $start) .
304                $plugin_html .
305                substr($a_html, $end + 5);
306
307            if (strlen($a_html) > $start + 5) {
308                $start = strpos($a_html, "{{{{{Plugged<pl", $start + 5);
309            } else {
310                $start = false;
311            }
312            $end = 0;
313            if (is_int($start)) {
314                $end = strpos($a_html, "}}}}}", $start);
315            }
316        }
317
318        return $a_html;
319    }
320
321    /**
322     * Get javascript files
323     */
324    public function getJavascriptFiles($a_mode)
325    {
326        $ilPluginAdmin = $this->plugin_admin;
327
328        $js_files = array();
329
330        $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
331            IL_COMP_SERVICE,
332            "COPage",
333            "pgcp"
334        );
335        foreach ($pl_names as $pl_name) {
336            $plugin = $ilPluginAdmin->getPluginObject(
337                IL_COMP_SERVICE,
338                "COPage",
339                "pgcp",
340                $pl_name
341            );
342            $plugin->setPageObj($this->getPage());
343            $pl_dir = $plugin->getDirectory();
344
345            $pl_js_files = $plugin->getJavascriptFiles($a_mode);
346            foreach ($pl_js_files as $pl_js_file) {
347                if (!is_int(strpos($pl_js_file, "//"))) {
348                    $pl_js_file = $pl_dir . "/" . $pl_js_file;
349                }
350                if (!in_array($pl_js_file, $js_files)) {
351                    $js_files[] = $pl_js_file;
352                }
353            }
354        }
355        //var_dump($js_files);
356        return $js_files;
357    }
358
359    /**
360     * Get css files
361     */
362    public function getCssFiles($a_mode)
363    {
364        $ilPluginAdmin = $this->plugin_admin;
365
366        $css_files = array();
367
368        $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
369            IL_COMP_SERVICE,
370            "COPage",
371            "pgcp"
372        );
373        foreach ($pl_names as $pl_name) {
374            $plugin = $ilPluginAdmin->getPluginObject(
375                IL_COMP_SERVICE,
376                "COPage",
377                "pgcp",
378                $pl_name
379            );
380            $plugin->setPageObj($this->getPage());
381            $pl_dir = $plugin->getDirectory();
382
383            $pl_css_files = $plugin->getCssFiles($a_mode);
384            foreach ($pl_css_files as $pl_css_file) {
385                if (!is_int(strpos($pl_css_file, "//"))) {
386                    $pl_css_file = $pl_dir . "/" . $pl_css_file;
387                }
388                if (!in_array($pl_css_file, $css_files)) {
389                    $css_files[] = $pl_css_file;
390                }
391            }
392        }
393
394        return $css_files;
395    }
396}
397