1<?php
2require_once('./Services/WebAccessChecker/interfaces/interface.ilWACCheckingClass.php');
3require_once('./Services/MediaObjects/classes/class.ilObjMediaObject.php');
4
5/**
6 * Class ilObjMediaObjectAccess
7 *
8 * @author  Fabian Schmid <fs@studer-raimann.ch>
9 * @version 1.0.0
10 */
11class ilObjMediaObjectAccess implements ilWACCheckingClass
12{
13    /**
14     * @var ilObjectDataCache
15     */
16    protected $obj_data_cache;
17
18    /**
19     * @var ilObjUser
20     */
21    protected $user;
22
23    /**
24     * @var ilAccessHandler
25     */
26    protected $access;
27
28
29    /**
30     * Constructor
31     */
32    public function __construct()
33    {
34        global $DIC;
35
36        $this->obj_data_cache = $DIC["ilObjDataCache"];
37        $this->user = $DIC->user();
38        $this->access = $DIC->access();
39    }
40
41
42    /**
43     * @param ilWACPath $ilWACPath
44     *
45     * @return bool
46     */
47    public function canBeDelivered(ilWACPath $ilWACPath)
48    {
49        preg_match("/.\\/data\\/.*\\/mm_([0-9]*)\\/.*/ui", $ilWACPath->getPath(), $matches);
50        $obj_id = $matches[1];
51
52        return $this->checkAccessMob($obj_id);
53    }
54
55
56    /**
57     * @param $obj_id
58     *
59     * @return bool
60     */
61    protected function checkAccessMob($obj_id)
62    {
63        foreach (ilObjMediaObject::lookupUsages($obj_id) as $usage) {
64            $oid = ilObjMediaObject::getParentObjectIdForUsage($usage, true);
65
66            // for content snippets we must get their usages and check them
67            switch ($usage["type"]) {
68                case "auth:pg":
69                    // Mobs on the Loginpage should always be delivered
70                    return true;
71                case "mep:pg":
72                    include_once("./Modules/MediaPool/classes/class.ilMediaPoolPage.php");
73                    $usages2 = ilMediaPoolPage::lookupUsages($usage["id"]);
74                    foreach ($usages2 as $usage2) {
75                        $oid2 = ilObjMediaObject::getParentObjectIdForUsage($usage2, true);
76                        if ($this->checkAccessMobUsage($usage2, $oid2)) {
77                            return true;
78                        }
79                    }
80                    break;
81
82                case "clip":
83                    if ($usage["id"] == $this->user->getId()) {
84                        return true;
85                    }
86                    break;
87
88                default:
89                    if ($this->checkAccessMobUsage($usage, $oid)) {
90                        return true;
91                    }
92                    break;
93            }
94        }
95
96        return false;
97    }
98
99
100    /**
101     * @param $usage
102     * @param $oid
103     *
104     * @return bool
105     */
106    protected function checkAccessMobUsage($usage, $oid)
107    {
108        /**
109         * @var $ilObjDataCache ilObjectDataCache
110         */
111        $ilObjDataCache = $this->obj_data_cache;
112        $ilUser = $this->user;
113        $user_id = $ilUser->getId();
114
115        switch ($usage['type']) {
116            case 'lm:pg':
117                if ($this->checkAccessObject($oid, 'lm')) {
118                    return true;
119                }
120                break;
121
122            case 'news':
123                // media objects in news (media casts)
124                include_once("./Modules/MediaCast/classes/class.ilObjMediaCastAccess.php");
125                include_once("./Services/News/classes/class.ilNewsItem.php");
126                if ($this->checkAccessObject($oid)) {
127                    return true;
128                } elseif (ilObjMediaCastAccess::_lookupPublicFiles($oid) && ilNewsItem::_lookupVisibility($usage["id"]) == NEWS_PUBLIC) {
129                    return true;
130                }
131                break;
132
133            case 'frm~:html':
134            case 'exca~:html':
135                // $oid = userid
136                //				foreach ($this->check_users as $user_id) {
137                if ($ilObjDataCache->lookupType($oid) == 'usr' && $oid == $user_id) {
138                    return true;
139                }
140                //				}
141                break;
142
143            case 'frm~d:html':
144                $draft_id = $usage['id'];
145
146                include_once 'Modules/Forum/classes/class.ilForumPostDraft.php';
147                $oDraft = ilForumPostDraft::newInstanceByDraftId($draft_id);
148                if ($user_id == $oDraft->getPostAuthorId()) {
149                    return true;
150                }
151                break;
152            case 'frm~h:html':
153                $history_id = $usage['id'];
154                include_once 'Modules/Forum/classes/class.ilForumDraftsHistory.php';
155                include_once 'Modules/Forum/classes/class.ilForumPostDraft.php';
156
157                $oHistoryDraft = new ilForumDraftsHistory($history_id);
158                $oDraft = ilForumPostDraft::newInstanceByDraftId($oHistoryDraft->getDraftId());
159                if ($user_id == $oDraft->getPostAuthorId()) {
160                    return true;
161                }
162                break;
163            case 'qpl:pg':
164            case 'qpl:html':
165                // test questions
166                if ($this->checkAccessTestQuestion($oid, $usage['id'])) {
167                    return true;
168                }
169                break;
170
171            case 'gdf:pg':
172                // special check for glossary terms
173                if ($this->checkAccessGlossaryTerm($oid, $usage['id'])) {
174                    return true;
175                }
176                break;
177
178            case 'sahs:pg':
179                // check for scorm pages
180                if ($this->checkAccessObject($oid, 'sahs')) {
181                    return true;
182                }
183                break;
184
185            case 'prtf:pg':
186                // special check for portfolio pages
187                if ($this->checkAccessPortfolioPage($oid, $usage['id'])) {
188                    return true;
189                }
190                break;
191
192            case 'blp:pg':
193                // special check for blog pages
194                if ($this->checkAccessBlogPage($oid, $usage['id'])) {
195                    return true;
196                }
197                break;
198
199            case 'lobj:pg':
200                // special check for learning objective pages
201                if ($this->checkAccessLearningObjectivePage($oid, $usage['id'])) {
202                    return true;
203                }
204                break;
205
206            case 'impr:pg':
207                include_once 'Services/Imprint/classes/class.ilImprint.php';
208
209                return (ilImprint::isActive() || $this->checkAccessObject(SYSTEM_FOLDER_ID, 'adm'));
210
211            case 'cstr:pg':
212            default:
213                // standard object check
214                if ($this->checkAccessObject($oid)) {
215                    return true;
216                }
217                break;
218        }
219
220        return false;
221    }
222
223
224    /**
225     * Check access rights for an object by its object id
226     *
227     * @param    int        object id
228     *
229     * @return   boolean     access given (true/false)
230     */
231    protected function checkAccessObject($obj_id, $obj_type = '')
232    {
233        $ilAccess = $this->access;
234        $ilUser = $this->user;
235        $user_id = $ilUser->getId();
236
237        if (!$obj_type) {
238            $obj_type = ilObject::_lookupType($obj_id);
239        }
240        $ref_ids = ilObject::_getAllReferences($obj_id);
241
242        foreach ($ref_ids as $ref_id) {
243            //			foreach ($this->check_users as $user_id) {
244            if ($ilAccess->checkAccessOfUser($user_id, "read", "view", $ref_id, $obj_type, $obj_id)) {
245                return true;
246            }
247            //			}
248        }
249
250        return false;
251    }
252
253
254    /**
255     * Check access rights for a test question
256     * This checks also tests with random selection of questions
257     *
258     * @param    int         object id (question pool or test)
259     * @param    int         usage id (not yet used)
260     *
261     * @return   boolean     access given (true/false)
262     */
263    protected function checkAccessTestQuestion($obj_id, $usage_id = 0)
264    {
265        $ilAccess = $this->access;
266
267        // give access if direct usage is readable
268        if ($this->checkAccessObject($obj_id)) {
269            return true;
270        }
271
272        $obj_type = ilObject::_lookupType($obj_id);
273        if ($obj_type == 'qpl') {
274            // give access if question pool is used by readable test
275            // for random selection of questions
276            include_once('./Modules/Test/classes/class.ilObjTestAccess.php');
277            $tests = ilObjTestAccess::_getRandomTestsForQuestionPool($obj_id);
278            foreach ($tests as $test_id) {
279                if ($this->checkAccessObject($test_id, 'tst')) {
280                    return true;
281                }
282            }
283        }
284
285        return false;
286    }
287
288
289    /**
290     * Check access rights for glossary terms
291     * This checks also learning modules linking the term
292     *
293     * @param    int         object id (glossary)
294     * @param    int         page id (definition)
295     *
296     * @return   boolean     access given (true/false)
297     */
298    protected function checkAccessGlossaryTerm($obj_id, $page_id)
299    {
300        // give access if glossary is readable
301        if ($this->checkAccessObject($obj_id)) {
302            return true;
303        }
304
305        $term_id = ilGlossaryDefinition::_lookupTermId($page_id);
306
307        include_once('./Services/Link/classes/class.ilInternalLink.php');
308        $sources = ilInternalLink::_getSourcesOfTarget('git', $term_id, 0);
309
310        if ($sources) {
311            foreach ($sources as $src) {
312                switch ($src['type']) {
313                    // Give access if term is linked by a learning module with read access.
314                    // The term including media is shown by the learning module presentation!
315                    case 'lm:pg':
316                        include_once("./Modules/LearningModule/classes/class.ilLMObject.php");
317                        $src_obj_id = ilLMObject::_lookupContObjID($src['id']);
318                        if ($this->checkAccessObject($src_obj_id, 'lm')) {
319                            return true;
320                        }
321                        break;
322
323                    // Don't yet give access if the term is linked by another glossary
324                    // The link will lead to the origin glossary which is already checked
325                    /*
326                    case 'gdf:pg':
327                        $src_term_id = ilGlossaryDefinition::_lookupTermId($src['id']);
328                        $src_obj_id = ilGlossaryTerm::_lookGlossaryID($src_term_id);
329                        if ($this->checkAccessObject($src_obj_id, 'glo'))
330                        {
331                            return true;
332                        }
333                        break;
334                    */
335                }
336            }
337        }
338    }
339
340
341    /**
342     * Check access rights for portfolio pages
343     *
344     * @param    int         object id (glossary)
345     * @param    int         page id (definition)
346     *
347     * @return   boolean     access given (true/false)
348     */
349    protected function checkAccessPortfolioPage($obj_id, $page_id)
350    {
351        $ilUser = $this->user;
352        include_once "Modules/Portfolio/classes/class.ilPortfolioAccessHandler.php";
353        $access_handler = new ilPortfolioAccessHandler();
354        if ($access_handler->checkAccessOfUser($ilUser->getId(), "read", "view", $obj_id, "prtf")) {
355            return true;
356        }
357
358        return false;
359    }
360
361
362    /**
363     * Check access rights for blog pages
364     *
365     * @param    int         object id (glossary)
366     * @param    int         page id (definition)
367     *
368     * @return   boolean     access given (true/false)
369     */
370    protected function checkAccessBlogPage($obj_id)
371    {
372        $ilUser = $this->user;
373        include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceTree.php";
374        $tree = new ilWorkspaceTree(0);
375        $node_id = $tree->lookupNodeId($obj_id);
376        if (!$node_id) {
377            return $this->checkAccessObject($obj_id);
378        } else {
379            include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php";
380
381            $access_handler = new ilWorkspaceAccessHandler($tree);
382            if ($access_handler->checkAccessOfUser($tree, $ilUser->getId(), "read", "view", $node_id, "blog")) {
383                return true;
384            }
385        }
386
387        return false;
388    }
389
390
391    /**
392     * @param $obj_id
393     * @param $page_id
394     *
395     * @return bool
396     */
397    protected function checkAccessLearningObjectivePage($obj_id, $page_id)
398    {
399        include_once "Modules/Course/classes/class.ilCourseObjective.php";
400        $crs_obj_id = ilCourseObjective::_lookupContainerIdByObjectiveId($page_id);
401
402        return $this->checkAccessObject($crs_obj_id, 'crs');
403    }
404}
405