Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
70.69% covered (warning)
70.69%
82 / 116
50.00% covered (danger)
50.00%
6 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
SeedDMS_Core_Object
70.69% covered (warning)
70.69%
82 / 116
50.00% covered (danger)
50.00%
6 / 12
154.70
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 isType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDMS
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDMS
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getID
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAttributes
65.22% covered (warning)
65.22%
15 / 23
0.00% covered (danger)
0.00%
0 / 1
12.41
 getAttribute
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
3.58
 getAttributeValue
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 getAttributeValueAsArray
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getAttributeValueAsString
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 setAttributeValue
73.81% covered (warning)
73.81%
31 / 42
0.00% covered (danger)
0.00%
0 / 1
30.70
 removeAttribute
70.83% covered (warning)
70.83%
17 / 24
0.00% covered (danger)
0.00%
0 / 1
14.00
1<?php
2declare(strict_types=1);
3
4/**
5 * Implementation of an generic object in the document management system
6 *
7 * @category   DMS
8 * @package    SeedDMS_Core
9 * @license    GPL2
10 * @author     Uwe Steinmann <uwe@steinmann.cx>
11 * @copyright  Copyright (C) 2010-2024 Uwe Steinmann
12 * @version    Release: @package_version@
13 */
14
15
16/**
17 * Class to represent a generic object in the document management system
18 *
19 * This is the base class for generic objects in SeedDMS.
20 *
21 * @category   DMS
22 * @package    SeedDMS_Core
23 * @author     Uwe Steinmann <uwe@steinmann.cx>
24 * @copyright  Copyright (C) 2010-2024 Uwe Steinmann
25 * @version    Release: @package_version@
26 */
27class SeedDMS_Core_Object { /* {{{ */
28    /**
29     * @var integer unique id of object
30     */
31    protected $_id;
32
33    /**
34     * @var array list of attributes
35     */
36    protected $_attributes;
37
38    /**
39     * @var SeedDMS_Core_DMS back reference to document management system
40     */
41    public $_dms;
42
43    /**
44     * SeedDMS_Core_Object constructor.
45     * @param $id
46     */
47    function __construct($id) { /* {{{ */
48        $this->_id = $id;
49        $this->_dms = null;
50    } /* }}} */
51
52    /**
53     * Check if this object is of a given type.
54     *
55     * This method must be implemened in the child class
56     *
57     * @param string $type type of object
58     */
59    public function isType($type) {return false;}
60
61    /**
62     * Set dms this object belongs to.
63     *
64     * Each object needs a reference to the dms it belongs to. It will be
65     * set when the object is created.
66     * The dms has a references to the currently logged in user
67     * and the database connection.
68     *
69     * @param SeedDMS_Core_DMS $dms reference to dms
70     */
71    public function setDMS($dms) { /* {{{ */
72        $this->_dms = $dms;
73    } /* }}} */
74
75    /**
76     * Returns instance of dms
77     *
78     * @return SeedDMS_Core_DMS
79     */
80    public function getDMS() { /* {{{ */
81        return $this->_dms;
82    } /* }}} */
83
84    /**
85     * Returns the internal id of the object
86     *
87     * @return integer id of document/folder
88     */
89    public function getID() { return $this->_id; }
90
91    /**
92     * Returns all attributes set for the object
93     *
94     * @return array|bool
95     */
96    public function getAttributes() { /* {{{ */
97        if (!$this->_attributes) {
98            $db = $this->_dms->getDB();
99
100            switch(get_class($this)) {
101                case $this->_dms->getClassname('document'):
102                    $queryStr = "SELECT a.* FROM `tblDocumentAttributes` a LEFT JOIN `tblAttributeDefinitions` b ON a.`attrdef`=b.`id` WHERE a.`document` = " . $this->_id." ORDER BY b.`name`";
103                    break;
104                case $this->_dms->getClassname('documentcontent'):
105                    $queryStr = "SELECT a.* FROM `tblDocumentContentAttributes` a LEFT JOIN `tblAttributeDefinitions` b ON a.`attrdef`=b.`id` WHERE a.`content` = " . $this->_id." ORDER BY b.`name`";
106                    break;
107                case $this->_dms->getClassname('folder'):
108                    $queryStr = "SELECT a.* FROM `tblFolderAttributes` a LEFT JOIN `tblAttributeDefinitions` b ON a.`attrdef`=b.`id` WHERE a.`folder` = " . $this->_id." ORDER BY b.`name`";
109                    break;
110                default:
111                    return false;
112            }
113            $resArr = $db->getResultArray($queryStr);
114            if (is_bool($resArr) && !$resArr) return false;
115
116            $this->_attributes = array();
117
118            foreach ($resArr as $row) {
119                $attrdef = $this->_dms->getAttributeDefinition($row['attrdef']);
120                $value = $attrdef->parseValue($row['value']);
121                $attr = new SeedDMS_Core_Attribute($row["id"], $this, $attrdef, $value);
122                $attr->setDMS($this->_dms);
123                $this->_attributes[$attrdef->getId()] = $attr;
124            }
125        }
126        return $this->_attributes;
127
128    } /* }}} */
129
130    /**
131     * Returns an attribute of the object for the given attribute definition
132     *
133     * @param SeedDMS_Core_AttributeDefinition $attrdef
134     * @return array|string value of attritbute or false. The value is an array
135     * if the attribute is defined as multi value
136     */
137    public function getAttribute($attrdef) { /* {{{ */
138        if (!$this->_attributes) {
139            $this->getAttributes();
140        }
141
142        if (isset($this->_attributes[$attrdef->getId()])) {
143            return $this->_attributes[$attrdef->getId()];
144        } else {
145            return false;
146        }
147
148    } /* }}} */
149
150    /**
151     * Returns an attribute value of the object for the given attribute definition
152     *
153     * @param SeedDMS_Core_AttributeDefinition $attrdef
154     * @return array|string value of attritbute or false. The value is an array
155     * if the attribute is defined as multi value
156     */
157    public function getAttributeValue($attrdef) { /* {{{ */
158        if (!$this->_attributes) {
159            $this->getAttributes();
160        }
161
162        if (isset($this->_attributes[$attrdef->getId()])) {
163            $value = $this->_attributes[$attrdef->getId()]->getValue();
164            return $value;
165            if($attrdef->getMultipleValues()) {
166                $sep = substr($value, 0, 1);
167                $vsep = $attrdef->getValueSetSeparator();
168                /* If the value doesn't start with the separator used in the value set,
169                 * then assume that the value was not saved with a leading separator.
170                 * This can happen, if the value was previously a single value from
171                 * the value set and later turned into a multi value attribute.
172                 */
173                if($sep == $vsep)
174                    return(explode($sep, substr($value, 1)));
175                else
176                    return(array($value));
177            } else {
178                return $this->_attributes[$attrdef->getId()]->getParsedValue();
179            }
180        } else
181            return false;
182
183    } /* }}} */
184
185    /**
186     * Returns an attribute value of the object for the given attribute definition
187     *
188     * This is a short cut for getAttribute($attrdef)->getValueAsArray() but
189     * first checks if the object has an attribute for the given attribute
190     * definition.
191     *
192     * @param SeedDMS_Core_AttributeDefinition $attrdef
193     * @return array|bool
194     * even if the attribute is not defined as multi value
195     */
196    public function getAttributeValueAsArray($attrdef) { /* {{{ */
197        if (!$this->_attributes) {
198            $this->getAttributes();
199        }
200
201        if (isset($this->_attributes[$attrdef->getId()])) {
202            return $this->_attributes[$attrdef->getId()]->getValueAsArray();
203        } else
204            return false;
205
206    } /* }}} */
207
208    /**
209     * Returns an attribute value of the object for the given attribute definition
210     *
211     * This is a short cut for getAttribute($attrdef)->getValueAsString() but
212     * first checks if the object has an attribute for the given attribute
213     * definition.
214     *
215     * @param SeedDMS_Core_AttributeDefinition $attrdef
216     * @return string value of attritbute or false. The value is always a string
217     * even if the attribute is defined as multi value
218     */
219    public function getAttributeValueAsString($attrdef) { /* {{{ */
220        if (!$this->_attributes) {
221            $this->getAttributes();
222        }
223
224        if (isset($this->_attributes[$attrdef->getId()])) {
225            return $this->_attributes[$attrdef->getId()]->getValue();
226        } else
227            return false;
228
229    } /* }}} */
230
231    /**
232     * Set an attribute of the object for the given attribute definition
233     *
234     * @param SeedDMS_Core_AttributeDefinition $attrdef definition of attribute
235     * @param array|string $value value of attribute, for multiple values this
236     * must be an array
237     * @return boolean true if operation was successful, otherwise false
238     */
239    public function setAttributeValue($attrdef, $value) { /* {{{ */
240        $db = $this->_dms->getDB();
241        if (!$this->_attributes) {
242            $this->getAttributes();
243        }
244
245        /* Check if objtype of attribute matches object */
246        if($attrdef->getObjType() != SeedDMS_Core_AttributeDefinition::objtype_all) {
247            if($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_document && !$this->isType('document'))
248                return false;
249            if($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_folder && !$this->isType('folder'))
250                return false;
251            if($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_documentcontent && !$this->isType('documentcontent'))
252                return false;
253        }
254
255        /* Handle the case if an attribute is not set already */
256        if(!isset($this->_attributes[$attrdef->getId()])) {
257            switch($attrdef->getType()) {
258            case SeedDMS_Core_AttributeDefinition::type_boolean:
259                $value = ($value === true || $value != '' || $value == 1) ? 1 : 0;
260                break;
261            }
262
263            $dbvalue = $attrdef->createValue($value);
264            switch(get_class($this)) {
265                case $this->_dms->getClassname('document'):
266                    $tablename = 'tblDocumentAttributes';
267                    $queryStr = "INSERT INTO `tblDocumentAttributes` (`document`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($dbvalue).")";
268                    break;
269                case $this->_dms->getClassname('documentcontent'):
270                    $tablename = 'tblDocumentContentAttributes';
271                    $queryStr = "INSERT INTO `tblDocumentContentAttributes` (`content`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($dbvalue).")";
272                    break;
273                case $this->_dms->getClassname('folder'):
274                    $tablename = 'tblFolderAttributes';
275                    $queryStr = "INSERT INTO `tblFolderAttributes` (`folder`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($dbvalue).")";
276                    break;
277                default:
278                    return false;
279            }
280            $res = $db->getResult($queryStr);
281            if (!$res)
282                return false;
283
284            $attr = new SeedDMS_Core_Attribute($db->getInsertID($tablename), $this, $attrdef, $value);
285            $attr->setDMS($this->_dms);
286            $this->_attributes[$attrdef->getId()] = $attr;
287
288            /* Check if 'onPostAddAttribute' callback is set */
289            if(isset($this->_dms->callbacks['onPostAddAttribute'])) {
290                foreach($this->_dms->callbacks['onPostAddAttribute'] as $callback) {
291                    if(!call_user_func($callback[0], $callback[1], $this, $attrdef, $value)) {
292                    }
293                }
294            }
295
296            return true;
297        }
298
299        /* The attribute already exists. setValue() will either update or delete it. */
300        $this->_attributes[$attrdef->getId()]->setValue($value);
301
302        return true;
303    } /* }}} */
304
305    /**
306     * Remove an attribute of the object for the given attribute definition
307     *
308     * FIXME: shouldn't this rather be setAttributeValue() with an empty value?
309     *
310     * @param SeedDMS_Core_AttributeDefinition $attrdef
311     * @return boolean true if operation was successful, otherwise false
312     */
313    public function removeAttribute($attrdef) { /* {{{ */
314        $db = $this->_dms->getDB();
315        if (!$this->_attributes) {
316            $this->getAttributes();
317        }
318        if(isset($this->_attributes[$attrdef->getId()])) {
319            $oldvalue = $this->_attributes[$attrdef->getId()]->getValue();
320            switch(get_class($this)) {
321                case $this->_dms->getClassname('document'):
322                    $queryStr = "DELETE FROM `tblDocumentAttributes` WHERE `document`=".$this->_id." AND `attrdef`=".$attrdef->getId();
323                    break;
324                case $this->_dms->getClassname('documentcontent'):
325                    $queryStr = "DELETE FROM `tblDocumentContentAttributes` WHERE `content`=".$this->_id." AND `attrdef`=".$attrdef->getId();
326                    break;
327                case $this->_dms->getClassname('folder'):
328                    $queryStr = "DELETE FROM `tblFolderAttributes` WHERE `folder`=".$this->_id." AND `attrdef`=".$attrdef->getId();
329                    break;
330                default:
331                    return false;
332            }
333            $res = $db->getResult($queryStr);
334            if (!$res)
335                return false;
336
337            /* Check if 'onPostRemoveAttribute' callback is set */
338            if(isset($this->_dms->callbacks['onPostRemoveAttribute'])) {
339                foreach($this->_dms->callbacks['onPostRemoveAttribute'] as $callback) {
340                    if(!call_user_func($callback[0], $callback[1], $this, $attrdef, $oldvalue)) {
341                    }
342                }
343            }
344
345            unset($this->_attributes[$attrdef->getId()]);
346        }
347        return true;
348    } /* }}} */
349} /* }}} */