1<?php
2/* Copyright (c) 1998-2018 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4/**
5 * @author  Niels Theen <ntheen@databay.de>
6 */
7class ilCertificateSettingsCourseFormRepository implements ilCertificateFormRepository
8{
9    /**
10     * @var ilLanguage
11     */
12    private $language;
13
14    /**
15     * @var ilCertificateSettingsFormRepository
16     */
17    private $settingsFromFactory;
18
19    /**
20     * @var \ilObjCourse
21     */
22    private $object;
23
24    /**
25     * @var ilObjectLP|mixed
26     */
27    private $learningProgressObject;
28
29    /**
30     * @var ilCertificateObjUserTrackingHelper|null
31     */
32    private $trackingHelper;
33
34    /**
35     * @var ilCertificateObjectHelper|null
36     */
37    private $objectHelper;
38
39    /**
40     * @var ilCertificateObjectLPHelper
41     */
42    private $lpHelper;
43
44    /**
45     * @var ilTree|mixed|null
46     */
47    private $tree;
48
49    /**
50     * @var ilSetting|null
51     */
52    private $setting;
53
54    /**
55     * @param ilObject $object
56     * @param string $certificatePath
57     * @param ilLanguage $language
58     * @param ilCtrl $controller
59     * @param ilAccess $access
60     * @param ilToolbarGUI $toolbar
61     * @param ilCertificatePlaceholderDescription $placeholderDescriptionObject
62     * @param ilObjectLP|null $learningProgressObject
63     * @param ilCertificateSettingsFormRepository|null $settingsFromFactory
64     * @param ilCertificateObjUserTrackingHelper|null $trackingHelper
65     * @param ilCertificateObjectHelper|null $objectHelper
66     * @param ilCertificateObjectLPHelper|null $lpHelper
67     * @param ilTree|null $tree
68     * @param ilSetting|null $setting
69     */
70    public function __construct(
71        \ilObject $object,
72        string $certificatePath,
73        bool $hasAdditionalElements,
74        ilLanguage $language,
75        ilCtrl $controller,
76        ilAccess $access,
77        ilToolbarGUI $toolbar,
78        ilCertificatePlaceholderDescription $placeholderDescriptionObject,
79        ilObjectLP $learningProgressObject = null,
80        ilCertificateSettingsFormRepository $settingsFromFactory = null,
81        ilCertificateObjUserTrackingHelper $trackingHelper = null,
82        ilCertificateObjectHelper $objectHelper = null,
83        ilCertificateObjectLPHelper $lpHelper = null,
84        ilTree $tree = null,
85        ilSetting $setting = null
86    ) {
87        $this->object = $object;
88
89        $this->language = $language;
90
91        if (null === $settingsFromFactory) {
92            $settingsFromFactory = new ilCertificateSettingsFormRepository(
93                $object->getId(),
94                $certificatePath,
95                $hasAdditionalElements,
96                $language,
97                $controller,
98                $access,
99                $toolbar,
100                $placeholderDescriptionObject
101            );
102        }
103        $this->settingsFromFactory = $settingsFromFactory;
104
105        if (null === $learningProgressObject) {
106            $learningProgressObject = ilObjectLP::getInstance($this->object->getId());
107        }
108        $this->learningProgressObject = $learningProgressObject;
109
110        if (null === $trackingHelper) {
111            $trackingHelper = new ilCertificateObjUserTrackingHelper();
112        }
113        $this->trackingHelper = $trackingHelper;
114
115        if (null === $objectHelper) {
116            $objectHelper = new ilCertificateObjectHelper();
117        }
118        $this->objectHelper = $objectHelper;
119
120        if (null === $lpHelper) {
121            $lpHelper = new ilCertificateObjectLPHelper();
122        }
123        $this->lpHelper = $lpHelper;
124
125        if (null === $tree) {
126            global $DIC;
127            $tree = $DIC['tree'];
128        }
129        $this->tree = $tree;
130
131        if (null === $setting) {
132            $setting = new ilSetting('crs');
133        }
134        $this->setting = $setting;
135    }
136
137    /**
138     * @param ilCertificateGUI $certificateGUI
139     * @return ilPropertyFormGUI
140     * @throws \ILIAS\Filesystem\Exception\FileAlreadyExistsException
141     * @throws \ILIAS\Filesystem\Exception\FileNotFoundException
142     * @throws \ILIAS\Filesystem\Exception\IOException
143     * @throws ilDatabaseException
144     * @throws ilException
145     * @throws ilWACException
146     */
147    public function createForm(ilCertificateGUI $certificateGUI)
148    {
149        $form = $this->settingsFromFactory->createForm($certificateGUI);
150
151        $objectLearningProgressSettings = new ilLPObjSettings($this->object->getId());
152
153        $mode = $objectLearningProgressSettings->getMode();
154        if (!$this->trackingHelper->enabledLearningProgress() || $mode == ilLPObjSettings::LP_MODE_DEACTIVATED) {
155            $subitems = new ilRepositorySelector2InputGUI($this->language->txt('objects'), 'subitems', true);
156
157            $formSection = new \ilFormSectionHeaderGUI();
158            $formSection->setTitle($this->language->txt('cert_form_sec_add_features'));
159            $form->addItem($formSection);
160
161            $exp = $subitems->getExplorerGUI();
162            $exp->setSkipRootNode(true);
163            $exp->setRootId($this->object->getRefId());
164            $exp->setTypeWhiteList($this->getLPTypes($this->object->getId()));
165
166            $objectHelper = $this->objectHelper;
167            $lpHelper = $this->lpHelper;
168            $subitems->setTitleModifier(function ($id) use ($objectHelper, $lpHelper) {
169                if (null === $id) {
170                    return '';
171                }
172                $obj_id = $objectHelper->lookupObjId((int) $id);
173                $olp = $lpHelper->getInstance($obj_id);
174
175                $invalid_modes = $this->getInvalidLPModes();
176
177                $mode = $olp->getModeText($olp->getCurrentMode());
178
179                if (in_array($olp->getCurrentMode(), $invalid_modes)) {
180                    $mode = '<strong>' . $mode . '</strong>';
181                }
182                return $objectHelper->lookupTitle($obj_id) . ' (' . $mode . ')';
183            });
184
185            $subitems->setRequired(true);
186            $form->addItem($subitems);
187        }
188
189        return $form;
190    }
191
192    /**
193     * @param array $formFields
194     */
195    public function save(array $formFields)
196    {
197        $invalidModes = $this->getInvalidLPModes();
198
199        $titlesOfObjectsWithInvalidModes = array();
200        $refIds = array();
201        if (isset($formFields['subitems'])) {
202            $refIds = $formFields['subitems'];
203        }
204
205        foreach ($refIds as $refId) {
206            $objectId = $this->objectHelper->lookupObjId((int) $refId);
207            $learningProgressObject = $this->lpHelper->getInstance($objectId);
208            $currentMode = $learningProgressObject->getCurrentMode();
209            if (in_array($currentMode, $invalidModes)) {
210                $titlesOfObjectsWithInvalidModes[] = $this->objectHelper->lookupTitle($objectId);
211            }
212        }
213
214        if (sizeof($titlesOfObjectsWithInvalidModes)) {
215            $message = sprintf($this->language->txt('certificate_learning_progress_must_be_active'), implode(', ', $titlesOfObjectsWithInvalidModes));
216            throw new ilException($message);
217        }
218
219        $this->setting->set('cert_subitems_' . $this->object->getId(), json_encode($formFields['subitems']));
220    }
221
222    /**
223     * @param string $content
224     * @return array|mixed
225     */
226    public function fetchFormFieldData(string $content)
227    {
228        $formFields = $this->settingsFromFactory->fetchFormFieldData($content);
229
230        $formFields['subitems'] = json_decode($this->setting->get('cert_subitems_' . $this->object->getId(), json_encode(array())));
231        if ($formFields['subitems'] === 'null' || $formFields['subitems'] === null) {
232            $formFields['subitems'] = array();
233        }
234        return $formFields;
235    }
236
237    /**
238     * @param int $a_parent_ref_id
239     * @return array
240     */
241    private function getLPTypes(int $a_parent_ref_id) : array
242    {
243        $result = array();
244
245        $root = $this->tree->getNodeData($a_parent_ref_id);
246        $sub_items = $this->tree->getSubTree($root);
247        array_shift($sub_items); // remove root
248
249        foreach ($sub_items as $node) {
250            if ($this->lpHelper->isSupportedObjectType($node['type'])) {
251                $class = $this->lpHelper->getTypeClass($node['type']);
252                $modes = $class::getDefaultModes($this->trackingHelper->enabledLearningProgress());
253
254                if (sizeof($modes) > 1) {
255                    $result[] = $node['type'];
256                }
257            }
258        }
259
260        return $result;
261    }
262
263    /**
264     * @return array
265     */
266    private function getInvalidLPModes()
267    {
268        $invalid_modes = array(
269            ilLPObjSettings::LP_MODE_DEACTIVATED,
270            ilLPObjSettings::LP_MODE_UNDEFINED
271        );
272
273        // without active LP the following modes cannot be supported
274        if (!$this->trackingHelper->enabledLearningProgress()) {
275            // status cannot be set without active LP
276            $invalid_modes[] = ilLPObjSettings::LP_MODE_MANUAL;
277            $invalid_modes[] = ilLPObjSettings::LP_MODE_MANUAL_BY_TUTOR;
278            $invalid_modes[] = ilLPObjSettings::LP_MODE_COLLECTION_MANUAL;
279
280            // mode cannot be configured without active LP
281            $invalid_modes[] = ilLPObjSettings::LP_MODE_COLLECTION;
282            $invalid_modes[] = ilLPObjSettings::LP_MODE_COLLECTION_MOBS;
283            $invalid_modes[] = ilLPObjSettings::LP_MODE_COLLECTION_TLT;
284            $invalid_modes[] = ilLPObjSettings::LP_MODE_SCORM;
285            $invalid_modes[] = ilLPObjSettings::LP_MODE_VISITS; // ?
286        }
287
288        return $invalid_modes;
289    }
290}
291