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