ocs  2.3.6
About: OCS (Open Conference System) is a Web publishing tool that will create a complete Web presence for your scholarly conference.
  Fossies Dox: ocs-2.3.6.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

DAO.inc.php
Go to the documentation of this file.
1 <?php
2 
20 // $Id$
21 
22 
23 import('db.DBConnection');
24 import('db.DAOResultFactory');
25 import('core.DataObject');
26 
27 define('SORT_DIRECTION_ASC', 0x00001);
28 define('SORT_DIRECTION_DESC', 0x00002);
29 
30 class DAO {
33 
38  function DAO($dataSource = null, $callHooks = true) {
39  if ($callHooks === true && checkPhpVersion('4.3.0')) {
40  $trace = debug_backtrace();
41  // Call hooks based on the calling entity, assuming
42  // this method is only called by a subclass. Results
43  // in hook calls named e.g. "sessiondao::_Constructor"
44  if (HookRegistry::call(strtolower($trace[1]['class']) . '::_Constructor', array(&$this, &$dataSource))) {
45  return;
46  }
47  }
48 
49  if (!isset($dataSource)) {
50  $this->_dataSource =& DBConnection::getConn();
51  } else {
52  $this->_dataSource = $dataSource;
53  }
54  }
55 
62  function &retrieve($sql, $params = false, $callHooks = true) {
63  if ($callHooks === true && checkPhpVersion('4.3.0')) {
64  $trace = debug_backtrace();
65  // Call hooks based on the calling entity, assuming
66  // this method is only called by a subclass. Results
67  // in hook calls named e.g. "sessiondao::_getsession"
68  // (always lower case).
69  $value = null;
70  if (HookRegistry::call(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), array(&$sql, &$params, &$value))) {
71  return $value;
72  }
73  }
74 
75  $start = Core::microtime();
76  $result =& $this->_dataSource->execute($sql, $params !== false && !is_array($params) ? array($params) : $params);
77  DBConnection::logQuery($sql, $start, $params);
78  if ($this->_dataSource->errorNo()) {
79  // FIXME Handle errors more elegantly.
80  fatalError('DB Error: ' . $this->_dataSource->errorMsg());
81  }
82  return $result;
83  }
84 
91  function &retrieveCached($sql, $params = false, $secsToCache = 3600, $callHooks = true) {
92  if ($callHooks === true && checkPhpVersion('4.3.0')) {
93  $trace = debug_backtrace();
94  // Call hooks based on the calling entity, assuming
95  // this method is only called by a subclass. Results
96  // in hook calls named e.g. "sessiondao::_getsession"
97  // (all lowercase).
98  $value = null;
99  if (HookRegistry::call(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), array(&$sql, &$params, &$secsToCache, &$value))) {
100  return $value;
101  }
102  }
103 
104  $this->setCacheDir();
105 
106  $start = Core::microtime();
107  $result =& $this->_dataSource->CacheExecute($secsToCache, $sql, $params !== false && !is_array($params) ? array($params) : $params);
108  DBConnection::logQuery($sql, $start, $params);
109  if ($this->_dataSource->errorNo()) {
110  // FIXME Handle errors more elegantly.
111  fatalError('DB Error: ' . $this->_dataSource->errorMsg());
112  }
113  return $result;
114  }
115 
124  function &retrieveLimit($sql, $params = false, $numRows = false, $offset = false, $callHooks = true) {
125  if ($callHooks === true && checkPhpVersion('4.3.0')) {
126  $trace = debug_backtrace();
127  // Call hooks based on the calling entity, assuming
128  // this method is only called by a subclass. Results
129  // in hook calls named e.g. "sessiondao::_getsession"
130  // (all lowercase).
131  $value = null;
132  if (HookRegistry::call(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), array(&$sql, &$params, &$numRows, &$offset, &$value))) {
133  return $value;
134  }
135  }
136 
137  $start = Core::microtime();
138  $result =& $this->_dataSource->selectLimit($sql, $numRows === false ? -1 : $numRows, $offset === false ? -1 : $offset, $params !== false && !is_array($params) ? array($params) : $params);
139  DBConnection::logQuery($sql, $start, $params);
140  if ($this->_dataSource->errorNo()) {
141  fatalError('DB Error: ' . $this->_dataSource->errorMsg());
142  }
143  return $result;
144  }
145 
152  function &retrieveRange($sql, $params = false, $dbResultRange = null, $callHooks = true) {
153  if ($callHooks === true && checkPhpVersion('4.3.0')) {
154  $trace = debug_backtrace();
155  // Call hooks based on the calling entity, assuming
156  // this method is only called by a subclass. Results
157  // in hook calls named e.g. "sessiondao::_getsession"
158  $value = null;
159  if (HookRegistry::call(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), array(&$sql, &$params, &$dbResultRange, &$value))) {
160  return $value;
161  }
162  }
163 
164  if (isset($dbResultRange) && $dbResultRange->isValid()) {
165  $start = Core::microtime();
166  $result =& $this->_dataSource->PageExecute($sql, $dbResultRange->getCount(), $dbResultRange->getPage(), $params);
167  DBConnection::logQuery($sql, $start, $params);
168  if ($this->_dataSource->errorNo()) {
169  fatalError('DB Error: ' . $this->_dataSource->errorMsg());
170  }
171  }
172  else {
173  $result =& $this->retrieve($sql, $params, false);
174  }
175  return $result;
176  }
177 
186  function update($sql, $params = false, $callHooks = true, $dieOnError = true) {
187  if ($callHooks === true && checkPhpVersion('4.3.0')) {
188  $trace = debug_backtrace();
189  // Call hooks based on the calling entity, assuming
190  // this method is only called by a subclass. Results
191  // in hook calls named e.g. "sessiondao::_updateobject"
192  // (all lowercase)
193  $value = null;
194  if (HookRegistry::call(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), array(&$sql, &$params, &$value))) {
195  return $value;
196  }
197  }
198 
199  $start = Core::microtime();
200  $this->_dataSource->execute($sql, $params !== false && !is_array($params) ? array($params) : $params);
201  DBConnection::logQuery($sql, $start, $params);
202  if ($dieOnError && $this->_dataSource->errorNo()) {
203  fatalError('DB Error: ' . $this->_dataSource->errorMsg());
204  }
205  return $this->_dataSource->errorNo() == 0 ? true : false;
206  }
207 
214  function replace($table, $arrFields, $keyCols) {
215  $arrFields = array_map(array($this->_dataSource, 'qstr'), $arrFields);
216  $this->_dataSource->Replace($table, $arrFields, $keyCols, false);
217  }
218 
225  function getInsertId($table = '', $id = '', $callHooks = true) {
226  return $this->_dataSource->po_insert_id($table, $id);
227  }
228 
234  function setCacheDir() {
235  static $cacheDir;
236  if (!isset($cacheDir)) {
237  global $ADODB_CACHE_DIR;
238 
239  $cacheDir = CacheManager::getFileCachePath() . '/_db';
240 
241  $ADODB_CACHE_DIR = $cacheDir;
242  }
243  }
244 
248  function flushCache() {
249  $this->setCacheDir();
250  $this->_dataSource->CacheFlush();
251  }
252 
258  function datetimeToDB($dt) {
259  return $this->_dataSource->DBTimeStamp($dt);
260  }
261 
267  function dateToDB($d) {
268  return $this->_dataSource->DBDate($d);
269  }
270 
276  function datetimeFromDB($dt) {
277  if ($dt === null) return null;
278  return $this->_dataSource->UserTimeStamp($dt, 'Y-m-d H:i:s');
279  }
285  function dateFromDB($d) {
286  if ($d === null) return null;
287  return $this->_dataSource->UserDate($d, 'Y-m-d');
288  }
289 
296  function convertFromDB($value, $type) {
297  switch ($type) {
298  case 'bool':
299  $value = (bool) $value;
300  break;
301  case 'int':
302  $value = (int) $value;
303  break;
304  case 'float':
305  $value = (float) $value;
306  break;
307  case 'object':
308  $value = unserialize($value);
309  break;
310  case 'date':
311  if ($value !== null) $value = strtotime($value);
312  break;
313  case 'string':
314  default:
315  // Nothing required.
316  break;
317  }
318  return $value;
319  }
320 
326  function getType($value) {
327  switch (gettype($value)) {
328  case 'boolean':
329  case 'bool':
330  return 'bool';
331  case 'integer':
332  case 'int':
333  return 'int';
334  case 'double':
335  case 'float':
336  return 'float';
337  case 'array':
338  case 'object':
339  return 'object';
340  case 'string':
341  default:
342  return 'string';
343  }
344  }
345 
352  function convertToDB($value, &$type) {
353  if ($type == null) {
354  $type = $this->getType($value);
355  }
356 
357  switch ($type) {
358  case 'object':
359  $value = serialize($value);
360  break;
361  case 'bool':
362  $value = $value ? 1 : 0;
363  break;
364  case 'date':
365  if ($value !== null) {
366  if (!is_numeric($value)) $value = strtotime($value);
367  $value = strftime('%Y-%m-%d %H:%M:%S', $value);
368  }
369  break;
370  default:
371  }
372 
373  return $value;
374  }
375 
376  function nullOrInt($value) {
377  return (empty($value)?null:(int) $value);
378  }
379 
381  $returner = array();
382  if (checkPhpVersion('4.3.0')) {
383  $trace = debug_backtrace();
384  // Call hooks based on the calling entity, assuming
385  // this method is only called by a subclass. Results
386  // in hook calls named e.g. "sessiondao::getAdditionalFieldNames"
387  // (class names lowercase)
388  HookRegistry::call(strtolower($trace[2]['class']) . '::getAdditionalFieldNames', array(&$this, &$returner));
389  }
390  return $returner;
391  }
392 
393  function getLocaleFieldNames() {
394  $returner = array();
395  if (checkPhpVersion('4.3.0')) {
396  $trace = debug_backtrace();
397  // Call hooks based on the calling entity, assuming
398  // this method is only called by a subclass. Results
399  // in hook calls named e.g. "sessiondao::getLocaleFieldNames"
400  // (class names lowercase)
401  HookRegistry::call(strtolower($trace[2]['class']) . '::getLocaleFieldNames', array(&$this, &$returner));
402  }
403  return $returner;
404  }
405 
412  function updateDataObjectSettings($tableName, &$dataObject, $idArray) {
413  // Initialize variables
414  $idFields = array_keys($idArray);
415  $idFields[] = 'locale';
416  $idFields[] = 'setting_name';
417 
418  // Build a data structure that we can process efficiently.
419  $translated = $metadata = 1;
420  $settings = !$metadata;
421  $settingFields = array(
422  // Translated data
423  $translated => array(
424  $settings => $this->getLocaleFieldNames(),
425  $metadata => $dataObject->getLocaleMetadataFieldNames()
426  ),
427  // Shared data
428  !$translated => array(
429  $settings => $this->getAdditionalFieldNames(),
430  $metadata => $dataObject->getAdditionalMetadataFieldNames()
431  )
432  );
433 
434  // Loop over all fields and update them in the settings table
435  $updateArray = $idArray;
436  $noLocale = 0;
437  $staleMetadataSettings = array();
438  foreach ($settingFields as $isTranslated => $fieldTypes) {
439  foreach ($fieldTypes as $isMetadata => $fieldNames) {
440  foreach ($fieldNames as $fieldName) {
441  // Now we have the following control data:
442  // - $isTranslated: true for translated data, false data shared between locales
443  // - $isMetadata: true for metadata fields, false for normal settings
444  // - $fieldName: the field in the data object to be updated
445  if ($dataObject->hasData($fieldName)) {
446  if ($isTranslated) {
447  // Translated data comes in as an array
448  // with the locale as the key.
449  $values = $dataObject->getData($fieldName);
450  if (!is_array($values)) {
451  // Inconsistent data: should have been an array
452  assert(false);
453  continue;
454  }
455  } else {
456  // Transform shared data into an array so that
457  // we can handle them the same way as translated data.
458  $values = array(
459  $noLocale => $dataObject->getData($fieldName)
460  );
461  }
462 
463  // Loop over the values and update them in the database
464  foreach ($values as $locale => $value) {
465  $updateArray['locale'] = ($locale === $noLocale ? '' : $locale);
466  $updateArray['setting_name'] = $fieldName;
467  $updateArray['setting_type'] = null;
468  // Convert the data value and implicitly set the setting type.
469  $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']);
470  $this->replace($tableName, $updateArray, $idFields);
471  }
472  } else {
473  // Meta-data fields are maintained "sparsly". Only set fields will be
474  // recorded in the settings table. Fields that are not explicity set
475  // in the data object will be deleted.
476  if ($isMetadata) $staleMetadataSettings[] = $fieldName;
477  }
478  }
479  }
480  }
481 
482  // Remove stale meta-data
483  if (count($staleMetadataSettings)) {
484  $removeWhere = '';
485  $removeParams = array();
486  foreach ($idArray as $idField => $idValue) {
487  if (!empty($removeWhere)) $removeWhere .= ' AND ';
488  $removeWhere .= $idField.' = ?';
489  $removeParams[] = $idValue;
490  }
491  $removeWhere .= rtrim(' AND setting_name IN ( '.str_repeat('? ,', count($staleMetadataSettings)), ',').')';
492  $removeParams = array_merge($removeParams, $staleMetadataSettings);
493  $removeSql = 'DELETE FROM '.$tableName.' WHERE '.$removeWhere;
494  $this->update($removeSql, $removeParams);
495  }
496  }
497 
498  function getDataObjectSettings($tableName, $idFieldName, $idFieldValue, &$dataObject) {
499  if ($idFieldName !== null) {
500  $sql = "SELECT * FROM $tableName WHERE $idFieldName = ?";
501  $params = array($idFieldValue);
502  } else {
503  $sql = "SELECT * FROM $tableName";
504  $params = false;
505  }
506  $start = Core::microtime();
507  $result =& $this->retrieve($sql, $params);
508 
509  while (!$result->EOF) {
510  $row =& $result->getRowAssoc(false);
511  $dataObject->setData(
512  $row['setting_name'],
513  $this->convertFromDB(
514  $row['setting_value'],
515  $row['setting_type']
516  ),
517  empty($row['locale'])?null:$row['locale']
518  );
519  unset($row);
520  $result->MoveNext();
521  }
522 
523  $result->Close();
524  unset($result);
525  }
526 
531  function getDriver() {
532  $conn =& DBConnection::getInstance();
533  return $conn->getDriver();
534  }
535 
541  function getDirectionMapping($direction) {
542  switch ($direction) {
543  case SORT_DIRECTION_ASC:
544  return 'ASC';
545  case SORT_DIRECTION_DESC:
546  return 'DESC';
547  default:
548  return 'ASC';
549  }
550  }
551 }
552 
553 ?>
config TEMPLATE inc php
Definition: config.inc.php:4
Operations for retrieving and modifying objects from a database.
Definition: DAO.inc.php:30
getLocaleFieldNames()
Definition: DAO.inc.php:393
DAO($dataSource=null, $callHooks=true)
Definition: DAO.inc.php:38
checkPhpVersion($version)
& retrieveLimit($sql, $params=false, $numRows=false, $offset=false, $callHooks=true)
Definition: DAO.inc.php:124
& retrieve($sql, $params=false, $callHooks=true)
Definition: DAO.inc.php:62
getInsertId($table='', $id='', $callHooks=true)
Definition: DAO.inc.php:225
updateDataObjectSettings($tableName, &$dataObject, $idArray)
Definition: DAO.inc.php:412
dateToDB($d)
Definition: DAO.inc.php:267
& retrieveRange($sql, $params=false, $dbResultRange=null, $callHooks=true)
Definition: DAO.inc.php:152
microtime()
Definition: Core.inc.php:98
& getInstance($setInstance=null)
nullOrInt($value)
Definition: DAO.inc.php:376
datetimeFromDB($dt)
Definition: DAO.inc.php:276
getAdditionalFieldNames()
Definition: DAO.inc.php:380
$_dataSource
Definition: DAO.inc.php:32
convertFromDB($value, $type)
Definition: DAO.inc.php:296
if(!function_exists('import')) if(!function_exists('file_get_contents')) fatalError($reason)
& retrieveCached($sql, $params=false, $secsToCache=3600, $callHooks=true)
Definition: DAO.inc.php:91
convertToDB($value, &$type)
Definition: DAO.inc.php:352
setCacheDir()
Definition: DAO.inc.php:234
call($hookName, $args=null)
flushCache()
Definition: DAO.inc.php:248
getDriver()
Definition: DAO.inc.php:531
getDataObjectSettings($tableName, $idFieldName, $idFieldValue, &$dataObject)
Definition: DAO.inc.php:498
replace($table, $arrFields, $keyCols)
Definition: DAO.inc.php:214
logQuery($sql, $start, $params=array())
datetimeToDB($dt)
Definition: DAO.inc.php:258
getType($value)
Definition: DAO.inc.php:326
update($sql, $params=false, $callHooks=true, $dieOnError=true)
Definition: DAO.inc.php:186
getDirectionMapping($direction)
Definition: DAO.inc.php:541
const SORT_DIRECTION_ASC
Definition: DAO.inc.php:27
const SORT_DIRECTION_DESC
Definition: DAO.inc.php:28
dateFromDB($d)
Definition: DAO.inc.php:285