Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
70.43% covered (warning)
70.43%
81 / 115
50.00% covered (danger)
50.00%
6 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
SeedDMS_Core_Object
70.43% covered (warning)
70.43%
81 / 115
50.00% covered (danger)
50.00%
6 / 12
148.96
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%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 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    public 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     * Returns an attribute of the object for the given attribute definition
131     *
132     * @param SeedDMS_Core_AttributeDefinition $attrdef
133     * @return array|string value of attritbute or false. The value is an array
134     * if the attribute is defined as multi value
135     */
136    public function getAttribute($attrdef) { /* {{{ */
137        if (!$this->_attributes) {
138            $this->getAttributes();
139        }
140
141        if (isset($this->_attributes[$attrdef->getId()])) {
142            return $this->_attributes[$attrdef->getId()];
143        } else {
144            return false;
145        }
146    } /* }}} */
147
148    /**
149     * Returns an attribute value of the object for the given attribute definition
150     * This is a short cut for $object->getAttribute($attrdef)->getValue()
151     *
152     * @param SeedDMS_Core_AttributeDefinition $attrdef
153     * @return mixed value of attritbute or null if the attribute is not set.
154     *   The value is an array if the attribute is defined as multi value
155     */
156    public function getAttributeValue($attrdef) { /* {{{ */
157        if (!$this->_attributes) {
158            $this->getAttributes();
159        }
160
161        if (isset($this->_attributes[$attrdef->getId()])) {
162            return $this->_attributes[$attrdef->getId()]->getValue();
163        } else {
164            return null;
165        }
166    } /* }}} */
167
168    /**
169     * Returns an attribute value of the object for the given attribute definition
170     *
171     * This is a short cut for getAttribute($attrdef)->getValueAsArray() but
172     * first checks if the object has an attribute for the given attribute
173     * definition.
174     *
175     * @param SeedDMS_Core_AttributeDefinition $attrdef
176     * @return mixed value of attritbute or null if the attribute is not set.
177     *   Even if the attribute is not defined as multi value
178     */
179    public function getAttributeValueAsArray($attrdef) { /* {{{ */
180        if (!$this->_attributes) {
181            $this->getAttributes();
182        }
183
184        if (isset($this->_attributes[$attrdef->getId()])) {
185            return $this->_attributes[$attrdef->getId()]->getValueAsArray();
186        } else {
187            return null;
188        }
189    } /* }}} */
190
191    /**
192     * Returns an attribute value of the object for the given attribute definition
193     *
194     * This is a short cut for getAttribute($attrdef)->getValueAsString() but
195     * first checks if the object has an attribute for the given attribute
196     * definition.
197     *
198     * @param SeedDMS_Core_AttributeDefinition $attrdef
199     * @return string value of attritbute or false. The value is always a string
200     * even if the attribute is defined as multi value
201     */
202    public function getAttributeValueAsString($attrdef) { /* {{{ */
203        if (!$this->_attributes) {
204            $this->getAttributes();
205        }
206
207        if (isset($this->_attributes[$attrdef->getId()])) {
208            return $this->_attributes[$attrdef->getId()]->getValue();
209        } else {
210            return false;
211        }
212    } /* }}} */
213
214    /**
215     * Set an attribute of the object for the given attribute definition
216     *
217     * @param SeedDMS_Core_AttributeDefinition $attrdef definition of attribute
218     * @param array|string $value value of attribute, for multiple values this
219     * must be an array
220     * @return boolean true if operation was successful, otherwise false
221     */
222    public function setAttributeValue($attrdef, $value) { /* {{{ */
223        $db = $this->_dms->getDB();
224        if (!$this->_attributes) {
225            $this->getAttributes();
226        }
227
228        /* Check if objtype of attribute matches object */
229        if ($attrdef->getObjType() != SeedDMS_Core_AttributeDefinition::objtype_all) {
230            if ($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_document && !$this->isType('document'))
231                return false;
232            if ($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_folder && !$this->isType('folder'))
233                return false;
234            if ($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_documentcontent && !$this->isType('documentcontent'))
235                return false;
236        }
237
238        /* Handle the case if an attribute is not set already */
239        if (!isset($this->_attributes[$attrdef->getId()])) {
240            switch ($attrdef->getType()) {
241                case SeedDMS_Core_AttributeDefinition::type_boolean:
242                    $value = ($value === true || $value != '' || $value == 1) ? 1 : 0;
243                    break;
244            }
245
246            $dbvalue = $attrdef->createValue($value);
247            switch (get_class($this)) {
248                case $this->_dms->getClassname('document'):
249                    $tablename = 'tblDocumentAttributes';
250                    $queryStr = "INSERT INTO `tblDocumentAttributes` (`document`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($dbvalue).")";
251                    break;
252                case $this->_dms->getClassname('documentcontent'):
253                    $tablename = 'tblDocumentContentAttributes';
254                    $queryStr = "INSERT INTO `tblDocumentContentAttributes` (`content`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($dbvalue).")";
255                    break;
256                case $this->_dms->getClassname('folder'):
257                    $tablename = 'tblFolderAttributes';
258                    $queryStr = "INSERT INTO `tblFolderAttributes` (`folder`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($dbvalue).")";
259                    break;
260                default:
261                    return false;
262            }
263            $res = $db->getResult($queryStr);
264            if (!$res)
265                return false;
266
267            $attr = new SeedDMS_Core_Attribute($db->getInsertID($tablename), $this, $attrdef, $value);
268            $attr->setDMS($this->_dms);
269            $this->_attributes[$attrdef->getId()] = $attr;
270
271            /* Check if 'onPostAddAttribute' callback is set */
272            if (isset($this->_dms->callbacks['onPostAddAttribute'])) {
273                foreach ($this->_dms->callbacks['onPostAddAttribute'] as $callback) {
274                    if (!call_user_func($callback[0], $callback[1], $this, $attrdef, $value)) {
275                    }
276                }
277            }
278
279            return true;
280        }
281
282        /* The attribute already exists. setValue() will either update or delete it. */
283        $this->_attributes[$attrdef->getId()]->setValue($value);
284
285        return true;
286    } /* }}} */
287
288    /**
289     * Remove an attribute of the object for the given attribute definition
290     *
291     * FIXME: shouldn't this rather be setAttributeValue() with an empty value?
292     *
293     * @param SeedDMS_Core_AttributeDefinition $attrdef
294     * @return boolean true if operation was successful, otherwise false
295     */
296    public function removeAttribute($attrdef) { /* {{{ */
297        $db = $this->_dms->getDB();
298        if (!$this->_attributes) {
299            $this->getAttributes();
300        }
301        if (isset($this->_attributes[$attrdef->getId()])) {
302            $oldvalue = $this->_attributes[$attrdef->getId()]->getValue();
303            switch (get_class($this)) {
304                case $this->_dms->getClassname('document'):
305                    $queryStr = "DELETE FROM `tblDocumentAttributes` WHERE `document`=".$this->_id." AND `attrdef`=".$attrdef->getId();
306                    break;
307                case $this->_dms->getClassname('documentcontent'):
308                    $queryStr = "DELETE FROM `tblDocumentContentAttributes` WHERE `content`=".$this->_id." AND `attrdef`=".$attrdef->getId();
309                    break;
310                case $this->_dms->getClassname('folder'):
311                    $queryStr = "DELETE FROM `tblFolderAttributes` WHERE `folder`=".$this->_id." AND `attrdef`=".$attrdef->getId();
312                    break;
313                default:
314                    return false;
315            }
316            $res = $db->getResult($queryStr);
317            if (!$res)
318                return false;
319
320            /* Check if 'onPostRemoveAttribute' callback is set */
321            if (isset($this->_dms->callbacks['onPostRemoveAttribute'])) {
322                foreach ($this->_dms->callbacks['onPostRemoveAttribute'] as $callback) {
323                    if (!call_user_func($callback[0], $callback[1], $this, $attrdef, $oldvalue)) {
324                    }
325                }
326            }
327
328            unset($this->_attributes[$attrdef->getId()]);
329        }
330        return true;
331    } /* }}} */
332} /* }}} */