1<?php
2
3/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5/**
6 * Page for user portfolio
7 *
8 * @author Jörg Lützenkirchen <luetzenkirchen@leifos.com>
9 */
10class ilPortfolioPage extends ilPageObject
11{
12    protected $portfolio_id;
13    protected $type = 1;
14    protected $title;
15    protected $order_nr;
16
17    const TYPE_PAGE = 1;
18    const TYPE_BLOG = 2;
19
20    /**
21     * Get parent type
22     *
23     * @return string parent type
24     */
25    public function getParentType()
26    {
27        return "prtf";
28    }
29
30    /**
31     * Set portfolio id
32     *
33     * @param int $a_val portfolio id
34     */
35    public function setPortfolioId($a_val)
36    {
37        $this->portfolio_id = $a_val;
38    }
39
40    /**
41     * Get portfolio id
42     *
43     * @return int portfolio id
44     */
45    public function getPortfolioId()
46    {
47        return $this->portfolio_id;
48    }
49
50    /**
51     * Set type
52     *
53     * @param int    type
54     */
55    public function setType($a_val)
56    {
57        $this->type = $a_val;
58    }
59
60    /**
61     * Get type
62     *
63     * @return    int    type
64     */
65    public function getType()
66    {
67        return $this->type;
68    }
69
70    /**
71     * Set Title
72     *
73     * @param string $a_title Title
74     */
75    public function setTitle($a_title)
76    {
77        $this->title = $a_title;
78    }
79
80    /**
81     * Get Title.
82     *
83     * @return    string    Title
84     */
85    public function getTitle()
86    {
87        $lng = $this->lng;
88
89        // because of migration of extended user profiles
90        if ($this->title == "###-") {
91            return $lng->txt("profile");
92        }
93
94        return $this->title;
95    }
96
97    /**
98     * Set order nr
99     *
100     * @param int    order nr
101     */
102    public function setOrderNr($a_val)
103    {
104        $this->order_nr = (int) $a_val;
105    }
106
107    /**
108     * Get order nr
109     *
110     * @return    int    order nr
111     */
112    public function getOrderNr()
113    {
114        return $this->order_nr;
115    }
116
117    /**
118     * Lookup max order nr for portfolio
119     *
120     * @param int $a_portfolio_id
121     * @return int
122     */
123    public static function lookupMaxOrderNr($a_portfolio_id)
124    {
125        global $DIC;
126
127        $ilDB = $DIC->database();
128
129        $set = $ilDB->query("SELECT MAX(order_nr) m FROM usr_portfolio_page" .
130            " WHERE portfolio_id = " . $ilDB->quote($a_portfolio_id, "integer"));
131        $rec = $ilDB->fetchAssoc($set);
132        return (int) $rec["m"];
133    }
134
135    /**
136     * Get properties for insert/update statements
137     *
138     * @return array
139     */
140    protected function getPropertiesForDB()
141    {
142        $fields = array(
143            "portfolio_id" => array("integer", $this->portfolio_id),
144            "type" => array("integer", $this->getType()),
145            "title" => array("text", $this->getTitle()),
146            "order_nr" => array("integer", $this->getOrderNr())
147        );
148
149        return $fields;
150    }
151
152    /**
153     * Create new portfolio page
154     */
155    public function create($a_import = false)
156    {
157        $ilDB = $this->db;
158
159        if (!$a_import) {
160            $this->setOrderNr(self::lookupMaxOrderNr($this->portfolio_id) + 10);
161        }
162
163        $id = $ilDB->nextId("usr_portfolio_page");
164        $this->setId($id);
165
166        $fields = $this->getPropertiesForDB();
167        $fields["id"] = array("integer", $id);
168
169        $ilDB->insert("usr_portfolio_page", $fields);
170
171        if (!$a_import) {
172            parent::create();
173            // $this->saveInternalLinks($this->getDomDoc());
174        }
175    }
176
177    /**
178     * Update page
179     *
180     * @return    boolean
181     */
182    public function update($a_validate = true, $a_no_history = false)
183    {
184        $ilDB = $this->db;
185
186        $id = $this->getId();
187        if ($id) {
188            $fields = $this->getPropertiesForDB();
189            $ilDB->update(
190                "usr_portfolio_page",
191                $fields,
192                array("id" => array("integer", $id))
193            );
194
195            parent::update($a_validate, $a_no_history);
196            return true;
197        }
198        return false;
199    }
200
201    /**
202     * Read page data
203     */
204    public function read()
205    {
206        $ilDB = $this->db;
207
208        $query = "SELECT * FROM usr_portfolio_page" .
209            " WHERE id = " . $ilDB->quote($this->getId(), "integer");
210        $set = $ilDB->query($query);
211        $rec = $ilDB->fetchAssoc($set);
212
213        $this->setPortfolioId($rec["portfolio_id"]);
214        $this->setType($rec["type"]);
215        $this->setTitle($rec["title"]);
216        $this->setOrderNr($rec["order_nr"]);
217
218        // get co page
219        parent::read();
220    }
221
222    /**
223     * delete portfolio page and all related data
224     */
225    public function delete()
226    {
227        $ilDB = $this->db;
228
229        $id = $this->getId();
230        if ($id) {
231            // delete internal links information to this page
232            ilInternalLink::_deleteAllLinksToTarget("user", $this->getId());
233
234            // delete record of table usr_portfolio_page
235            $query = "DELETE FROM usr_portfolio_page" .
236                " WHERE id = " . $ilDB->quote($this->getId(), "integer");
237            $ilDB->manipulate($query);
238
239            // delete co page
240            parent::delete();
241        }
242    }
243
244    /**
245     * Lookup portfolio page property
246     *
247     * @param int $a_id
248     * @param string $a_prop
249     * @return mixed
250     */
251    protected static function lookupProperty($a_id, $a_prop)
252    {
253        global $DIC;
254
255        $ilDB = $DIC->database();
256
257        $set = $ilDB->query("SELECT " . $a_prop .
258            " FROM usr_portfolio_page" .
259            " WHERE id = " . $ilDB->quote($a_id, "integer"));
260        $rec = $ilDB->fetchAssoc($set);
261        return $rec[$a_prop];
262    }
263
264    /**
265     * Lookup title
266     *
267     * @param $a_page_id
268     * @return mixed
269     */
270    public static function lookupTitle($a_page_id)
271    {
272        return self::lookupProperty($a_page_id, "title");
273    }
274
275    /**
276     * Lookup type
277     *
278     * @param $a_page_id
279     * @return mixed
280     */
281    public static function lookupType($a_page_id)
282    {
283        return self::lookupProperty($a_page_id, "type");
284    }
285
286    /**
287     * Get pages of portfolio
288     *
289     * @param int $a_portfolio_id
290     * @return array
291     */
292    public static function getAllPortfolioPages($a_portfolio_id)
293    {
294        global $DIC;
295
296        $ilDB = $DIC->database();
297        $lng = $DIC->language();
298
299        $set = $ilDB->query("SELECT * FROM usr_portfolio_page" .
300            " WHERE portfolio_id = " . $ilDB->quote($a_portfolio_id, "integer") .
301            " ORDER BY order_nr");
302        $pages = array();
303        while ($rec = $ilDB->fetchAssoc($set)) {
304            // because of migration of extended user profiles
305            if ($rec["title"] == "###-") {
306                $rec["title"] = $lng->txt("profile");
307            }
308
309            $pages[] = $rec;
310        }
311        return $pages;
312    }
313
314    /**
315     * Fix ordering
316     *
317     * @param int $a_portfolio_id
318     */
319    public static function fixOrdering($a_portfolio_id)
320    {
321        global $DIC;
322
323        $ilDB = $DIC->database();
324
325        $pages = self::getAllPortfolioPages($a_portfolio_id);
326        $cnt = 10;
327        foreach ($pages as $p) {
328            $ilDB->manipulate(
329                "UPDATE usr_portfolio_page SET " .
330                " order_nr = " . $ilDB->quote($cnt, "integer") .
331                " WHERE id = " . $ilDB->quote($p["id"], "integer")
332            );
333            $cnt += 10;
334        }
335    }
336
337    /**
338     * Get portfolio id of page id
339     *
340     * @param int $a_page_id
341     * @return int
342     */
343    public static function findPortfolioForPage($a_page_id)
344    {
345        return self::lookupProperty($a_page_id, "portfolio_id");
346    }
347
348    /**
349     * Get goto href for internal wiki page link target
350     *
351     * @param
352     * @return string
353     */
354    public static function getGotoForPortfolioPageTarget($a_target, $a_offline = false)
355    {
356        global $DIC;
357
358        $pid = self::findPortfolioForPage((int) $a_target);
359        $type = ilObject::_lookupType($pid);
360        if ($type == "prtt") {
361            $ctrl = $DIC->ctrl();
362            $ctrl->setParameterByClass("ilobjportfoliotemplategui", "user_page", $a_target);
363            $href = $ctrl->getLinkTargetByClass(array(
364                "ilRepositoryGUI",
365                "ilObjPortfolioTemplateGUI",
366                "ilobjportfoliotemplategui"
367            ), "preview", "", false, true);
368        } else {
369            if (!$a_offline) {
370                $href = "./goto.php?client_id=" . CLIENT_ID . "&amp;target=prtf_" . $pid . "_" . $a_target;
371            } else {
372                $href = "prtf_" . $a_target . ".html";
373            }
374        }
375        return $href;
376    }
377
378    /**
379     * Update internal links, after multiple pages have been copied
380     */
381    public static function updateInternalLinks($a_copied_nodes, ilObjPortfolioBase $a_target_obj)
382    {
383        //		var_dump($a_copied_nodes);
384        $all_fixes = array();
385        foreach ($a_copied_nodes as $original_id => $copied_id) {
386            $pid = self::findPortfolioForPage((int) $copied_id);
387
388            //
389            // 1. Outgoing links from the copied page.
390            //
391            //$targets = ilInternalLink::_getTargetsOfSource($a_parent_type.":pg", $copied_id);
392            if ($a_target_obj->getType() == "prtf") {
393                $tpg = new ilPortfolioPage($copied_id);
394            }
395            if ($a_target_obj->getType() == "prtt") {
396                $tpg = new ilPortfolioTemplatePage($copied_id);
397            }
398            $tpg->buildDom();
399            $il = $tpg->getInternalLinks();
400            //			var_dump($il);
401            $targets = array();
402            foreach ($il as $l) {
403                $targets[] = array(
404                    "type" => ilInternalLink::_extractTypeOfTarget($l["Target"]),
405                    "id" => (int) ilInternalLink::_extractObjIdOfTarget($l["Target"]),
406                    "inst" => (int) ilInternalLink::_extractInstOfTarget($l["Target"])
407                );
408            }
409            $fix = array();
410            foreach ($targets as $target) {
411                if (($target["inst"] == 0 || $target["inst"] = IL_INST_ID) &&
412                    ($target["type"] == "ppage")) {
413                    // first check, whether target is also within the copied set
414                    if ($a_copied_nodes[$target["id"]] > 0) {
415                        $fix[$target["id"]] = $a_copied_nodes[$target["id"]];
416                    }
417                }
418            }
419            //			var_dump($fix);
420            // outgoing links to be fixed
421            if (count($fix) > 0) {
422                $t = ilObject::_lookupType($pid);
423                if (is_array($all_fixes[$t . ":" . $copied_id])) {
424                    $all_fixes[$t . ":" . $copied_id] += $fix;
425                } else {
426                    $all_fixes[$t . ":" . $copied_id] = $fix;
427                }
428            }
429        }
430        //		var_dump($all_fixes);
431        foreach ($all_fixes as $pg => $fixes) {
432            $pg = explode(":", $pg);
433            $page = ilPageObjectFactory::getInstance($pg[0], $pg[1]);
434            if ($page->moveIntLinks($fixes)) {
435                $page->update(true, true);
436            }
437        }
438    }
439
440
441    /**
442     * @param $a_title_changes
443     */
444    public function renameLinksOnTitleChange($a_title_changes)
445    {
446        $this->buildDom();
447
448        $changed = false;
449
450        // resolve normal internal links
451        $xpc = xpath_new_context($this->dom);
452        $path = "//IntLink";
453        $res = xpath_eval($xpc, $path);
454        for ($i = 0; $i < count($res->nodeset); $i++) {
455            $target = $res->nodeset[$i]->get_attribute("Target");
456            $type = $res->nodeset[$i]->get_attribute("Type");
457            $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
458            if (isset($a_title_changes[$obj_id]) && is_int(strpos($target, "__"))) {
459                if ($type == "PortfolioPage") {
460                    if ($res->nodeset[$i]->get_content() == $a_title_changes[$obj_id]["old"]) {
461                        $res->nodeset[$i]->set_content($a_title_changes[$obj_id]["new"]);
462                        $changed = true;
463                    }
464                }
465            }
466        }
467        unset($xpc);
468
469        return $changed;
470    }
471
472    /**
473     * Get portfolio pages for blog
474     *
475     * @param int $a_blog_id
476     * @return ilPortfolioPage[]
477     */
478    public static function getPagesForBlog($a_blog_id)
479    {
480        global $DIC;
481
482        $ilDB = $DIC->database();
483
484        $set = $ilDB->query("SELECT * FROM usr_portfolio_page" .
485            " WHERE title = " . $ilDB->quote($a_blog_id, "text") .
486            " AND type = " . $ilDB->quote(self::TYPE_BLOG, "integer"));
487        $pages = array();
488        while ($rec = $ilDB->fetchAssoc($set)) {
489            $pages[] = new ilPortfolioPage($rec["id"]);
490        }
491        return $pages;
492    }
493}
494