ILIAS  release_8 Revision v8.24
class.ilObjPortfolioBase.php
Go to the documentation of this file.
1<?php
2
24abstract class ilObjPortfolioBase extends ilObject2
25{
26 protected \ILIAS\Notes\Service $notes;
28 protected bool $online = false;
29 protected bool $comments = false;
30 protected string $bg_color = "";
31 protected string $font_color = "";
32 protected string $img = "";
33 protected string $ppic = "";
34 protected bool $style = false;
35
36 public function __construct(
37 int $a_id = 0,
38 bool $a_reference = true
39 ) {
40 global $DIC;
41
42 $this->notes = $DIC->notes();
43
44 parent::__construct($a_id, $a_reference);
45
46 $this->setting = $DIC->settings();
47
48 $this->db = $DIC->database();
49 }
50
51
52 //
53 // PROPERTIES
54 //
55
56 public function setOnline(bool $a_value): void
57 {
58 $this->online = $a_value;
59 }
60
61 public function isOnline(): bool
62 {
63 return $this->online;
64 }
65
66 public static function lookupOnline(int $a_id): bool
67 {
68 global $DIC;
69
70 $ilDB = $DIC->database();
71
72 $set = $ilDB->query("SELECT is_online" .
73 " FROM usr_portfolio" .
74 " WHERE id = " . $ilDB->quote($a_id, "integer"));
75 $row = $ilDB->fetchAssoc($set);
76 return (bool) $row["is_online"];
77 }
78
79 public function setPublicComments(bool $a_value): void
80 {
81 $this->comments = $a_value;
82 }
83
84 public function hasPublicComments(): bool
85 {
86 return $this->comments;
87 }
88
89 public function hasProfilePicture(): bool
90 {
91 return $this->ppic;
92 }
93
94 public function setProfilePicture(bool $a_status): void
95 {
96 $this->ppic = $a_status;
97 }
98
99 public function getBackgroundColor(): string
100 {
101 if (!$this->bg_color) {
102 $this->bg_color = "ffffff";
103 }
104 return $this->bg_color;
105 }
106
110 public function setBackgroundColor(string $a_value): void
111 {
112 $this->bg_color = $a_value;
113 }
114
115 public function getFontColor(): string
116 {
117 if (!$this->font_color) {
118 $this->font_color = "505050";
119 }
120 return $this->font_color;
121 }
122
123 public function setFontColor(string $a_value): void
124 {
125 $this->font_color = $a_value;
126 }
127
131 public function getImage(): string
132 {
133 return $this->img;
134 }
135
139 public function setImage(string $a_value): void
140 {
141 $this->img = $a_value;
142 }
143
144 //
145 // CRUD
146 //
147
148 protected function doRead(): void
149 {
151
152 $set = $ilDB->query("SELECT * FROM usr_portfolio" .
153 " WHERE id = " . $ilDB->quote($this->id, "integer"));
154 $row = $ilDB->fetchAssoc($set);
155
156 $this->setOnline((bool) $row["is_online"]);
157 $this->setProfilePicture((bool) $row["ppic"]);
158 $this->setBackgroundColor((string) $row["bg_color"]);
159 $this->setFontColor((string) $row["font_color"]);
160 $this->setImage((string) $row["img"]);
161
162 // #14661
163 $this->setPublicComments($this->notes->domain()->commentsActive($this->id));
164
165 $this->doReadCustom($row);
166 }
167
171 protected function doReadCustom(array $a_row): void
172 {
173 }
174
175 protected function doCreate(bool $clone_mode = false): void
176 {
178
179 $ilDB->manipulate("INSERT INTO usr_portfolio (id,is_online)" .
180 " VALUES (" . $ilDB->quote($this->id, "integer") . "," .
181 $ilDB->quote(0, "integer") . ")");
182 }
183
184 protected function doUpdate(): void
185 {
187
188 $fields = array(
189 "is_online" => array("integer", $this->isOnline()),
190 "ppic" => array("integer", $this->hasProfilePicture()),
191 "bg_color" => array("text", $this->getBackgroundColor()),
192 "font_color" => array("text", $this->getFontColor()),
193 "img" => array("text", $this->getImage())
194 );
195 $this->doUpdateCustom($fields);
196
197 // #14661
198 $this->notes->domain()->activateComments($this->id, $this->hasPublicComments());
199
200 $ilDB->update(
201 "usr_portfolio",
202 $fields,
203 array("id" => array("integer", $this->id))
204 );
205 }
206
210 protected function doUpdateCustom(array &$a_fields): void
211 {
212 }
213
214 protected function doDelete(): void
215 {
217
218 $this->deleteAllPages();
219 $this->deleteImage();
220
221 $ilDB->manipulate("DELETE FROM usr_portfolio" .
222 " WHERE id = " . $ilDB->quote($this->id, "integer"));
223 }
224
225 abstract protected function deleteAllPages(): void;
226
227
228 //
229 // IMAGES
230 //
231
235 public function getImageFullPath(
236 bool $a_as_thumb = false
237 ): string {
238 if ($this->img) {
239 $path = self::initStorage($this->id);
240 if (!$a_as_thumb) {
241 return $path . $this->img;
242 }
243
244 return $path . "thb_" . $this->img;
245 }
246 return "";
247 }
248
252 public function deleteImage(): void
253 {
254 if ($this->id) {
255 $storage = new ilFSStoragePortfolio($this->id);
256 $storage->delete();
257
258 $this->setImage("");
259 }
260 }
261
265 public static function initStorage(
266 int $a_id,
267 string $a_subdir = null
268 ): string {
269 $storage = new ilFSStoragePortfolio($a_id);
270 $storage->create();
271
272 $path = $storage->getAbsolutePath() . "/";
273
274 if ($a_subdir) {
275 $path .= $a_subdir . "/";
276
277 if (!is_dir($path) && !mkdir($path) && !is_dir($path)) {
278 throw new \RuntimeException(sprintf('Directory "%s" was not created', $path));
279 }
280 }
281
282 return $path;
283 }
284
288 public function uploadImage(
289 array $a_upload
290 ): bool {
291 if (!$this->id) {
292 return false;
293 }
294
295 $this->deleteImage();
296
297 // #10074
298 $clean_name = preg_replace("/[^a-zA-Z0-9\_\.\-]/", "", $a_upload["name"]);
299
300 $path = self::initStorage($this->id);
301 $original = "org_" . $this->id . "_" . $clean_name;
302 $thumb = "thb_" . $this->id . "_" . $clean_name;
303 $processed = $this->id . "_" . $clean_name;
304
305 if (ilFileUtils::moveUploadedFile($a_upload["tmp_name"], $original, $path . $original)) {
306 chmod($path . $original, 0770);
307
308 $prfa_set = new ilSetting("prfa");
309 /* as banner height should overflow, we only handle width
310 $dimensions = $prfa_set->get("banner_width")."x".
311 $prfa_set->get("banner_height");
312 */
313 $dimensions = $prfa_set->get("banner_width");
314
315 // take quality 100 to avoid jpeg artefacts when uploading jpeg files
316 // taking only frame [0] to avoid problems with animated gifs
317 $original_file = ilShellUtil::escapeShellArg($path . $original);
318 $thumb_file = ilShellUtil::escapeShellArg($path . $thumb);
319 $processed_file = ilShellUtil::escapeShellArg($path . $processed);
320 ilShellUtil::execConvert($original_file . "[0] -geometry 100x100 -quality 100 JPEG:" . $thumb_file);
322 $original_file . "[0] -geometry " . $dimensions . " -quality 100 JPEG:" . $processed_file
323 );
324
325 $this->setImage($processed);
326
327 return true;
328 }
329 return false;
330 }
331
332
333 //
334 // TRANSMOGRIFIER
335 //
336
343 protected static function cloneBasics(
344 ilObjPortfolioBase $a_source,
345 ilObjPortfolioBase $a_target
346 ): void {
347 global $DIC;
348
349 // copy portfolio properties
350 $a_target->setPublicComments($a_source->hasPublicComments());
351 $a_target->setProfilePicture($a_source->hasProfilePicture());
352 $a_target->setFontColor($a_source->getFontColor());
353 $a_target->setBackgroundColor($a_source->getBackgroundColor());
354 $a_target->setImage($a_source->getImage());
355 $a_target->update();
356
357 // banner/images
358 $source_dir = $a_source->initStorage($a_source->getId());
359 $target_dir = $a_target->initStorage($a_target->getId());
360 ilFSStoragePortfolio::_copyDirectory($source_dir, $target_dir);
361
362 // container settings
363 foreach (ilContainer::_getContainerSettings($a_source->getId()) as $keyword => $value) {
364 ilContainer::_writeContainerSetting($a_target->getId(), $keyword, $value);
365 }
366
367 // style
368 $content_style_domain = $DIC
369 ->contentStyle()
370 ->domain()
371 ->styleForObjId($a_source->getId());
372 $content_style_domain->cloneTo($a_target->getId());
373 }
374
378 public static function clonePagesAndSettings(
379 ilObjPortfolioBase $a_source,
380 ilObjPortfolioBase $a_target,
381 ?array $a_recipe = null,
382 bool $copy_all = false
383 ): void {
384 global $DIC;
385
386 $lng = $DIC->language();
387 $ilUser = $DIC->user();
388
389 $source_id = $a_source->getId();
390 $target_id = $a_target->getId();
391
392 if ($a_source instanceof ilObjPortfolioTemplate &&
393 $a_target instanceof ilObjPortfolio) {
394 $direction = "t2p";
395 } elseif ($a_source instanceof ilObjPortfolio &&
396 $a_target instanceof ilObjPortfolioTemplate) {
397 $direction = "p2t";
398 } else {
399 return;
400 }
401
402 self::cloneBasics($a_source, $a_target);
403
404 // copy advanced metadata
406 ilAdvancedMDValues::_cloneValues($copy_id, $a_source->getId(), $a_target->getId());
407
408 // copy selection of global optional sets
410 $a_target->getId(),
411 'pfpg',
413 );
414
415 // fix metadata record type assignment
416 // e.g. if portfolio is created from template
417 // we need to change this from prtt to prtf
419 ilObject::_lookupType($a_source->getId()),
420 $a_target->getId(),
421 "pfpg",
422 false
423 ) as $rec) {
424 /*
425 * BT 35494: reset assignement of the newly cloned local records,
426 * and only append what's needed to global ones
427 */
429 if ($rec->getParentObject() == $a_target->getId()) {
430 $rec->setAssignedObjectTypes(
431 [[
432 "obj_type" => $target_type,
433 "sub_type" => "pfpg",
434 "optional" => 0
435 ]
436 ]
437 );
438 } elseif (!$rec->isAssignedObjectType($target_type, 'pfpg')) {
439 $rec->appendAssignedObjectType(
441 "pfpg"
442 );
443 }
444 $rec->update();
445 }
446
447 // personal skills
448 $pskills = array_keys(ilPersonalSkill::getSelectedUserSkills($ilUser->getId()));
449
450 // copy pages
451 $blog_count = 0;
452 $page_map = array();
453 foreach (ilPortfolioPage::getAllPortfolioPages($source_id) as $page) {
454 $page_id = $page["id"];
455
456 if ($direction === "t2p") {
457 $source_page = new ilPortfolioTemplatePage($page_id);
458 $target_page = new ilPortfolioPage();
459 } else {
460 $source_page = new ilPortfolioPage($page_id);
461 $target_page = new ilPortfolioTemplatePage();
462 }
463 $source_page->setPortfolioId($source_id);
464 $target_page->setPortfolioId($target_id);
465
466 $page_type = $source_page->getType();
467 $page_title = $source_page->getTitle();
468
469
470
471
472 $page_recipe = null;
473 if (isset($a_recipe)) {
474 $page_recipe = $a_recipe[$page_id] ?? null;
475 }
476
477 $valid = false;
478 switch ($page_type) {
479 // blog => blog template
481 if ($direction === "p2t") {
483 $page_title = $lng->txt("obj_blog") . " " . (++$blog_count);
484 $valid = true;
485 }
486 break;
487
488 // blog template => blog (needs recipe)
490 if ($direction === "t2p" && (is_array($page_recipe) || $copy_all)) {
491 $page_type = ilPortfolioPage::TYPE_BLOG;
492 if ($copy_all) {
493 $page_title = self::createBlogInPersonalWorkspace($page_title);
494 $valid = true;
495 } elseif ($page_recipe[0] == "blog") {
496 switch ($page_recipe[1]) {
497 case "create":
498 $page_title = self::createBlogInPersonalWorkspace($page_recipe[2]);
499 $valid = true;
500 break;
501
502 case "reuse":
503 $page_title = $page_recipe[2];
504 $valid = true;
505 break;
506
507 case "ignore":
508 // do nothing
509 break;
510 }
511 }
512 }
513 break;
514
515 // page editor
516 default:
517 $target_page->setXMLContent(
518 $source_page->copyXmlContent(
519 true,
520 $a_target->getId(),
521 $copy_id
522 )
523 );
524 $target_page->buildDom(true);
525
526 // parse content / blocks
527
528 if ($direction === "t2p") {
529 $dom = $target_page->getDom();
530 if ($dom instanceof php4DOMDocument) {
531 $dom = $dom->myDOMDocument;
532 }
533
534 // update profile/consultation hours user id
535 self::updateDomNodes($dom, "//PageContent/Profile", "User", $ilUser->getId());
536 self::updateDomNodes($dom, "//PageContent/ConsultationHours", "User", $ilUser->getId());
537 self::updateDomNodes($dom, "//PageContent/MyCourses", "User", $ilUser->getId());
538
539 // skills
540 $xpath = new DOMXPath($dom);
541 $nodes = $xpath->query("//PageContent/Skills");
542 foreach ($nodes as $node) {
543 $skill_id = $node->getAttribute("Id");
544
545 // existing personal skills
546 if (in_array($skill_id, $pskills)) {
547 $node->setAttribute("User", $ilUser->getId());
548 }
549 // new skill
550 elseif ($copy_all || in_array($skill_id, $a_recipe["skills"])) {
551 ilPersonalSkill::addPersonalSkill($ilUser->getId(), $skill_id);
552
553 $node->setAttribute("User", $ilUser->getId());
554 }
555 // remove skill
556 else {
557 $page_element = $node->parentNode;
558 $page_element->parentNode->removeChild($page_element);
559 }
560 }
561 }
562
563 $valid = true;
564 break;
565 }
566
567 if ($valid) {
568 // #12038 - update xml from dom
569 $target_page->setXMLContent($target_page->getXMLFromDom());
570
571 $target_page->setType($page_type);
572 $target_page->setTitle($page_title);
573 $target_page->create(false);
574
575 if ($page_type === ilPortfolioPage::TYPE_PAGE) {
576 $target_page->update(); // handle mob usages!
577 }
578 $page_map[$source_page->getId()] = $target_page->getId();
579 }
580 }
581 ilPortfolioPage::updateInternalLinks($page_map, $a_target);
582 }
583
584 protected static function updateDomNodes(
585 DOMDocument $a_dom,
586 string $a_xpath,
587 string $a_attr_id,
588 string $a_attr_value
589 ): void {
590 $xpath_temp = new DOMXPath($a_dom);
591 $nodes = $xpath_temp->query($a_xpath);
592 foreach ($nodes as $node) {
593 $node->setAttribute($a_attr_id, $a_attr_value);
594 }
595 }
596
597 protected static function createBlogInPersonalWorkspace(string $a_title): int
598 {
599 global $DIC;
600
601 $ilUser = $DIC->user();
602
603 static $ws_access = null;
604
605 $blog = new ilObjBlog();
606 $blog->setType("blog");
607 $blog->setTitle($a_title);
608 $blog->create();
609
610 if (!$ws_access) {
611 $tree = new ilWorkspaceTree($ilUser->getId());
612
613 // #13235
614 if (!$tree->getRootId()) {
615 $tree->createTreeForUser($ilUser->getId());
616 }
617
618 $ws_access = new ilWorkspaceAccessHandler($tree);
619 }
620
621 $tree = $ws_access->getTree();
622 $node_id = $tree->insertObject($tree->getRootId(), $blog->getId());
623 $ws_access->setPermissions($tree->getRootId(), $node_id);
624
625 return $blog->getId();
626 }
627
631 public function fixLinksOnTitleChange(array $a_title_changes): void
632 {
633 foreach (ilPortfolioPage::getAllPortfolioPages($this->getId()) as $port_page) {
634 if ($this->getType() === "prtt") {
635 $page = new ilPortfolioTemplatePage($port_page["id"]);
636 } else {
637 $page = new ilPortfolioPage($port_page["id"]);
638 }
639 if ($page->renameLinksOnTitleChange($a_title_changes)) {
640 $page->update(true, true);
641 }
642 }
643 }
644}
static getObjRecSelection(int $a_obj_id, string $a_sub_type="")
Get repository object record selection.
static _getSelectedRecordsByObject(string $a_obj_type, int $a_id, string $a_sub_type="", bool $is_ref_id=true)
static saveObjRecSelection(int $a_obj_id, string $a_sub_type="", array $a_records=null, bool $a_delete_before=true)
Save repository object record selection.
static _cloneValues(int $copy_id, int $a_source_id, int $a_target_id, ?string $a_sub_type=null, ?int $a_source_sub_id=null, ?int $a_target_sub_id=null)
Clone Advanced Meta Data.
static _writeContainerSetting(int $a_id, string $a_keyword, string $a_value)
static _getContainerSettings(int $a_id)
static _allocateCopyId()
Allocate a copy for further entries.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _copyDirectory(string $a_sdir, string $a_tdir)
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static clonePagesAndSettings(ilObjPortfolioBase $a_source, ilObjPortfolioBase $a_target, ?array $a_recipe=null, bool $copy_all=false)
Build template from portfolio and vice versa.
deleteImage()
remove existing file
doUpdateCustom(array &$a_fields)
May be overwritte by derived classes.
fixLinksOnTitleChange(array $a_title_changes)
Update internal portfolio links on title change.
setProfilePicture(bool $a_status)
static cloneBasics(ilObjPortfolioBase $a_source, ilObjPortfolioBase $a_target)
Clone basic settings.
uploadImage(array $a_upload)
Upload new image file.
ILIAS Notes Service $notes
setImage(string $a_value)
Set banner image.
getImageFullPath(bool $a_as_thumb=false)
Get banner image incl.
static updateDomNodes(DOMDocument $a_dom, string $a_xpath, string $a_attr_id, string $a_attr_value)
static initStorage(int $a_id, string $a_subdir=null)
Init file system storage.
setBackgroundColor(string $a_value)
Set background color, e.g.
static createBlogInPersonalWorkspace(string $a_title)
static lookupOnline(int $a_id)
doReadCustom(array $a_row)
May be overwritten by derived classes.
doCreate(bool $clone_mode=false)
__construct(int $a_id=0, bool $a_reference=true)
Constructor.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupType(int $id, bool $reference=false)
ilDBInterface $db
static addPersonalSkill(int $a_user_id, int $a_skill_node_id)
static getSelectedUserSkills(int $a_user_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getAllPortfolioPages(int $a_portfolio_id)
Get pages of portfolio.
static updateInternalLinks(array $a_copied_nodes, ilObjPortfolioBase $a_target_obj)
Update internal links, after multiple pages have been copied.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static escapeShellArg(string $a_arg)
static execConvert(string $args)
execute convert command
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
$valid
global $DIC
Definition: feed.php:28
$target_id
Definition: goto.php:52
$target_type
Definition: goto.php:51
$ilUser
Definition: imgupload.php:34
$path
Definition: ltiservices.php:32
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$lng