1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4/**
5 * Class ilDclFieldEditGUI
6 *
7 * @author  Martin Studer <ms@studer-raimann.ch>
8 * @author  Marcel Raimann <mr@studer-raimann.ch>
9 * @author  Fabian Schmid <fs@studer-raimann.ch>
10 * @author  Oskar Truffer <ot@studer-raimann.ch>
11 * @version $Id:
12 *
13 *
14 *
15 * @ingroup ModulesDataCollection
16 */
17class ilDclFieldEditGUI
18{
19
20    /**
21     * @var int
22     */
23    protected $obj_id;
24    /**
25     * @var int
26     */
27    protected $table_id;
28    /**
29     * @var ilObjDataCollectionGUI|object
30     */
31    protected $parent_obj;
32    /**
33     * @var ilDclTable
34     */
35    protected $table;
36    /**
37     * @var ilPropertyFormGUI
38     */
39    protected $form;
40    /**
41     * @var ilDclBaseFieldModel
42     */
43    protected $field_obj;
44
45
46    /**
47     * Constructor
48     *
49     * @param ilDclTableListGUI $a_parent_obj
50     * @param    int            $table_id We need a table_id if no field_id is set (creation mode). We ignore the table_id by edit mode
51     * @param    int            $field_id The field_id of a existing fiel (edit mode)
52     */
53    public function __construct(ilDclTableListGUI $a_parent_obj)
54    {
55        global $DIC;
56        $ilCtrl = $DIC['ilCtrl'];
57
58        $this->obj_id = $a_parent_obj->obj_id;
59        $this->parent_obj = $a_parent_obj;
60
61        $this->table_id = $_GET["table_id"];
62        $this->field_id = $_GET['field_id'];
63
64        if ($this->field_id) {
65            $this->field_obj = ilDclCache::getFieldCache($this->field_id);
66        } else {
67            $datatype = null;
68            if (isset($_POST['datatype']) && in_array($_POST['datatype'], array_keys(ilDclDatatype::getAllDatatype()))) {
69                $datatype = $_POST['datatype'];
70            }
71            $this->field_obj = ilDclFieldFactory::getFieldModelInstance($this->field_id, $datatype);
72            if (!$this->table_id) {
73                $ilCtrl->redirectByClass("ilDclTableListGUI", "listFields");
74            }
75            $this->field_obj->setTableId($this->table_id);
76            $ilCtrl->saveParameter($this, "table_id");
77        }
78
79        $this->table = ilDclCache::getTableCache($this->table_id);
80    }
81
82
83    /**
84     * execute command
85     */
86    public function executeCommand()
87    {
88        global $DIC;
89        $ilCtrl = $DIC['ilCtrl'];
90        $ilCtrl->saveParameter($this, 'field_id');
91
92        $cmd = $ilCtrl->getCmd();
93
94        if (!$this->checkAccess()) {
95            $this->permissionDenied();
96
97            return;
98        }
99
100        switch ($cmd) {
101            case "update":
102                $this->save("update");
103                break;
104            default:
105                $this->$cmd();
106                break;
107        }
108
109        return true;
110    }
111
112
113    /**
114     * create field add form
115     */
116    public function create()
117    {
118        global $DIC;
119        $tpl = $DIC['tpl'];
120
121        $this->initForm();
122        $tpl->setContent($this->form->getHTML());
123    }
124
125
126    /**
127     * create field edit form
128     */
129    public function edit()
130    {
131        global $DIC;
132        $tpl = $DIC['tpl'];
133
134        $this->initForm("edit");
135
136        $this->field_obj->fillPropertiesForm($this->form);
137
138        $tpl->setContent($this->form->getHTML());
139    }
140
141
142    /*
143     * permissionDenied
144     */
145    public function permissionDenied()
146    {
147        global $DIC;
148        $tpl = $DIC['tpl'];
149        $tpl->setContent("Permission denied");
150    }
151
152
153    /**
154     * confirmDelete
155     */
156    public function confirmDelete()
157    {
158        global $DIC;
159        $ilCtrl = $DIC['ilCtrl'];
160        $lng = $DIC['lng'];
161        $tpl = $DIC['tpl'];
162
163        include_once './Services/Utilities/classes/class.ilConfirmationGUI.php';
164        $conf = new ilConfirmationGUI();
165        $conf->setFormAction($ilCtrl->getFormAction($this));
166        $conf->setHeaderText($lng->txt('dcl_confirm_delete_field'));
167
168        $conf->addItem('field_id', (int) $this->field_obj->getId(), $this->field_obj->getTitle());
169
170        $conf->setConfirm($lng->txt('delete'), 'delete');
171        $conf->setCancel($lng->txt('cancel'), 'cancelDelete');
172
173        $tpl->setContent($conf->getHTML());
174    }
175
176
177    /**
178     * cancelDelete
179     */
180    public function cancelDelete()
181    {
182        global $DIC;
183        $ilCtrl = $DIC['ilCtrl'];
184
185        $ilCtrl->redirectByClass("ildclfieldlistgui", "listFields");
186    }
187
188
189    /*
190     * delete
191     */
192    public function delete()
193    {
194        global $DIC;
195        $ilCtrl = $DIC['ilCtrl'];
196
197        $this->table->deleteField($this->field_obj->getId());
198        $ilCtrl->redirectByClass("ildclfieldlistgui", "listFields");
199    }
200
201
202    /*
203     * cancel
204     */
205    public function cancel()
206    {
207        global $DIC;
208        $ilCtrl = $DIC['ilCtrl'];
209        $ilCtrl->redirectByClass("ildclfieldlistgui", "listFields");
210    }
211
212
213    /**
214     * initEditCustomForm
215     *
216     * @param string $a_mode values: create | edit
217     */
218    public function initForm($a_mode = "create")
219    {
220        global $DIC;
221        $ilCtrl = $DIC['ilCtrl'];
222        $lng = $DIC['lng'];
223
224        include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
225        $this->form = new ilPropertyFormGUI();
226
227        if ($a_mode == "edit") {
228            $this->form->setTitle($lng->txt('dcl_edit_field'));
229            $hidden_prop = new ilHiddenInputGUI("field_id");
230            $this->form->addItem($hidden_prop);
231
232            $this->form->setFormAction($ilCtrl->getFormAction($this), "update");
233
234            $this->form->addCommandButton('update', $lng->txt('dcl_update_field'));
235        } else {
236            $this->form->setTitle($lng->txt('dcl_new_field'));
237            $hidden_prop = new ilHiddenInputGUI("table_id");
238            $hidden_prop->setValue($this->field_obj->getTableId());
239            $this->form->addItem($hidden_prop);
240
241            $this->form->setFormAction($ilCtrl->getFormAction($this), "save");
242
243            $this->form->addCommandButton('save', $lng->txt('dcl_create_field'));
244        }
245        $this->form->addCommandButton('cancel', $lng->txt('cancel'));
246
247        $text_prop = new ilTextInputGUI($lng->txt("title"), "title");
248        $text_prop->setRequired(true);
249        $text_prop->setInfo(sprintf($lng->txt('fieldtitle_allow_chars'), ilDclBaseFieldModel::_getTitleInvalidChars(false)));
250        $text_prop->setValidationRegexp(ilDclBaseFieldModel::_getTitleInvalidChars(true));
251        $this->form->addItem($text_prop);
252
253        // Description
254        $text_prop = new ilTextAreaInputGUI($lng->txt("dcl_field_description"), "description");
255        $this->form->addItem($text_prop);
256
257        $edit_datatype = new ilRadioGroupInputGUI($lng->txt('dcl_datatype'), 'datatype');
258
259        foreach (ilDclDatatype::getAllDatatype() as $datatype) {
260            $model = new ilDclBaseFieldModel();
261            $model->setDatatypeId($datatype->getId());
262
263            if ($a_mode == 'edit' && $datatype->getId() == $this->field_obj->getDatatypeId()) {
264                $model = $this->field_obj;
265            }
266
267            $field_representation = ilDclFieldFactory::getFieldRepresentationInstance($model);
268            $field_representation->addFieldCreationForm($edit_datatype, $this->getDataCollectionObject(), $a_mode);
269        }
270        $edit_datatype->setRequired(true);
271
272        //you can't change type but we still need it in POST
273        if ($a_mode == "edit") {
274            $edit_datatype->setDisabled(true);
275        }
276        $this->form->addItem($edit_datatype);
277
278        // Required
279        $cb = new ilCheckboxInputGUI($lng->txt("dcl_field_required"), "required");
280        $this->form->addItem($cb);
281
282        //Unique
283        $cb = new ilCheckboxInputGUI($lng->txt("dcl_unique"), "unique");
284        $cb->setInfo($lng->txt('dcl_unique_desc'));
285        $this->form->addItem($cb);
286    }
287
288
289    /**
290     * save Field
291     *
292     * @param string $a_mode values: create | update
293     */
294    public function save($a_mode = "create")
295    {
296        global $DIC;
297        $ilCtrl = $DIC['ilCtrl'];
298        $lng = $DIC['lng'];
299        $tpl = $DIC['tpl'];
300
301        $this->initForm($a_mode == "update" ? "edit" : "create");
302
303        if ($this->checkInput($a_mode)) {
304
305            // check if confirmation is needed and if so, fetch and render confirmationGUI
306            if (($a_mode == "update") && !($this->form->getInput('confirmed')) && $this->field_obj->isConfirmationRequired($this->form)) {
307                $ilConfirmationGUI = $this->field_obj->getConfirmationGUI($this->form);
308                $tpl->setContent($ilConfirmationGUI->getHTML());
309
310                return;
311            }
312
313            $title = $this->form->getInput("title");
314            if ($a_mode != "create" && $title != $this->field_obj->getTitle()) {
315                ilUtil::sendInfo($lng->txt("dcl_field_title_change_warning"), true);
316            }
317
318            $this->field_obj->setTitle($title);
319            $this->field_obj->setDescription($this->form->getInput("description"));
320            $this->field_obj->setDatatypeId($this->form->getInput("datatype"));
321            $this->field_obj->setRequired($this->form->getInput("required"));
322            $this->field_obj->setUnique($this->form->getInput("unique"));
323
324            if ($a_mode == "update") {
325                $this->field_obj->doUpdate();
326            } else {
327                $this->field_obj->setOrder($this->table->getNewFieldOrder());
328                $this->field_obj->doCreate();
329            }
330
331            // Get possible properties and save them
332            $this->field_obj->storePropertiesFromForm($this->form);
333
334            $ilCtrl->setParameter($this, "field_id", $this->field_obj->getId());
335
336            if ($a_mode == "update") {
337                ilUtil::sendSuccess($lng->txt("dcl_msg_field_modified"), true);
338            } else {
339                $this->table->addField($this->field_obj);
340                $this->table->buildOrderFields();
341                ilUtil::sendSuccess($lng->txt("msg_field_created"), false);
342            }
343            $ilCtrl->redirectByClass(strtolower("ilDclFieldListGUI"), "listFields");
344        } else {
345            $this->form->setValuesByPost();
346            $tpl->setContent($this->form->getHTML());
347        }
348    }
349
350
351    /**
352     * Check input of form
353     *
354     * @param $a_mode 'create' | 'update'
355     *
356     * @return bool
357     */
358    protected function checkInput($a_mode)
359    {
360        global $DIC;
361        $lng = $DIC['lng'];
362        $return = $this->form->checkInput();
363
364        // load specific model for input checking
365        $datatype_id = $this->form->getInput('datatype');
366        if ($datatype_id != null && is_numeric($datatype_id)) {
367            $base_model = new ilDclBaseFieldModel();
368            $base_model->setDatatypeId($datatype_id);
369            $field_validation_class = ilDclFieldFactory::getFieldModelInstanceByClass($base_model);
370
371            if (!$field_validation_class->checkFieldCreationInput($this->form)) {
372                $return = false;
373            }
374        }
375
376        // Don't allow multiple fields with the same title in this table
377        if ($a_mode == 'create') {
378            if ($title = $this->form->getInput('title')) {
379                if (ilDclTable::_hasFieldByTitle($title, $this->table_id)) {
380                    $inputObj = $this->form->getItemByPostVar('title');
381                    $inputObj->setAlert($lng->txt("dcl_field_title_unique"));
382                    $return = false;
383                }
384            }
385        }
386
387        if (!$return) {
388            ilUtil::sendFailure($lng->txt("form_input_not_valid"));
389        }
390
391        return $return;
392    }
393
394
395    /**
396     * @return bool
397     */
398    protected function checkAccess()
399    {
400        if ($field_id = $this->field_obj->getId()) {
401            return ilObjDataCollectionAccess::hasAccessToField($this->getDataCollectionObject()->ref_id, $this->table_id, $field_id);
402        } else {
403            return ilObjDataCollectionAccess::hasAccessToFields($this->getDataCollectionObject()->ref_id, $this->table_id);
404        }
405    }
406
407    /**
408     * @return ilObjDataCollection
409     */
410    public function getDataCollectionObject()
411    {
412        return $this->parent_obj->getDataCollectionObject();
413    }
414}
415