1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4/**
5 * ADT base class
6 *
7 * @author Jörg Lützenkirchen <luetzenkirchen@leifos.com>
8 * @version $Id$
9 * @ingroup ServicesADT
10 */
11abstract class ilADT
12{
13    protected $definition; // [ilADTDefinition]
14    protected $validation_errors = []; // [array]
15
16
17    // :TODO: error codes for ALL types - see self::translateErrorMessage()
18
19    const ADT_VALIDATION_ERROR_NULL_NOT_ALLOWED = "adt1";
20
21    // text-based
22    const ADT_VALIDATION_ERROR_MAX_LENGTH = "adt2";
23
24    // multi
25    const ADT_VALIDATION_ERROR_MAX_SIZE = "adt3";
26
27    // number-based
28    const ADT_VALIDATION_ERROR_MIN = "adt4";
29    const ADT_VALIDATION_ERROR_MAX = "adt5";
30
31    // date-based
32    const ADT_VALIDATION_DATE = "adt6";
33
34    // invalid target node for internal link
35    const ADT_VALIDATION_ERROR_INVALID_NODE = 'adt7';
36
37    /**
38     * Constructor
39     *
40     * @return self
41     */
42    public function __construct(ilADTDefinition $a_def)
43    {
44        $this->setDefinition($a_def);
45        $this->reset();
46    }
47
48    /**
49     * Get type (from class/instance)
50     *
51     * @return string
52     */
53    public function getType()
54    {
55        return $this->getDefinition()->getType();
56    }
57
58    /**
59     * Init property defaults
60     */
61    protected function reset()
62    {
63    }
64
65
66    //
67    // definition
68    //
69
70    /**
71     * Check if definition is valid for ADT
72     *
73     * @return bool;
74     */
75    abstract protected function isValidDefinition(ilADTDefinition $a_def);
76
77    /**
78     * Set definition
79     *
80     * @throws ilException
81     * @param ilADTDefinition $a_def
82     */
83    protected function setDefinition(ilADTDefinition $a_def)
84    {
85        if ($this->isValidDefinition($a_def)) {
86            $this->definition = clone $a_def;
87        } else {
88            throw new ilException("ilADT invalid definition");
89        }
90    }
91
92    /**
93     * Get definition
94     *
95     * @return ilADTDefinition $a_def
96     */
97    protected function getDefinition()
98    {
99        return $this->definition;
100    }
101
102    /**
103     * Get copy of definition
104     *
105     * @return ilADTDefinition $a_def
106     */
107    public function getCopyOfDefinition()
108    {
109        return (clone $this->definition);
110    }
111
112
113    //
114    // comparison
115    //
116
117    /**
118     * Check if given ADT equals self
119     *
120     * @param ilADT $a_adt
121     * @return bool
122     */
123    abstract public function equals(ilADT $a_adt);
124
125    /**
126     * Check if given ADT is larger than self
127     *
128     * @param ilADT $a_adt
129     * @return bool
130     */
131    abstract public function isLarger(ilADT $a_adt);
132
133    /**
134     * Check if given ADT is larger or equal than self
135     *
136     * @param ilADT $a_adt
137     * @return bool
138     */
139    public function isLargerOrEqual(ilADT $a_adt)
140    {
141        return ($this->equals($a_adt) ||
142            $this->isLarger($a_adt));
143    }
144
145    /**
146     * Check if given ADT is smaller than self
147     *
148     * @param ilADT $a_adt
149     * @return bool
150     */
151    abstract public function isSmaller(ilADT $a_adt);
152
153    /**
154     * Check if given ADT is smaller or equal than self
155     *
156     * @param ilADT $a_adt
157     * @return bool
158     */
159    public function isSmallerOrEqual(ilADT $a_adt)
160    {
161        return ($this->equals($a_adt) ||
162            $this->isSmaller($a_adt));
163    }
164
165    /**
166     * Check if self is inbetween given ADTs (exclusive)
167     *
168     * @param ilADT $a_adt_from
169     * @param ilADT $a_adt_to
170     * @return bool
171     */
172    public function isInbetween(ilADT $a_adt_from, ilADT $a_adt_to)
173    {
174        return ($this->isLarger($a_adt_from) &&
175            $this->isSmaller($a_adt_to));
176    }
177
178    /**
179     * Check if self is inbetween given ADTs (inclusive)
180     *
181     * @param ilADT $a_adt_from
182     * @param ilADT $a_adt_to
183     * @return bool
184     */
185    public function isInbetweenOrEqual(ilADT $a_adt_from, ilADT $a_adt_to)
186    {
187        return ($this->equals($a_adt_from) ||
188            $this->equals($a_adt_to) ||
189            $this->isInbetween($a_adt_from, $a_adt_to));
190    }
191
192
193    //
194    // null
195    //
196
197    /**
198     * Is currently null
199     *
200     * @return bool
201     */
202    abstract public function isNull();
203
204
205    //
206    // validation
207    //
208
209    /**
210     * Is currently valid
211     *
212     * @return boolean
213     */
214    public function isValid()
215    {
216        $this->validation_errors = array();
217
218        if (!$this->getDefinition()->isNullAllowed() && $this->isNull()) {
219            $this->addValidationError(self::ADT_VALIDATION_ERROR_NULL_NOT_ALLOWED);
220            return false;
221        }
222        return true;
223    }
224
225    /**
226     * Add validation error code
227     *
228     * @param int $a_error_code
229     */
230    protected function addValidationError($a_error_code)
231    {
232        $this->validation_errors[] = (string) $a_error_code;
233    }
234
235    /**
236     * Get all validation error codes
237     *
238     * @see isValid()
239     * @return array
240     */
241    public function getValidationErrors()
242    {
243        if (is_array($this->validation_errors) &&
244            sizeof($this->validation_errors)) {
245            return array_unique($this->validation_errors);
246        }
247        return array();
248    }
249
250    /**
251     * Translate error-code to human-readable message
252     *
253     * @throws Exception
254     * @param int $a_code
255     * @return string
256     */
257    public function translateErrorCode($a_code)
258    {
259        global $DIC;
260
261        $lng = $DIC['lng'];
262
263        // $lng->txt("msg_wrong_format");
264
265        switch ($a_code) {
266            case self::ADT_VALIDATION_ERROR_NULL_NOT_ALLOWED:
267                return $lng->txt("msg_input_is_required");
268
269            case self::ADT_VALIDATION_ERROR_MAX_LENGTH:
270                return $lng->txt("adt_error_max_length");
271
272            case self::ADT_VALIDATION_ERROR_MAX_SIZE:
273                return $lng->txt("adt_error_max_size");
274
275            case self::ADT_VALIDATION_ERROR_MIN:
276                return $lng->txt("form_msg_value_too_low");
277
278            case self::ADT_VALIDATION_ERROR_MAX:
279                return $lng->txt("form_msg_value_too_high");
280
281            // :TODO: currently not used - see ilDateTimeInputGUI
282            case self::ADT_VALIDATION_DATE:
283                return $lng->txt("exc_date_not_valid");
284
285            default:
286                throw new Exception("ADT unknown error code");
287        }
288    }
289
290    /**
291     * Get unique checksum
292     *
293     * @return string
294     */
295    abstract public function getCheckSum();
296}
297