1: <?php
2:
3: /**
4: * This file contains the abstract base item class of the generic db.
5: *
6: * @package Core
7: * @subpackage GenericDB
8: * @version SVN Revision $Rev:$
9: *
10: * @author Murat Purc <murat@purc.de>
11: * @copyright four for business AG <www.4fb.de>
12: * @license http://www.contenido.org/license/LIZENZ.txt
13: * @link http://www.4fb.de
14: * @link http://www.contenido.org
15: */
16:
17: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
18:
19: // Try to load GenericDB database driver
20: // TODO: check if this is needed any longer because we have autoloading feature
21: global $cfg;
22: $driver_filename = cRegistry::getBackendPath() . $cfg['path']['classes'] . 'drivers/' . $cfg['sql']['gdb_driver'] . '/class.gdb.' . $cfg['sql']['gdb_driver'] . '.php';
23: if (cFileHandler::exists($driver_filename)) {
24: include_once($driver_filename);
25: }
26:
27: /**
28: * Class cItemBaseAbstract.
29: * Base class with common features for database based items and item
30: * collections.
31: *
32: * NOTE:
33: * Because of required downwards compatibilitiy all protected/private member
34: * variables or methods don't have an leading underscore.
35: *
36: * @package Core
37: * @subpackage GenericDB
38: */
39: abstract class cItemBaseAbstract extends cGenericDb {
40:
41: /**
42: * Database instance, contains the database object
43: *
44: * @var cDb
45: */
46: protected $db;
47:
48: /**
49: * Second DB instance, is required for some additional queries without
50: * losing an current existing query result.
51: *
52: * @var cDb
53: */
54: protected $secondDb;
55:
56: /**
57: * Property collection instance
58: *
59: * @var cApiPropertyCollection
60: */
61: protected $properties;
62:
63: /**
64: * Item cache instance
65: *
66: * @var cItemCache
67: */
68: protected $_oCache;
69:
70: /**
71: * GenericDB settings, see $cfg['sql']
72: *
73: * @var array
74: */
75: protected $_settings;
76:
77: /**
78: * Storage of the source table to use for the information
79: *
80: * @var string
81: */
82: protected $table;
83:
84: /**
85: * Setting of primaryKey name (deprecated)
86: *
87: * @deprecated [2015-05-04]
88: * Class variable primaryKey is deprecated, use getPrimaryKeyName() instead
89: * @var string
90: */
91: private $primaryKey;
92:
93: /**
94: * Storage of the primary key name
95: *
96: * @var string
97: */
98: protected $_primaryKeyName;
99:
100: /**
101: * Checks for the virginity of created objects.
102: * If true, the object
103: * is virgin and no operations on it except load-functions are allowed.
104: *
105: * @deprecated [2015-05-05]
106: * Class variable virgin is deprecated, use negated result of isLoaded() instead
107: * @var bool
108: */
109: private $virgin = true;
110:
111: /**
112: * Checks if an object is loaded
113: * If it is true an object is loaded
114: * If it is false then no object is loaded and only load-functions are allowed to be used
115: * @var bool
116: */
117: protected $_loaded = false;
118:
119: /**
120: * Storage of the last occured error
121: *
122: * @var string
123: */
124: protected $lasterror = '';
125:
126: /**
127: * Classname of current instance
128: *
129: * @var string
130: */
131: protected $_className;
132:
133: /**
134: * Sets some common properties
135: *
136: * @param string $sTable
137: * Name of table
138: * @param string $sPrimaryKey
139: * Primary key of table
140: * @param string $sClassName
141: * Name of parent class
142: * @throws cInvalidArgumentException
143: * If table name or primary key is not set
144: */
145: protected function __construct($sTable, $sPrimaryKey, $sClassName) {
146: global $cfg;
147:
148: $this->db = cRegistry::getDb();
149:
150: if ($sTable == '') {
151: $sMsg = "$sClassName: No table specified. Inherited classes *need* to set a table";
152: throw new cInvalidArgumentException($sMsg);
153: } elseif ($sPrimaryKey == '') {
154: $sMsg = "No primary key specified. Inherited classes *need* to set a primary key";
155: throw new cInvalidArgumentException($sMsg);
156: }
157:
158: $this->_settings = $cfg['sql'];
159:
160: // instantiate caching
161: $aCacheOpt = (isset($this->_settings['cache'])) ? $this->_settings['cache'] : array();
162: $this->_oCache = cItemCache::getInstance($sTable, $aCacheOpt);
163:
164: $this->table = $sTable;
165: static::_setPrimaryKeyName($sPrimaryKey);
166: $this->_className = $sClassName;
167: }
168:
169: /**
170: * Resets class variables back to default
171: * This is handy in case a new item is tried to be loaded into this class instance.
172: */
173: protected function _resetItem() {
174: $this->_setLoaded(false);
175: $this->properties = null;
176: $this->lasterror = '';
177: }
178:
179: /**
180: * Escape string for using in SQL-Statement.
181: *
182: * @param string $sString
183: * The string to escape
184: * @return string
185: * Escaped string
186: */
187: public function escape($sString) {
188: return $this->db->escape($sString);
189: }
190:
191: /**
192: * Checks if an object is loaded
193: * If it is true an object is loaded
194: * If it is false then no object is loaded and only load-functions are allowed to be used
195: * @return bool Whether an object has been loaded
196: */
197: public function isLoaded() {
198: return (bool) $this->_loaded;
199: }
200:
201: /**
202: * Sets loaded state of class
203: * If it is true an object is loaded
204: * If it is false then no object is loaded and only load-functions are allowed to be used
205: *
206: * @param bool $value
207: * Whether an object is loaded
208: */
209: protected function _setLoaded($value) {
210: $this->_loaded = (bool) $value;
211: }
212:
213: /**
214: * Magic getter function for deprecated variables primaryKey and virgin
215: * This function will be removed when the variables are no longer supported
216: *
217: * @param string $name
218: * Name of the variable that should be accessed
219: * @return mixed
220: */
221: public function __get($name) {
222: if ('primaryKey' === $name) {
223: return static::getPrimaryKeyName();
224: }
225: if ('virgin' === $name) {
226: return !static::isLoaded();
227: }
228: }
229:
230: /**
231: * Magic setter function for deprecated variables primaryKey and virgin
232: * This function will be removed when the variables are no longer supported
233: *
234: * @param string $name
235: * Name of the variable that should be accessed
236: * @param mixed $value
237: * Value that should be assigned to variable
238: */
239: public function __set($name, $value) {
240: if ('primaryKey' === $name) {
241: static::_setPrimaryKeyName($value);
242: } else if ('virgin' === $name) {
243: static::_setLoaded(!(bool) $value);
244: }
245: }
246:
247: /**
248: * Get the primary key name in database
249: * @return string
250: * Name of primary key
251: */
252: public function getPrimaryKeyName() {
253: return (string) $this->_primaryKeyName;
254: }
255:
256: /**
257: * Set the primary key name for class
258: * The name must always match the primary key name in database
259: *
260: * @param string $keyName
261: */
262: protected function _setPrimaryKeyName($keyName) {
263: $this->_primaryKeyName = (string) $keyName;
264: }
265:
266: /**
267: * Returns the second database instance, usable to run additional statements
268: * without losing current query results.
269: *
270: * @return cDb
271: */
272: protected function _getSecondDBInstance() {
273: if (!isset($this->secondDb) || !($this->secondDb instanceof cDb)) {
274: $this->secondDb = cRegistry::getDb();
275: }
276: return $this->secondDb;
277: }
278:
279: /**
280: * Returns properties instance, instantiates it if not done before.
281: * NOTE: This funtion changes always the client variable of property
282: * collection instance.
283: *
284: * @param int $idclient [optional]
285: * Id of client to use in property collection.
286: * If not passed it uses global variable
287: * @return cApiPropertyCollection
288: */
289: protected function _getPropertiesCollectionInstance($idclient = 0) {
290: global $client;
291:
292: if ((int) $idclient <= 0) {
293: $idclient = $client;
294: }
295:
296: // Runtime on-demand allocation of the properties object
297: if (!isset($this->properties) || !($this->properties instanceof cApiPropertyCollection)) {
298: $this->properties = new cApiPropertyCollection();
299: }
300:
301: if ((int) $idclient > 0) {
302: $this->properties->changeClient($idclient);
303: }
304:
305: return $this->properties;
306: }
307: }
308: