Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
47.53% |
241 / 507 |
|
44.19% |
19 / 43 |
CRAP | |
0.00% |
0 / 2 |
SeedDMS_Core_Attribute | |
47.67% |
41 / 86 |
|
33.33% |
4 / 12 |
281.83 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
setDMS | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDMS | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getID | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getValue | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getParsedValue | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
30 | |||
getValueAsArray | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
4.25 | |||
setValue | |
49.06% |
26 / 53 |
|
0.00% |
0 / 1 |
92.94 | |||
validate | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getValidationError | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setValidationError | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAttributeDefinition | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
SeedDMS_Core_AttributeDefinition | |
47.51% |
200 / 421 |
|
48.39% |
15 / 31 |
6164.05 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
1 | |||
setDMS | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDMS | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getID | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getName | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setName | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
getObjType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setObjType | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
getType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setType | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
getMultipleValues | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setMultipleValues | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
getMinValues | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setMinValues | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
getMaxValues | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setMaxValues | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
getValueSet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getValueSetSeparator | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
4.05 | |||
getValueSetAsArray | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getValueSetValue | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
setValueSet | |
84.62% |
11 / 13 |
|
0.00% |
0 / 1 |
3.03 | |||
getRegex | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setRegex | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
4.02 | |||
isUsed | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
56 | |||
parseValue | |
30.56% |
11 / 36 |
|
0.00% |
0 / 1 |
90.35 | |||
getStatistics | |
0.00% |
0 / 75 |
|
0.00% |
0 / 1 |
1190 | |||
remove | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
getObjects | |
0.00% |
0 / 33 |
|
0.00% |
0 / 1 |
272 | |||
removeValue | |
0.00% |
0 / 39 |
|
0.00% |
0 / 1 |
272 | |||
validate | |
81.74% |
94 / 115 |
|
0.00% |
0 / 1 |
101.70 | |||
getValidationError | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Implementation of the attribute object in the document management system |
4 | * |
5 | * @category DMS |
6 | * @package SeedDMS_Core |
7 | * @license GPL 2 |
8 | * @version @version@ |
9 | * @author Uwe Steinmann <uwe@steinmann.cx> |
10 | * @copyright Copyright (C) 2012 Uwe Steinmann |
11 | * @version Release: @package_version@ |
12 | */ |
13 | |
14 | /** |
15 | * Class to represent an attribute in the document management system |
16 | * |
17 | * Attributes are key/value pairs which can be attachted to documents, |
18 | * folders and document content. The number of attributes is unlimited. |
19 | * Each attribute has a value and is related to an attribute definition, |
20 | * which holds the name and other information about the attribute. |
21 | * |
22 | * @see SeedDMS_Core_AttributeDefinition |
23 | * |
24 | * @category DMS |
25 | * @package SeedDMS_Core |
26 | * @author Uwe Steinmann <uwe@steinmann.cx> |
27 | * @copyright Copyright (C) 2012-2013 Uwe Steinmann |
28 | * @version Release: @package_version@ |
29 | */ |
30 | class SeedDMS_Core_Attribute { /* {{{ */ |
31 | /** |
32 | * @var integer id of attribute |
33 | * |
34 | * @access protected |
35 | */ |
36 | protected $_id; |
37 | |
38 | /** |
39 | * @var SeedDMS_Core_Folder|SeedDMS_Core_Document|SeedDMS_Core_DocumentContent SeedDMS_Core_Object folder, document or document content |
40 | * this attribute belongs to |
41 | * |
42 | * @access protected |
43 | */ |
44 | protected $_obj; |
45 | |
46 | /** |
47 | * @var SeedDMS_Core_AttributeDefinition definition of this attribute |
48 | * |
49 | * @access protected |
50 | */ |
51 | protected $_attrdef; |
52 | |
53 | /** |
54 | * @var mixed value of this attribute |
55 | * |
56 | * @access protected |
57 | */ |
58 | protected $_value; |
59 | |
60 | /** |
61 | * @var integer validation error |
62 | * |
63 | * @access protected |
64 | */ |
65 | protected $_validation_error; |
66 | |
67 | /** |
68 | * @var SeedDMS_Core_DMS reference to the dms instance this attribute belongs to |
69 | * |
70 | * @access protected |
71 | */ |
72 | protected $_dms; |
73 | |
74 | /** |
75 | * SeedDMS_Core_Attribute constructor. |
76 | * @param $id |
77 | * @param $obj |
78 | * @param $attrdef |
79 | * @param $value |
80 | */ |
81 | function __construct($id, $obj, $attrdef, $value) { /* {{{ */ |
82 | $this->_id = $id; |
83 | $this->_obj = $obj; |
84 | $this->_attrdef = $attrdef; |
85 | $this->_value = $value; |
86 | $this->_validation_error = 0; |
87 | $this->_dms = null; |
88 | } /* }}} */ |
89 | |
90 | /** |
91 | * Set reference to dms |
92 | * |
93 | * @param SeedDMS_Core_DMS $dms |
94 | */ |
95 | function setDMS($dms) { /* {{{ */ |
96 | $this->_dms = $dms; |
97 | } /* }}} */ |
98 | |
99 | /** |
100 | * Get dms of attribute |
101 | * |
102 | * @return object $dms |
103 | */ |
104 | function getDMS() { return $this->_dms; } |
105 | |
106 | /** |
107 | * Get internal id of attribute |
108 | * |
109 | * @return integer id |
110 | */ |
111 | function getID() { return $this->_id; } |
112 | |
113 | /** |
114 | * Return attribute value as stored in database |
115 | * |
116 | * This function will return the value of multi value attributes |
117 | * including the separator char. |
118 | * |
119 | * @return string the attribute value as it is stored in the database. |
120 | */ |
121 | function getValue() { return $this->_value; } |
122 | |
123 | /** |
124 | * Return attribute value parsed into a php type or object |
125 | * |
126 | * This function will return the value of multi value attributes |
127 | * including the separator char. |
128 | * |
129 | * @return string the attribute value as it is stored in the database. |
130 | */ |
131 | function getParsedValue() { /* {{{ */ |
132 | switch($this->_attrdef->getType()) { |
133 | case SeedDMS_Core_AttributeDefinition::type_float: |
134 | return (float) $this->_value; |
135 | case SeedDMS_Core_AttributeDefinition::type_boolean: |
136 | return (bool) $this->_value; |
137 | case SeedDMS_Core_AttributeDefinition::type_int: |
138 | return (int) $this->_value; |
139 | default: |
140 | return $this->_value; |
141 | } |
142 | } /* }}} */ |
143 | |
144 | /** |
145 | * Return attribute values as an array |
146 | * |
147 | * This function returns the attribute value as an array. The array |
148 | * has one element for non multi value attributes and n elements for |
149 | * multi value attributes. |
150 | * |
151 | * @return array the attribute values |
152 | */ |
153 | function getValueAsArray() { /* {{{ */ |
154 | if($this->_attrdef->getMultipleValues()) { |
155 | /* If the value doesn't start with the separator used in the value set, |
156 | * then assume that the value was not saved with a leading separator. |
157 | * This can happen, if the value was previously a single value from |
158 | * the value set and later turned into a multi value attribute. |
159 | */ |
160 | $sep = substr($this->_value, 0, 1); |
161 | if(!($vsep = $this->_attrdef->getValueSetSeparator())) |
162 | $vsep = $sep; |
163 | if($sep == $vsep) |
164 | return(explode($sep, substr($this->_value, 1))); |
165 | else |
166 | return(array($this->_value)); |
167 | } else { |
168 | return array($this->_value); |
169 | } |
170 | } /* }}} */ |
171 | |
172 | /** |
173 | * Set a value of an attribute |
174 | * |
175 | * The attribute is completely deleted if the value is an empty string |
176 | * or empty array. An array of values is only allowed if the attribute may |
177 | * have multiple values. If an array is passed and the attribute may |
178 | * have only a single value, then the first element of the array will |
179 | * be taken. |
180 | * |
181 | * @param string $values value as string or array to be set |
182 | * @return boolean true if operation was successfull, otherwise false |
183 | */ |
184 | function setValue($values) { /* {{{*/ |
185 | $db = $this->_dms->getDB(); |
186 | |
187 | if($this->_attrdef->getMultipleValues()) { |
188 | $valuesetstr = $this->_attrdef->getValueSet(); |
189 | /* Multiple values without a value set is not allowed */ |
190 | /* No need to have valueset anymore. If none is given, the values are |
191 | * expected to be separated by ',' |
192 | if(!$valuesetstr) |
193 | return false; |
194 | */ |
195 | $valueset = $this->_attrdef->getValueSetAsArray(); |
196 | |
197 | if(is_array($values)) { |
198 | if($values) { |
199 | $vsep = $this->_attrdef->getValueSetSeparator(); |
200 | if($valueset) { |
201 | /* Validation should have been done before |
202 | $error = false; |
203 | foreach($values as $v) { |
204 | if(!in_array($v, $valueset)) { $error = true; break; } |
205 | } |
206 | if($error) |
207 | return false; |
208 | */ |
209 | $valuesetstr = $this->_attrdef->getValueSet(); |
210 | $value = $vsep.implode($vsep, $values); |
211 | } else { |
212 | $value = $vsep.implode($vsep, $values); |
213 | } |
214 | } else { |
215 | $value = ''; |
216 | } |
217 | } else { |
218 | if($values) { |
219 | if($valuesetstr) { |
220 | if($valuesetstr[0] != $values[0]) |
221 | $values = explode($valuesetstr[0], $values); |
222 | else |
223 | $values = explode($valuesetstr[0], substr($values, 1)); |
224 | } else { |
225 | $values = explode(',', substr($values, 1)); |
226 | } |
227 | |
228 | if($valueset) { |
229 | /* Validation should have been done before |
230 | $error = false; |
231 | foreach($values as $v) { |
232 | if(!in_array($v, $valueset)) { $error = true; break; } |
233 | } |
234 | if($error) |
235 | return false; |
236 | */ |
237 | $value = $valuesetstr[0].implode($valuesetstr[0], $values); |
238 | } else { |
239 | $value = ','.implode(',', $values); |
240 | } |
241 | } else { |
242 | $value = $values; |
243 | } |
244 | } |
245 | } else { |
246 | if(is_array($values)) { |
247 | if($values) |
248 | $value = $values[0]; |
249 | else |
250 | $value = ''; |
251 | } else { |
252 | $value = $values; |
253 | } |
254 | } |
255 | |
256 | switch(get_class($this->_obj)) { |
257 | case $this->_dms->getClassname('document'): |
258 | if(trim($value) === '') |
259 | $queryStr = "DELETE FROM `tblDocumentAttributes` WHERE `document` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); |
260 | else |
261 | $queryStr = "UPDATE `tblDocumentAttributes` SET `value` = ".$db->qstr($value)." WHERE `document` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); |
262 | break; |
263 | case $this->_dms->getClassname('documentcontent'): |
264 | if(trim($value) === '') |
265 | $queryStr = "DELETE FROM `tblDocumentContentAttributes` WHERE `content` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); |
266 | else |
267 | $queryStr = "UPDATE `tblDocumentContentAttributes` SET `value` = ".$db->qstr($value)." WHERE `content` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); |
268 | break; |
269 | case $this->_dms->getClassname('folder'): |
270 | if(trim($value) === '') |
271 | $queryStr = "DELETE FROM `tblFolderAttributes` WHERE `folder` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); |
272 | else |
273 | $queryStr = "UPDATE `tblFolderAttributes` SET `value` = ".$db->qstr($value)." WHERE `folder` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); |
274 | break; |
275 | default: |
276 | return false; |
277 | } |
278 | if (!$db->getResult($queryStr)) |
279 | return false; |
280 | |
281 | $oldvalue = $this->_value; |
282 | $this->_value = $value; |
283 | |
284 | /* Check if 'onPostUpdateAttribute' callback is set */ |
285 | $kk = (trim($value) === '') ? 'Remove' : 'Update'; |
286 | if(isset($this->_dms->callbacks['onPost'.$kk.'Attribute'])) { |
287 | foreach($this->_dms->callbacks['onPost'.$kk.'Attribute'] as $callback) { |
288 | if(!call_user_func($callback[0], $callback[1], $this->_obj, $this->_attrdef, $value, $oldvalue)) { |
289 | } |
290 | } |
291 | } |
292 | |
293 | return true; |
294 | } /* }}} */ |
295 | |
296 | /** |
297 | * Validate attribute value |
298 | * |
299 | * This function checks if the attribute values fits the attribute |
300 | * definition. |
301 | * If the validation fails the validation error will be set which |
302 | * can be requested by SeedDMS_Core_Attribute::getValidationError() |
303 | * |
304 | * @return boolean true if validation succeeds, otherwise false |
305 | */ |
306 | function validate() { /* {{{ */ |
307 | /** @var SeedDMS_Core_AttributeDefinition $attrdef */ |
308 | $attrdef = $this->_attrdef; |
309 | $result = $attrdef->validate($this->_value); |
310 | $this->_validation_error = $attrdef->getValidationError(); |
311 | return $result; |
312 | } /* }}} */ |
313 | |
314 | /** |
315 | * Get validation error from last validation |
316 | * |
317 | * @return integer error code |
318 | */ |
319 | function getValidationError() { return $this->_validation_error; } |
320 | |
321 | /** |
322 | * Set validation error |
323 | * |
324 | * @param integer error code |
325 | */ |
326 | function setValidationError($error) { $this->_validation_error = $error; } |
327 | |
328 | /** |
329 | * Get definition of attribute |
330 | * |
331 | * @return object attribute definition |
332 | */ |
333 | function getAttributeDefinition() { return $this->_attrdef; } |
334 | |
335 | } /* }}} */ |
336 | |
337 | /** |
338 | * Class to represent an attribute definition in the document management system |
339 | * |
340 | * Attribute definitions specify the name, type, object type, minimum and |
341 | * maximum values and a value set. The object type determines the object |
342 | * an attribute may be attached to. If the object type is set to object_all |
343 | * the attribute can be used for documents, document content and folders. |
344 | * |
345 | * The type of an attribute specifies the skalar data type. |
346 | * |
347 | * Attributes for which multiple values are allowed must have the |
348 | * multiple flag set to true and specify a value set. A value set |
349 | * is a string consisting of n separated values. The separator is the |
350 | * first char of the value set. A possible value could be '|REV-A|REV-B' |
351 | * If multiple values are allowed, then minvalues and maxvalues may |
352 | * restrict the allowed number of values. |
353 | * |
354 | * @see SeedDMS_Core_Attribute |
355 | * |
356 | * @category DMS |
357 | * @package SeedDMS_Core |
358 | * @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx> |
359 | * @copyright Copyright (C) 2012 Uwe Steinmann |
360 | * @version Release: @package_version@ |
361 | */ |
362 | class SeedDMS_Core_AttributeDefinition { /* {{{ */ |
363 | /** |
364 | * @var integer id of attribute definition |
365 | * |
366 | * @access protected |
367 | */ |
368 | protected $_id; |
369 | |
370 | /** |
371 | * @var string name of attribute definition |
372 | * |
373 | * @access protected |
374 | */ |
375 | protected $_name; |
376 | |
377 | /** |
378 | * @var string object type of attribute definition. This can be one of |
379 | * type_int, type_float, type_string, type_boolean, type_url, or type_email. |
380 | * |
381 | * @access protected |
382 | */ |
383 | protected $_type; |
384 | |
385 | /** |
386 | * @var string type of attribute definition. This can be one of objtype_all, |
387 | * objtype_folder, objtype_document, or objtype_documentcontent. |
388 | * |
389 | * @access protected |
390 | */ |
391 | protected $_objtype; |
392 | |
393 | /** |
394 | * @var boolean whether an attribute can have multiple values |
395 | * |
396 | * @access protected |
397 | */ |
398 | protected $_multiple; |
399 | |
400 | /** |
401 | * @var integer minimum values of an attribute |
402 | * |
403 | * @access protected |
404 | */ |
405 | protected $_minvalues; |
406 | |
407 | /** |
408 | * @var integer maximum values of an attribute |
409 | * |
410 | * @access protected |
411 | */ |
412 | protected $_maxvalues; |
413 | |
414 | /** |
415 | * @var string list of possible values of an attribute |
416 | * |
417 | * @access protected |
418 | */ |
419 | protected $_valueset; |
420 | |
421 | /** |
422 | * @var string regular expression the value must match |
423 | * |
424 | * @access protected |
425 | */ |
426 | protected $_regex; |
427 | |
428 | /** |
429 | * @var integer validation error |
430 | * |
431 | * @access protected |
432 | */ |
433 | protected $_validation_error; |
434 | |
435 | /** |
436 | * @var SeedDMS_Core_DMS reference to the dms instance this attribute definition belongs to |
437 | * |
438 | * @access protected |
439 | */ |
440 | protected $_dms; |
441 | |
442 | /** |
443 | * @var string just the separator of a value set (not used) |
444 | * |
445 | * @access protected |
446 | */ |
447 | protected $_separator; |
448 | |
449 | /* |
450 | * Possible skalar data types of an attribute |
451 | */ |
452 | const type_int = '1'; |
453 | const type_float = '2'; |
454 | const type_string = '3'; |
455 | const type_boolean = '4'; |
456 | const type_url = '5'; |
457 | const type_email = '6'; |
458 | const type_date = '7'; |
459 | |
460 | /* |
461 | * Addtional data types of an attribute representing objects in seeddms |
462 | */ |
463 | const type_folder = '101'; |
464 | const type_document = '102'; |
465 | //const type_documentcontent = '103'; |
466 | const type_user = '104'; |
467 | const type_group = '105'; |
468 | |
469 | /* |
470 | * The object type for which a attribute may be used |
471 | */ |
472 | const objtype_all = '0'; |
473 | const objtype_folder = '1'; |
474 | const objtype_document = '2'; |
475 | const objtype_documentcontent = '3'; |
476 | |
477 | /* |
478 | * The validation error codes |
479 | */ |
480 | const val_error_none = 0; |
481 | const val_error_min_values = 1; |
482 | const val_error_max_values = 2; |
483 | const val_error_boolean = 8; |
484 | const val_error_int = 6; |
485 | const val_error_date = 9; |
486 | const val_error_float = 7; |
487 | const val_error_regex = 3; |
488 | const val_error_email = 5; |
489 | const val_error_url = 4; |
490 | const val_error_document = 10; |
491 | const val_error_folder = 11; |
492 | const val_error_user = 12; |
493 | const val_error_group = 13; |
494 | const val_error_valueset = 14; |
495 | |
496 | /** |
497 | * Constructor |
498 | * |
499 | * @param integer $id internal id of attribute definition |
500 | * @param string $name name of attribute |
501 | * @param integer $objtype type of object for which this attribute definition |
502 | * may be used. |
503 | * @param integer $type skalar type of attribute |
504 | * @param boolean $multiple set to true if multiple values are allowed |
505 | * @param integer $minvalues minimum number of values |
506 | * @param integer $maxvalues maximum number of values |
507 | * @param string $valueset separated list of allowed values, the first char |
508 | * is taken as the separator |
509 | * @param $regex |
510 | */ |
511 | function __construct($id, $name, $objtype, $type, $multiple, $minvalues, $maxvalues, $valueset, $regex) { /* {{{ */ |
512 | $this->_id = $id; |
513 | $this->_name = $name; |
514 | $this->_type = $type; |
515 | $this->_objtype = $objtype; |
516 | $this->_multiple = $multiple; |
517 | $this->_minvalues = $minvalues; |
518 | $this->_maxvalues = $maxvalues; |
519 | $this->_valueset = $valueset; |
520 | $this->_separator = substr($valueset, 0, 1); |
521 | $this->_regex = $regex; |
522 | $this->_dms = null; |
523 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_none; |
524 | } /* }}} */ |
525 | |
526 | /** |
527 | * Set reference to dms |
528 | * |
529 | * @param SeedDMS_Core_DMS $dms |
530 | */ |
531 | function setDMS($dms) { /* {{{ */ |
532 | $this->_dms = $dms; |
533 | } /* }}} */ |
534 | |
535 | /** |
536 | * Get dms of attribute definition |
537 | * |
538 | * @return object $dms |
539 | */ |
540 | function getDMS() { return $this->_dms; } |
541 | |
542 | /** |
543 | * Get internal id of attribute definition |
544 | * |
545 | * @return integer id |
546 | */ |
547 | function getID() { return $this->_id; } |
548 | |
549 | /** |
550 | * Get name of attribute definition |
551 | * |
552 | * @return string name |
553 | */ |
554 | function getName() { return $this->_name; } |
555 | |
556 | function setName($name) { /* {{{ */ |
557 | $db = $this->_dms->getDB(); |
558 | |
559 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `name` =".$db->qstr($name)." WHERE `id` = " . $this->_id; |
560 | $res = $db->getResult($queryStr); |
561 | if (!$res) |
562 | return false; |
563 | |
564 | $this->_name = $name; |
565 | return true; |
566 | } /* }}} */ |
567 | |
568 | /** |
569 | * Get object type of attribute definition |
570 | * |
571 | * This can be one of objtype_all, |
572 | * objtype_folder, objtype_document, or objtype_documentcontent. |
573 | * |
574 | * @return integer type |
575 | */ |
576 | function getObjType() { return $this->_objtype; } |
577 | |
578 | /** |
579 | * Set object type of attribute definition |
580 | * |
581 | * This can be one of objtype_all, |
582 | * objtype_folder, objtype_document, or objtype_documentcontent. |
583 | * |
584 | * @param integer $objtype type |
585 | * @return bool |
586 | */ |
587 | function setObjType($objtype) { /* {{{ */ |
588 | $db = $this->_dms->getDB(); |
589 | |
590 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `objtype` =".intval($objtype)." WHERE `id` = " . $this->_id; |
591 | $res = $db->getResult($queryStr); |
592 | if (!$res) |
593 | return false; |
594 | |
595 | $this->_objtype = $objtype; |
596 | return true; |
597 | } /* }}} */ |
598 | |
599 | /** |
600 | * Get type of attribute definition |
601 | * |
602 | * This can be one of type_int, type_float, type_string, type_boolean, |
603 | * type_url, type_email. |
604 | * |
605 | * @return integer type |
606 | */ |
607 | function getType() { return $this->_type; } |
608 | |
609 | /** |
610 | * Set type of attribute definition |
611 | * |
612 | * This can be one of type_int, type_float, type_string, type_boolean, |
613 | * type_url, type_email. |
614 | * |
615 | * @param integer $type type |
616 | * @return bool |
617 | */ |
618 | function setType($type) { /* {{{ */ |
619 | $db = $this->_dms->getDB(); |
620 | |
621 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `type` =".intval($type)." WHERE `id` = " . $this->_id; |
622 | $res = $db->getResult($queryStr); |
623 | if (!$res) |
624 | return false; |
625 | |
626 | $this->_type = $type; |
627 | return true; |
628 | } /* }}} */ |
629 | |
630 | /** |
631 | * Check if attribute definition allows multi values for attribute |
632 | * |
633 | * @return boolean true if attribute may have multiple values |
634 | */ |
635 | function getMultipleValues() { return $this->_multiple; } |
636 | |
637 | /** |
638 | * Set if attribute definition allows multi values for attribute |
639 | * |
640 | * @param boolean $mv true if attribute may have multiple values, otherwise |
641 | * false |
642 | * @return bool |
643 | */ |
644 | function setMultipleValues($mv) { /* {{{ */ |
645 | $db = $this->_dms->getDB(); |
646 | |
647 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `multiple` =".intval($mv)." WHERE `id` = " . $this->_id; |
648 | $res = $db->getResult($queryStr); |
649 | if (!$res) |
650 | return false; |
651 | |
652 | $this->_multiple = $mv; |
653 | return true; |
654 | } /* }}} */ |
655 | |
656 | /** |
657 | * Return minimum number of values for attributes |
658 | * |
659 | * Attributes with multiple values may be limited to a range |
660 | * of values. This functions returns the minimum number of values. |
661 | * |
662 | * @return integer minimum number of values |
663 | */ |
664 | function getMinValues() { return $this->_minvalues; } |
665 | |
666 | function setMinValues($minvalues) { /* {{{ */ |
667 | $db = $this->_dms->getDB(); |
668 | |
669 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `minvalues` =".intval($minvalues)." WHERE `id` = " . $this->_id; |
670 | $res = $db->getResult($queryStr); |
671 | if (!$res) |
672 | return false; |
673 | |
674 | $this->_minvalues = $minvalues; |
675 | return true; |
676 | } /* }}} */ |
677 | |
678 | /** |
679 | * Return maximum number of values for attributes |
680 | * |
681 | * Attributes with multiple values may be limited to a range |
682 | * of values. This functions returns the maximum number of values. |
683 | * |
684 | * @return integer maximum number of values |
685 | */ |
686 | function getMaxValues() { return $this->_maxvalues; } |
687 | |
688 | function setMaxValues($maxvalues) { /* {{{ */ |
689 | $db = $this->_dms->getDB(); |
690 | |
691 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `maxvalues` =".intval($maxvalues)." WHERE `id` = " . $this->_id; |
692 | $res = $db->getResult($queryStr); |
693 | if (!$res) |
694 | return false; |
695 | |
696 | $this->_maxvalues = $maxvalues; |
697 | return true; |
698 | } /* }}} */ |
699 | |
700 | /** |
701 | * Get the value set as saved in the database |
702 | * |
703 | * This is a string containing the list of valueѕ separated by a |
704 | * delimiter which also precedes the whole string, e.g. '|Yes|No' |
705 | * |
706 | * Use {@link SeedDMS_Core_AttributeDefinition::getValueSetAsArray()} |
707 | * for a list of values returned as an array. |
708 | * |
709 | * @return string value set |
710 | */ |
711 | function getValueSet() { /* {{{ */ |
712 | return $this->_valueset; |
713 | } /* }}} */ |
714 | |
715 | /** |
716 | * Get the separator used for the value set |
717 | * |
718 | * This is the first char of the value set string. |
719 | * |
720 | * @return string separator or an empty string if a value set is not set |
721 | */ |
722 | function getValueSetSeparator() { /* {{{ */ |
723 | if(strlen($this->_valueset) > 1) { |
724 | return $this->_valueset[0]; |
725 | } elseif($this->_multiple) { |
726 | if($this->_type == SeedDMS_Core_AttributeDefinition::type_boolean) |
727 | return ''; |
728 | else |
729 | return ','; |
730 | } else { |
731 | return ''; |
732 | } |
733 | } /* }}} */ |
734 | |
735 | /** |
736 | * Get the whole value set as an array |
737 | * |
738 | * Each element is trimmed. |
739 | * |
740 | * @return array values of value set or false if the value set has |
741 | * less than 2 chars |
742 | */ |
743 | function getValueSetAsArray() { /* {{{ */ |
744 | if(strlen($this->_valueset) > 1) |
745 | return array_map('trim', explode($this->_valueset[0], substr($this->_valueset, 1))); |
746 | else |
747 | return array(); |
748 | } /* }}} */ |
749 | |
750 | /** |
751 | * Get the n'th trimmed value of a value set |
752 | * |
753 | * @param $ind starting from 0 for the first element in the value set |
754 | * @return string n'th value of value set or false if the index is |
755 | * out of range or the value set has less than 2 chars |
756 | * @internal param int $index |
757 | */ |
758 | function getValueSetValue($ind) { /* {{{ */ |
759 | if(strlen($this->_valueset) > 1) { |
760 | $tmp = explode($this->_valueset[0], substr($this->_valueset, 1)); |
761 | if(isset($tmp[$ind])) |
762 | return trim($tmp[$ind]); |
763 | else |
764 | return false; |
765 | } else |
766 | return false; |
767 | } /* }}} */ |
768 | |
769 | /** |
770 | * Set the value set |
771 | * |
772 | * A value set is a list of values allowed for an attribute. The values |
773 | * are separated by a char which must also be the first char of the |
774 | * value set string. The method decomposes the value set, removes all |
775 | * leading and trailing white space from the elements and recombines them |
776 | * into a string. |
777 | * |
778 | * @param string $valueset |
779 | * @return boolean true if value set could be set, otherwise false |
780 | */ |
781 | function setValueSet($valueset) { /* {{{ */ |
782 | /* |
783 | $tmp = array(); |
784 | foreach($valueset as $value) { |
785 | $tmp[] = str_replace('"', '""', $value); |
786 | } |
787 | $valuesetstr = implode(",", $tmp); |
788 | */ |
789 | $valueset = trim($valueset); |
790 | if($valueset) { |
791 | $valuesetarr = array_map('trim', explode($valueset[0], substr($valueset, 1))); |
792 | $valuesetstr = $valueset[0].implode($valueset[0], $valuesetarr); |
793 | } else { |
794 | $valuesetstr = ''; |
795 | } |
796 | |
797 | $db = $this->_dms->getDB(); |
798 | |
799 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `valueset` =".$db->qstr($valuesetstr)." WHERE `id` = " . $this->_id; |
800 | $res = $db->getResult($queryStr); |
801 | if (!$res) |
802 | return false; |
803 | |
804 | $this->_valueset = $valuesetstr; |
805 | $this->_separator = substr($valuesetstr, 0, 1); |
806 | return true; |
807 | } /* }}} */ |
808 | |
809 | /** |
810 | * Get the regular expression as saved in the database |
811 | * |
812 | * @return string regular expression |
813 | */ |
814 | function getRegex() { /* {{{ */ |
815 | return $this->_regex; |
816 | } /* }}} */ |
817 | |
818 | /** |
819 | * Set the regular expression |
820 | * |
821 | * A value of the attribute must match this regular expression. |
822 | * |
823 | * The methods checks if the regular expression is valid by running |
824 | * preg_match() on an empty string and see if it fails. Trying to set |
825 | * an invalid regular expression will not overwrite the current |
826 | * regular expression. |
827 | * |
828 | * All leading and trailing spaces of $regex will be removed. |
829 | * |
830 | * @param string $regex |
831 | * @return boolean true if regex could be set or is invalid, otherwise false |
832 | */ |
833 | function setRegex($regex) { /* {{{ */ |
834 | $db = $this->_dms->getDB(); |
835 | |
836 | $regex = trim($regex); |
837 | if($regex && @preg_match($regex, '') === false) |
838 | return false; |
839 | |
840 | $queryStr = "UPDATE `tblAttributeDefinitions` SET `regex` =".$db->qstr($regex)." WHERE `id` = " . $this->_id; |
841 | $res = $db->getResult($queryStr); |
842 | if (!$res) |
843 | return false; |
844 | |
845 | $this->_regex = $regex; |
846 | return true; |
847 | } /* }}} */ |
848 | |
849 | /** |
850 | * Check if the attribute definition is used |
851 | * |
852 | * Checks all documents, folders and document content whether at least |
853 | * one of them referenceѕ this attribute definition |
854 | * |
855 | * @return boolean true if attribute definition is used, otherwise false |
856 | */ |
857 | function isUsed() { /* {{{ */ |
858 | $db = $this->_dms->getDB(); |
859 | |
860 | $queryStr = "SELECT * FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id; |
861 | $resArr = $db->getResultArray($queryStr); |
862 | if (is_array($resArr) && count($resArr) == 0) { |
863 | $queryStr = "SELECT * FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id; |
864 | $resArr = $db->getResultArray($queryStr); |
865 | if (is_array($resArr) && count($resArr) == 0) { |
866 | $queryStr = "SELECT * FROM `tblDocumentContentAttributes` WHERE `attrdef`=".$this->_id; |
867 | $resArr = $db->getResultArray($queryStr); |
868 | if (is_array($resArr) && count($resArr) == 0) { |
869 | |
870 | return false; |
871 | } |
872 | } |
873 | } |
874 | return true; |
875 | } /* }}} */ |
876 | |
877 | /** |
878 | * Parse a given value according to attribute definition |
879 | * |
880 | * The return value is always an array, even if the attribute is a single |
881 | * value attribute. If the type of attribute is any of document, folder, user, |
882 | * or group then this method will fetch each object from the database and |
883 | * return an array of SeedDMS_Core_Document, SeedDMS_Core_Folder, etc. |
884 | * |
885 | * @param $value string |
886 | * @return array|bool |
887 | */ |
888 | function parseValue(string $value) { /* {{{ */ |
889 | if($this->getMultipleValues()) { |
890 | /* If the value doesn't start with the separator used in the value set, |
891 | * then assume that the value was not saved with a leading separator. |
892 | * This can happen, if the value was previously a single value from |
893 | * the value set and later turned into a multi value attribute. |
894 | */ |
895 | $sep = substr($value, 0, 1); |
896 | $vsep = $this->getValueSetSeparator(); |
897 | if($sep == $vsep) |
898 | $values = explode($sep, substr($value, 1)); |
899 | else |
900 | $values = array($value); |
901 | } else { |
902 | $values = array($value); |
903 | } |
904 | |
905 | switch((string) $this->getType()) { |
906 | case self::type_document: |
907 | foreach($values as $value) { |
908 | if($u = $this->_dms->getDocument((int) $value)) |
909 | $tmp[] = $u->getName(); |
910 | else |
911 | $tmp[] = '???'; |
912 | } |
913 | $values = $tmp; |
914 | break; |
915 | case self::type_folder: |
916 | foreach($values as $value) { |
917 | if($u = $this->_dms->getFolder((int) $value)) |
918 | $tmp[] = $u->getName(); |
919 | else |
920 | $tmp[] = '???'; |
921 | } |
922 | $values = $tmp; |
923 | break; |
924 | case self::type_user: |
925 | foreach($values as $value) { |
926 | if($u = $this->_dms->getUser((int) $value)) |
927 | $tmp[] = $u->getLogin(); |
928 | else |
929 | $tmp[] = '???'; |
930 | } |
931 | $values = $tmp; |
932 | break; |
933 | case self::type_group: |
934 | foreach($values as $value) { |
935 | if($u = $this->_dms->getGroup((int) $value)) |
936 | $tmp[] = $u->getName(); |
937 | else |
938 | $tmp[] = '???'; |
939 | } |
940 | $values = $tmp; |
941 | break; |
942 | } |
943 | return $values; |
944 | } /* }}} */ |
945 | |
946 | /** |
947 | * Return a list of documents, folders, document contents where this |
948 | * attribute definition is used |
949 | * |
950 | * @param integer $limit return not more the n objects of each type |
951 | * @return array|bool |
952 | */ |
953 | function getStatistics($limit=0) { /* {{{ */ |
954 | $db = $this->_dms->getDB(); |
955 | |
956 | $result = array('docs'=>array(), 'folders'=>array(), 'contents'=>array()); |
957 | if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || |
958 | $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_document) { |
959 | $queryStr = "SELECT * FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id; |
960 | if($limit) |
961 | $queryStr .= " limit ".(int) $limit; |
962 | $resArr = $db->getResultArray($queryStr); |
963 | if($resArr) { |
964 | foreach($resArr as $rec) { |
965 | if($doc = $this->_dms->getDocument($rec['document'])) { |
966 | $result['docs'][] = $doc; |
967 | } |
968 | } |
969 | } |
970 | $valueset = $this->getValueSetAsArray(); |
971 | $possiblevalues = array(); |
972 | foreach($valueset as $value) { |
973 | $possiblevalues[md5($value)] = array('value'=>$value, 'c'=>0); |
974 | } |
975 | $queryStr = "SELECT count(*) c, `value` FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id." GROUP BY `value` ORDER BY c DESC"; |
976 | $resArr = $db->getResultArray($queryStr); |
977 | if($resArr) { |
978 | foreach($resArr as $row) { |
979 | $tmpattr = new SeedDMS_Core_Attribute(0, null, $this, $row['value']); |
980 | foreach($tmpattr->getValueAsArray() as $value) { |
981 | if(isset($possiblevalues[md5($value)])) { |
982 | $possiblevalues[md5($value)]['c'] += $row['c']; |
983 | } else { |
984 | $possiblevalues[md5($value)] = array('value'=>$value, 'c'=>$row['c']); |
985 | } |
986 | } |
987 | } |
988 | $result['frequencies']['document'] = $possiblevalues; |
989 | } |
990 | } |
991 | |
992 | if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || |
993 | $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_folder) { |
994 | $queryStr = "SELECT * FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id; |
995 | if($limit) |
996 | $queryStr .= " limit ".(int) $limit; |
997 | $resArr = $db->getResultArray($queryStr); |
998 | if($resArr) { |
999 | foreach($resArr as $rec) { |
1000 | if($folder = $this->_dms->getFolder($rec['folder'])) { |
1001 | $result['folders'][] = $folder; |
1002 | } |
1003 | } |
1004 | } |
1005 | $valueset = $this->getValueSetAsArray(); |
1006 | $possiblevalues = array(); |
1007 | foreach($valueset as $value) { |
1008 | $possiblevalues[md5($value)] = array('value'=>$value, 'c'=>0); |
1009 | } |
1010 | $queryStr = "SELECT count(*) c, `value` FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id." GROUP BY `value` ORDER BY c DESC"; |
1011 | $resArr = $db->getResultArray($queryStr); |
1012 | if($resArr) { |
1013 | foreach($resArr as $row) { |
1014 | $tmpattr = new SeedDMS_Core_Attribute(0, null, $this, $row['value']); |
1015 | foreach($tmpattr->getValueAsArray() as $value) { |
1016 | if(isset($possiblevalues[md5($value)])) { |
1017 | $possiblevalues[md5($value)]['c'] += $row['c']; |
1018 | } else { |
1019 | $possiblevalues[md5($value)] = array('value'=>$value, 'c'=>$row['c']); |
1020 | } |
1021 | } |
1022 | } |
1023 | $result['frequencies']['folder'] = $possiblevalues; |
1024 | } |
1025 | } |
1026 | |
1027 | if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || |
1028 | $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_documentcontent) { |
1029 | $queryStr = "SELECT * FROM `tblDocumentContentAttributes` WHERE `attrdef`=".$this->_id; |
1030 | if($limit) |
1031 | $queryStr .= " limit ".(int) $limit; |
1032 | $resArr = $db->getResultArray($queryStr); |
1033 | if($resArr) { |
1034 | foreach($resArr as $rec) { |
1035 | if($content = $this->_dms->getDocumentContent($rec['content'])) { |
1036 | $result['contents'][] = $content; |
1037 | } |
1038 | } |
1039 | } |
1040 | $valueset = $this->getValueSetAsArray(); |
1041 | $possiblevalues = array(); |
1042 | foreach($valueset as $value) { |
1043 | $possiblevalues[md5($value)] = array('value'=>$value, 'c'=>0); |
1044 | } |
1045 | $queryStr = "SELECT count(*) c, `value` FROM `tblDocumentContentAttributes` WHERE `attrdef`=".$this->_id." GROUP BY `value` ORDER BY c DESC"; |
1046 | $resArr = $db->getResultArray($queryStr); |
1047 | if($resArr) { |
1048 | foreach($resArr as $row) { |
1049 | $tmpattr = new SeedDMS_Core_Attribute(0, null, $this, $row['value']); |
1050 | foreach($tmpattr->getValueAsArray() as $value) { |
1051 | if(isset($possiblevalues[md5($value)])) { |
1052 | $possiblevalues[md5($value)]['c'] += $row['c']; |
1053 | } else { |
1054 | $possiblevalues[md5($value)] = array('value'=>$value, 'c'=>$row['c']); |
1055 | } |
1056 | } |
1057 | } |
1058 | $result['frequencies']['content'] = $possiblevalues; |
1059 | } |
1060 | } |
1061 | |
1062 | return $result; |
1063 | } /* }}} */ |
1064 | |
1065 | /** |
1066 | * Remove the attribute definition |
1067 | * Removal is only executed when the definition is not used anymore. |
1068 | * |
1069 | * @return boolean true on success or false in case of an error |
1070 | */ |
1071 | function remove() { /* {{{ */ |
1072 | $db = $this->_dms->getDB(); |
1073 | |
1074 | if($this->isUsed()) |
1075 | return false; |
1076 | |
1077 | // Delete user itself |
1078 | $queryStr = "DELETE FROM `tblAttributeDefinitions` WHERE `id` = " . $this->_id; |
1079 | if (!$db->getResult($queryStr)) return false; |
1080 | |
1081 | return true; |
1082 | } /* }}} */ |
1083 | |
1084 | /** |
1085 | * Get all documents and folders by a given attribute value |
1086 | * |
1087 | * @param string $attrvalue value of attribute |
1088 | * @param integer $limit limit number of documents/folders |
1089 | * @return array array containing list of documents and folders |
1090 | */ |
1091 | public function getObjects($attrvalue, $limit=0, $op=O_EQ) { /* {{{ */ |
1092 | $db = $this->_dms->getDB(); |
1093 | |
1094 | $result = array('docs'=>array(), 'folders'=>array(), 'contents'=>array()); |
1095 | if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || |
1096 | $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_document) { |
1097 | $queryStr = "SELECT * FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id; |
1098 | if($attrvalue != null) { |
1099 | $queryStr .= " AND "; |
1100 | if($this->getMultipleValues()) { |
1101 | $sep = $this->getValueSetSeparator(); |
1102 | $queryStr .= "(`value` like ".$db->qstr($sep.$attrvalue.'%')." OR `value` like ".$db->qstr('%'.$sep.$attrvalue.$sep.'%')." OR `value` like ".$db->qstr('%'.$sep.$attrvalue).")"; |
1103 | } else { |
1104 | $queryStr .= "`value`".$op.$db->qstr($attrvalue); |
1105 | } |
1106 | } |
1107 | if($limit) |
1108 | $queryStr .= " limit ".(int) $limit; |
1109 | $resArr = $db->getResultArray($queryStr); |
1110 | if($resArr) { |
1111 | foreach($resArr as $rec) { |
1112 | if($doc = $this->_dms->getDocument($rec['document'])) { |
1113 | $result['docs'][] = $doc; |
1114 | } |
1115 | } |
1116 | } |
1117 | } |
1118 | |
1119 | if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || |
1120 | $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_folder) { |
1121 | $queryStr = "SELECT * FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id." AND "; |
1122 | if($this->getMultipleValues()) { |
1123 | $sep = $this->getValueSetSeparator(); |
1124 | $queryStr .= "(`value` like ".$db->qstr($sep.$attrvalue.'%')." OR `value` like ".$db->qstr('%'.$sep.$attrvalue.$sep.'%')." OR `value` like ".$db->qstr('%'.$sep.$attrvalue).")"; |
1125 | } else { |
1126 | $queryStr .= "`value`=".$db->qstr($attrvalue); |
1127 | } |
1128 | if($limit) |
1129 | $queryStr .= " limit ".(int) $limit; |
1130 | $resArr = $db->getResultArray($queryStr); |
1131 | if($resArr) { |
1132 | foreach($resArr as $rec) { |
1133 | if($folder = $this->_dms->getFolder($rec['folder'])) { |
1134 | $result['folders'][] = $folder; |
1135 | } |
1136 | } |
1137 | } |
1138 | } |
1139 | |
1140 | return $result; |
1141 | } /* }}} */ |
1142 | |
1143 | /** |
1144 | * Remove a given attribute value from all documents, versions and folders |
1145 | * |
1146 | * @param string $attrvalue value of attribute |
1147 | * @return array array containing list of documents and folders |
1148 | */ |
1149 | public function removeValue($attrvalue) { /* {{{ */ |
1150 | $db = $this->_dms->getDB(); |
1151 | |
1152 | foreach(array('document', 'documentcontent', 'folder') as $type) { |
1153 | if($type == 'document') { |
1154 | $tablename = "tblDocumentAttributes"; |
1155 | $objtype = SeedDMS_Core_AttributeDefinition::objtype_document; |
1156 | } elseif($type == 'documentcontent') { |
1157 | $tablename = "tblDocumentContentAttributes"; |
1158 | $objtype = SeedDMS_Core_AttributeDefinition::objtype_documentcontent; |
1159 | } elseif($type == 'folder') { |
1160 | $tablename = "tblFolderAttributes"; |
1161 | $objtype = SeedDMS_Core_AttributeDefinition::objtype_folder; |
1162 | } |
1163 | if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || $objtype) { |
1164 | $queryStr = "SELECT * FROM `".$tablename."` WHERE `attrdef`=".$this->_id." AND "; |
1165 | if($this->getMultipleValues()) { |
1166 | $sep = $this->getValueSetSeparator(); |
1167 | $queryStr .= "(`value` like ".$db->qstr($sep.$attrvalue.'%')." OR `value` like ".$db->qstr('%'.$sep.$attrvalue.$sep.'%')." OR `value` like ".$db->qstr('%'.$sep.$attrvalue).")"; |
1168 | } else { |
1169 | $queryStr .= "`value`=".$db->qstr($attrvalue); |
1170 | } |
1171 | |
1172 | $resArr = $db->getResultArray($queryStr); |
1173 | if($resArr) { |
1174 | $db->startTransaction(); |
1175 | foreach($resArr as $rec) { |
1176 | if($rec['value'] == $attrvalue) { |
1177 | $queryStr = "DELETE FROM `".$tablename."` WHERE `id`=".$rec['id']; |
1178 | } else { |
1179 | if($this->getMultipleValues()) { |
1180 | $sep = substr($rec['value'], 0, 1); |
1181 | $vsep = $this->getValueSetSeparator(); |
1182 | if($sep == $vsep) |
1183 | $values = explode($sep, substr($rec['value'], 1)); |
1184 | else |
1185 | $values = array($rec['value']); |
1186 | if (($key = array_search($attrvalue, $values)) !== false) { |
1187 | unset($values[$key]); |
1188 | } |
1189 | if($values) { |
1190 | $queryStr = "UPDATE `".$tablename."` SET `value`=".$db->qstr($sep.implode($sep, $values))." WHERE `id`=".$rec['id']; |
1191 | } else { |
1192 | $queryStr = "DELETE FROM `".$tablename."` WHERE `id`=".$rec['id']; |
1193 | } |
1194 | } else { |
1195 | } |
1196 | } |
1197 | if (!$db->getResult($queryStr)) { |
1198 | $db->rollbackTransaction(); |
1199 | return false; |
1200 | } |
1201 | } |
1202 | $db->commitTransaction(); |
1203 | } |
1204 | } |
1205 | } |
1206 | return true; |
1207 | } /* }}} */ |
1208 | |
1209 | /** |
1210 | * Validate value against attribute definition |
1211 | * |
1212 | * This function checks if the given value fits the attribute |
1213 | * definition. |
1214 | * If the validation fails the validation error will be set which |
1215 | * can be requested by SeedDMS_Core_Attribute::getValidationError() |
1216 | * Set $new to true if the value to be checked isn't saved to the database |
1217 | * already. It will just be passed to the callback onAttributeValidate where |
1218 | * it could be used to, e.g. check if a value is unique once it is saved to |
1219 | * the database. $object is set to a folder, document or documentcontent |
1220 | * if the attribute belongs to such an object. This will be null, if a |
1221 | * new object is created. |
1222 | * |
1223 | * @param string|array $attrvalue attribute value |
1224 | * @param object $object set if the current attribute is saved for this object |
1225 | * (this will only be passed to the onAttributeValidate callback) |
1226 | * @param boolean $new set to true if the value is new value and not taken from |
1227 | * an existing attribute |
1228 | * (this will only be passed to the onAttributeValidate callback) |
1229 | * @return boolean true if validation succeeds, otherwise false |
1230 | */ |
1231 | function validate($attrvalue, $object=null, $new=false) { /* {{{ */ |
1232 | /* Check if 'onAttributeValidate' callback is set */ |
1233 | if(isset($this->_dms->callbacks['onAttributeValidate'])) { |
1234 | foreach($this->_dms->callbacks['onAttributeValidate'] as $callback) { |
1235 | $ret = call_user_func($callback[0], $callback[1], $this, $attrvalue, $object, $new); |
1236 | if(is_bool($ret)) |
1237 | return $ret; |
1238 | } |
1239 | } |
1240 | |
1241 | /* Turn $attrvalue into an array of values. Checks if $attrvalue starts |
1242 | * with a separator char as set in the value set and use it to explode |
1243 | * the $attrvalue. If the separator doesn't match or this attribute |
1244 | * definition doesn't have a value set, then just create a one element |
1245 | * array. if $attrvalue is empty, then create an empty array. |
1246 | */ |
1247 | if($this->getMultipleValues()) { |
1248 | if(is_string($attrvalue) && $attrvalue) { |
1249 | $sep = $attrvalue[0]; |
1250 | $vsep = $this->getValueSetSeparator(); |
1251 | if($sep == $vsep) |
1252 | $values = explode($attrvalue[0], substr($attrvalue, 1)); |
1253 | else |
1254 | $values = array($attrvalue); |
1255 | } elseif(is_array($attrvalue)) { |
1256 | $values = $attrvalue; |
1257 | } elseif(is_string($attrvalue) && !$attrvalue) { |
1258 | $values = array(); |
1259 | } else |
1260 | $values = array($attrvalue); |
1261 | } elseif($attrvalue !== null) { |
1262 | $values = array($attrvalue); |
1263 | } else { |
1264 | $values = array(); |
1265 | } |
1266 | |
1267 | /* Check if attribute value has at least the minimum number of values */ |
1268 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_none; |
1269 | if($this->getMinValues() > count($values)) { |
1270 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_min_values; |
1271 | return false; |
1272 | } |
1273 | /* Check if attribute value has not more than maximum number of values */ |
1274 | if($this->getMaxValues() && $this->getMaxValues() < count($values)) { |
1275 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_max_values; |
1276 | return false; |
1277 | } |
1278 | |
1279 | $success = true; |
1280 | switch((string) $this->getType()) { |
1281 | case self::type_boolean: |
1282 | foreach($values as $value) { |
1283 | $success = $success && (preg_match('/^[01]$/', $value) ? true : false); |
1284 | } |
1285 | if(!$success) |
1286 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_boolean; |
1287 | break; |
1288 | case self::type_int: |
1289 | foreach($values as $value) { |
1290 | $success = $success && (preg_match('/^[0-9]*$/', $value) ? true : false); |
1291 | } |
1292 | if(!$success) |
1293 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_int; |
1294 | break; |
1295 | case self::type_date: |
1296 | foreach($values as $value) { |
1297 | $d = explode('-', $value, 3); |
1298 | $success = $success && (count($d) == 3) && checkdate((int) $d[1], (int) $d[2], (int) $d[0]); |
1299 | } |
1300 | if(!$success) |
1301 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_date; |
1302 | break; |
1303 | case self::type_float: |
1304 | foreach($values as $value) { |
1305 | $success = $success && is_numeric($value); |
1306 | } |
1307 | if(!$success) |
1308 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_float; |
1309 | break; |
1310 | case self::type_string: |
1311 | if(trim($this->getRegex()) != '') { |
1312 | foreach($values as $value) { |
1313 | $success = $success && (preg_match($this->getRegex(), $value) ? true : false); |
1314 | } |
1315 | } |
1316 | if(!$success) |
1317 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_regex; |
1318 | break; |
1319 | case self::type_email: |
1320 | foreach($values as $value) { |
1321 | //$success &= filter_var($value, FILTER_VALIDATE_EMAIL) ? true : false; |
1322 | $success = $success && (preg_match('/^[a-z0-9._-]+@[a-z0-9-]{2,63}(\.[a-z0-9-]{2,63})*\.[a-z]{2,63}$/i', $value) ? true : false); |
1323 | } |
1324 | if(!$success) |
1325 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_email; |
1326 | break; |
1327 | case self::type_url: |
1328 | foreach($values as $value) { |
1329 | $success = $success && (preg_match('/^http(s)?:\/\/[a-z0-9_-]+(\.[a-z0-9-]{2,63})*(:[0-9]+)?(\/.*)?$/i', $value) ? true : false); |
1330 | } |
1331 | if(!$success) |
1332 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_url; |
1333 | break; |
1334 | case self::type_document: |
1335 | foreach($values as $value) { |
1336 | $success = true; |
1337 | if(!$this->_dms->getDocument((int) $value)) |
1338 | $success = false; |
1339 | } |
1340 | if(!$success) |
1341 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_document; |
1342 | break; |
1343 | case self::type_folder: |
1344 | foreach($values as $value) { |
1345 | $success = true; |
1346 | if(!$this->_dms->getFolder((int) $value)) |
1347 | $success = false; |
1348 | } |
1349 | if(!$success) |
1350 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_folder; |
1351 | break; |
1352 | case self::type_user: |
1353 | foreach($values as $value) { |
1354 | $success = true; |
1355 | if(!$this->_dms->getUser((int) $value)) |
1356 | $success = false; |
1357 | } |
1358 | if(!$success) |
1359 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_user; |
1360 | break; |
1361 | case self::type_group: |
1362 | foreach($values as $value) { |
1363 | $success = true; |
1364 | if(!$this->_dms->getGroup((int) $value)) |
1365 | $success = false; |
1366 | } |
1367 | if(!$success) |
1368 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_group; |
1369 | break; |
1370 | } |
1371 | |
1372 | if(!$success) |
1373 | return $success; |
1374 | |
1375 | /* Check if value is in value set */ |
1376 | if($valueset = $this->getValueSetAsArray()) { |
1377 | /* An empty value cannot be the value set */ |
1378 | if(!$values) { |
1379 | $success = false; |
1380 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_valueset; |
1381 | } else { |
1382 | foreach($values as $value) { |
1383 | if(!in_array($value, $valueset)) { |
1384 | $success = false; |
1385 | $this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_valueset; |
1386 | } |
1387 | } |
1388 | } |
1389 | } |
1390 | |
1391 | return $success; |
1392 | |
1393 | } /* }}} */ |
1394 | |
1395 | /** |
1396 | * Get validation error from last validation |
1397 | * |
1398 | * @return integer error code |
1399 | */ |
1400 | function getValidationError() { return $this->_validation_error; } |
1401 | |
1402 | } /* }}} */ |