[ Index ]
 

Code source de LifeType 1.2.4

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/class/dao/ -> model.class.php (source)

   1  <?php
   2  
   3      /**
   4       * \defgroup DAO
   5       *    
   6       * DAO stands for "Data Access Object" and represents a data model 
   7       * according to the MVC architecture. 
   8       *
   9       * DAO classes isolate developers of all the intricacies of the 
  10       * database structure, so that for example loading a post from the 
  11       * dabase is as easy as:
  12       *
  13       * <pre>
  14       *   $articles = new Articles();
  15       *   $userPost = $arcticles->getBlogArticle( 15 );
  16       * </pre>
  17       *
  18       * Otherwise, developers would need to write an SQL query every time we 
  19       * need to load an article from the database. In general, DAO classes 
  20       * provide access to reading, updating and removing data from the database.
  21       * In pLog, we usually have two classes per entity: a smaller one that 
  22       * contains no database access logic and that only contains the information
  23       * necessary (usually, it represents a row from the database), and the 
  24       * second will be a bigger class that includes SQL code and database logic 
  25       * and that provides all the methods outlined above (read, update and 
  26       * remove from the database) Examples of this are Articles and Article, 
  27       * or Users and UserInfo. 
  28       *
  29       * Other relevant DAO classes are ArticleComments and UserComment, 
  30       * MyLink and MyLinks, etc.
  31       *
  32       * All classes that extend the base Model class, automatically inherit 
  33       * an open connection to the database * (via the private attribute 
  34       * Model::_db) and several other database-related methods. 
  35       *
  36       * Furthermore all classes that extend the base Model class gets a 
  37       * reference to the global disk-based cache. More information on how
  38       * to use the cache can be found in the Cache Group
  39       *
  40       * If you need to implement some kind of data access, please extend 
  41       * from Model.
  42       *
  43       */
  44  
  45      /**
  46       * default database prefix, if none other specified
  47       */
  48      define( "DEFAULT_DB_PREFIX", "plog_" );
  49  
  50      /**
  51       * whether database-level debugging is enabled
  52       */
  53      define( "DAO_DEBUG_ENABLED", false );
  54  
  55      /**
  56       * how many items per page by default, when paging is enabled
  57       */
  58      define( "DEFAULT_ITEMS_PER_PAGE", 15 );
  59      
  60      /**
  61       * whether we're going to use paging or not.
  62       */
  63      define( "DEFAULT_PAGING_ENABLED", -1 );
  64      
  65      /**
  66       * enable or disable the data cache
  67       */
  68      define( "DATA_CACHE_ENABLED", true );
  69  
  70      /**
  71       * the names of the tables used in pLog
  72       */
  73      define( 'BLOGS_TABLENAME', 'blogs' );
  74      define( 'ARTICLES_TABLENAME', 'articles' );
  75      define( 'ARTICLETEXTS_TABLENAME', 'articles_text' );
  76      define( 'ARTICLE_CATEGORIES_RELATIONSHIP_TABLENAME',
  77              'article_categories_link' );
  78      define( 'CUSTOMFIELD_VALUES', 'custom_fields_values' );
  79  
  80  
  81      /**
  82       * \ingroup DAO
  83       *
  84       * This class provides all the classes extending it with a database 
  85       * connection so that classes don't have to 
  86       * worry about that. Later on, the Model classes will be used by 
  87       * the corresponding action object.
  88       */
  89      class Model
  90      {
  91  
  92          var $_db;        
  93          var $_prefix = null;
  94          var $_cache;
  95          var $_dbInitialized =  false;
  96          var $_lastError = "";
  97  
  98          /**
  99           * Basic constructor, setting up a cache for all classes extending Model
 100           *
 101           * @param useCache Some object might not need a cache and can disable it by passing false
 102           */
 103          function Model( $cacheEnabled = DATA_CACHE_ENABLED )
 104          {
 105              // allow a cache for all dao objects
 106              lt_include( PLOG_CLASS_PATH . "class/cache/cachemanager.class.php" );
 107              $this->_cache =& CacheManager::getCache( $cacheEnabled );
 108          }
 109  
 110          /**
 111           * executes a query with certain limits (for paging, for ex.)
 112           *
 113           * @param query The query to be executed
 114           * @param page enable paging, pass page number or -1 to disable paging
 115           * @param itemsPerPage number of items on a page
 116           * @see Execute
 117           * @return A ResultSet or false if errors
 118           */        
 119          function Execute( $query, 
 120                            $page = DEFAULT_PAGING_ENABLED, 
 121                            $itemsPerPage = DEFAULT_ITEMS_PER_PAGE )
 122          {
 123              // initialize the db when we have to execute the first query, 
 124              // not earlier. 
 125              $this->_initializeDb();
 126          
 127              // see PDbDriverBase (or one of its drivers like PDbMySQLDriver 
 128              // for details)
 129              $result = $this->_db->Execute( $query, $page, $itemsPerPage );
 130  
 131              // if the query generated an error, write a message to the sql 
 132              // error log file
 133              if( !$result ) {
 134                  $this->_lastError = $this->_db->ErrorMsg();
 135                  lt_include( PLOG_CLASS_PATH . "class/logger/loggermanager.class.php" );
 136  
 137                  $log =& LoggerManager::getLogger( "sqlerr" );
 138                  $error = $this->DbError();
 139                  $log->error( "The following query = \n" .
 140                                $query .
 141                               "generated the following error message = \n" .
 142                                $error );
 143              }
 144                  
 145              return( $result );
 146          }
 147  
 148          /**
 149           * Returns the last error message from the database.
 150           *
 151           * @param driverError Set this field to true if interested in getting the error message as reported by
 152           * the driver. Keep in mind that the error message might be gone after we've closed the connection
 153           * (by calling the Close() method at the driver level) The only way to get the error message in 
 154           * that case (if any at all) is by setting this parameter to 'false'. If done so, this class will save
 155           * the last error message and make it available via this method. This parameter defaults to false.
 156           * @return A string containing the error message
 157           */
 158          function DbError( $driverError = false )
 159          {
 160              if( $driverError )
 161                  return( $this->_db->ErrorMsg());
 162              else
 163                  return( $this->_lastError );
 164          }
 165          
 166          /**
 167           * Retrieves one single row/object from the database
 168           *
 169           * @param field
 170           * @param value
 171           * @param cacheId
 172           * @param caches
 173           * @return
 174           */
 175          function get( $field, $value, $cacheId, $caches = null )
 176          {
 177              $dbObject = $this->_cache->getData( $value, $cacheId );
 178  
 179              if( !$dbObject ) {
 180                  $query = "SELECT * FROM ".$this->table." WHERE {$field} = '".Db::qstr( $value )."'";
 181                  
 182                  $result = $this->Execute( $query );
 183                  
 184                  if( !$result )
 185                      return false;
 186                  
 187                  if( $result->RowCount() == 0 ){
 188                      $result->Close();
 189                      return false;
 190                  }
 191                      
 192                  $row = $result->FetchRow();
 193                  $result->Close();
 194  
 195                  $dbObject = $this->mapRow( $row );
 196                  
 197                  $this->_cache->setData( $value, $cacheId, $dbObject );
 198                  if( $caches ) {
 199                      foreach( $caches as $cache => $getter ) {
 200                          $this->_cache->setData( $dbObject->$getter(), $cache, $dbObject );
 201                      }
 202                  }
 203              }
 204              
 205              return( $dbObject );
 206              
 207          }
 208                  
 209          /**
 210           * Retrieves all the rows from the given table
 211           *
 212           * @param key
 213           * @param cacheId
 214           * @param itemCaches
 215           * @param sorting
 216           * @param searchTerms
 217           * @param page
 218           * @param itemsPerPage
 219           * @return
 220           */         
 221          function getAll( $key, $cacheId, $itemCaches = null, $sorting = Array(), $searchTerms ="", $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE )
 222          {
 223              return( $this->getMany( $key, "_all_", $cacheId, $itemCaches, $sorting, $searchTerms, $page, $itemsPerPage ));
 224          }      
 225          
 226          /**
 227           * This method must be reimplemented by child classes wishing to provide
 228           * search functionalities
 229           *
 230           * @param searchTerms
 231           * @return search string to be used in an SQL query
 232           */
 233  		function getSearchConditions( $searchTerms )
 234          {
 235              return( "" );
 236          }
 237          
 238          /**
 239           * Retrieves a set of rows of the given table using the given (simple) conditions.
 240           *
 241           * @param key
 242           * @param value
 243           * @param cacheId
 244           * @param itemCaches
 245           * @param sorting
 246           * @param searchTerms
 247           * @param page
 248           * @param itemsPerPage
 249           * @return
 250           */                 
 251          function getMany( $key, $value, $cacheId, $itemCaches = null, $sorting = Array(), $searchTerms = "", $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE )
 252          {
 253              // if we previously used the search terms, then we did not cache the data
 254              if( $searchTerms == "" )
 255                  $dbObjects = $this->_cache->getData( $value, $cacheId );
 256              else
 257                  $dbObjects = null;
 258                  
 259              if( !$dbObjects ) {
 260                  $query = "SELECT * FROM ".$this->table;    
 261                  $where = "";
 262                  // if $value is 'all' or null, then we are going to cache the whole thing so let's not
 263                  // include these as parameters. 
 264                  if( $value != "_all_" && $value != null ) {
 265                      $where .= " WHERE {$key} = '".Db::qstr($value)."'";                    
 266                  }
 267                  if( $searchTerms != "" ) {
 268                      // get the table-dependent search string
 269                      $search = $this->getSearchConditions( $searchTerms );
 270                      // add the search terms, if any
 271                      if( $where ) $where .= " AND $search";
 272                      else
 273                          if( $search) $where = " WHERE ".$search;
 274                      // remove the last 'AND' in case it's the last thing in the string
 275                      if( substr($where, strlen( $where ) - 3 , 3) == 'AND' )
 276                          $where = substr( $where, 0, strlen( $where ) - 3 );
 277                  }
 278                  $orderBy = "";
 279                  if( count( $sorting ) > 0 ) {
 280                      // check the sorting...
 281                      $orderBy = " ORDER BY ";
 282                      foreach( $sorting as $field => $dir ) {
 283                          $orderBy .= "$field $dir";
 284                      }
 285                  }
 286  
 287                  // build the query including all parts
 288                  $query = $query.$where.$orderBy;
 289                  
 290                  $result = $this->Execute( $query );
 291                  
 292                  if( !$result )
 293                      return false;
 294                  
 295                  if( $result->RowCount() == 0 ){
 296                      $result->Close();
 297                      return false;
 298                  }
 299                      
 300                  $dbObjects = Array();
 301                  while( $row = $result->FetchRow()) {            
 302                      $dbObject = $this->mapRow( $row );
 303                      $dbObjects[] = $dbObject;
 304                      if( $itemCaches ) {
 305                          foreach( $itemCaches as $cache => $getter ) {
 306                              $this->_cache->setData( $dbObject->$getter(), $cache, $dbObject );
 307                          }
 308                      }
 309                  }
 310                  $result->Close();
 311  
 312                  // do not cache data if using search terms!
 313                  if( $searchTerms == "" ) 
 314                      $this->_cache->setData( $value, $cacheId, $dbObjects );
 315              }
 316              
 317              if( $page > -1 ) {
 318                  // return only a subset of the items
 319                  $start = (($page - 1) * $itemsPerPage );
 320                  $dbObjects = array_slice( $dbObjects, $start, $itemsPerPage );                
 321              }
 322              
 323              return( $dbObjects );
 324          }
 325          
 326          /**
 327           * Adds a row to the current table
 328           *
 329           * @param dbObject
 330           * @param cacheId
 331           * @return True if successful or false if error
 332           */
 333          function add( &$dbObject, $cacheId = null ) 
 334          {
 335              $fields = $dbObject->getFieldGetters();
 336              $fieldsString = '';
 337              $fieldsValuesString = '';
 338  
 339              $sql    = "INSERT INTO `".$this->table."` (";
 340  
 341              foreach ($fields as $field => $getter)
 342              {
 343                  if( $field != "id" ) {
 344                      // let's ignore the primary key!
 345                      $fieldsString .= $field.", ";
 346                  
 347                      $value = $dbObject->$getter();
 348                      
 349                      if( is_array( $value )) $value = serialize( $value );     
 350                      elseif( is_bool( $value ))  $value = (int)$value;  // convert the bool to '1' or '0'
 351                      elseif( is_object( $value )) {
 352                          if( strtolower(get_class( $value )) == "timestamp" )
 353                              $value = $value->getTimestamp();
 354                          else
 355                              $value = serialize( $value );
 356                      }
 357                      $value = Db::qstr($value);
 358                      $fieldsValuesString .= "'" . $value . "', ";
 359                  }
 360              }
 361  
 362              $sql .= substr($fieldsString, 0, -2) . ") VALUES (".substr($fieldsValuesString, 0, -2).")";            
 363              
 364              $result = $this->Execute( $sql );            
 365              if( !$result )
 366                  return false;
 367                  
 368              $dbObject->setId( $this->_db->Insert_ID());            
 369              
 370              if( $cacheId ) {
 371                  foreach( $cacheId as $cache => $getter ) {
 372                      $this->_cache->setData( $dbObject->{$getter}(), $cache, $dbObject );
 373                  }
 374              }           
 375  
 376              return( $dbObject->getId());
 377          }
 378          
 379          /** 
 380           * Updates an object/row in the database
 381           *
 382           * @param dbObject
 383           * @return True if successful or false if error
 384           */
 385          function update( &$dbObject )
 386          {
 387              lt_include( PLOG_CLASS_PATH."class/database/db.class.php" );
 388          
 389              $fields = $dbObject->getFieldGetters();
 390              $sql    = "UPDATE `".$this->table."` SET ";
 391  
 392              foreach ($fields as $field => $getter)
 393              {
 394                  $value = $dbObject->$getter();
 395                  if( is_array( $value )) $value = serialize( $value );                
 396                  elseif( strtolower(get_class( $value )) == "timestamp" )
 397                      $value = $value->getTimestamp();
 398                  elseif( is_object( $value )) $value = serialize( $value );
 399                  
 400                  $value = Db::qstr($value);
 401                  $sql  .= "`" . $field . "`='" . $value . "', ";
 402              }
 403  
 404              $sql = substr($sql, 0, -2) . " WHERE id = '".Db::qstr($dbObject->getId())."'";            
 405              
 406              $result = $this->Execute( $sql );            
 407              
 408              if( !$result )
 409                  return false;
 410  
 411              return true;
 412          }
 413          
 414          /**
 415           * Deletes a row from the database, using the field and value parameters as the condition
 416           *
 417           * @param field
 418           * @param value
 419           * @return True if successful or false otherwise
 420           */
 421          function delete( $field, $value )
 422          {
 423              $query = "DELETE FROM ".$this->table." WHERE {$field} = '{$value}'";
 424              $result = $this->Execute( $query );                                
 425              return( $result );
 426          }
 427  
 428          /**
 429           * returns the current database prefix
 430           *
 431           * @deprecated the prefix should be set/added by the Db Classes, not by the model
 432           * @return the current database prefix
 433           */
 434          function getPrefix()
 435          {
 436              if ( $this->_prefix === null ) {
 437                  lt_include( PLOG_CLASS_PATH."class/database/db.class.php" );
 438  
 439                  $this->_prefix = Db::getPrefix();
 440              }
 441  
 442              return $this->_prefix;
 443          }
 444  
 445          /**
 446           * retrieves the number of records in a table given an optional condition
 447           *
 448           * @param table
 449           * @param cond
 450           * @return the number of items or 0 if none or error
 451           */
 452          function getNumItems( $table, $cond = "", $pk = "id" )
 453          {
 454              // build up the query
 455              if( $cond != "" ) $cond = "WHERE $cond";
 456              $query = "SELECT COUNT($pk) AS total FROM $table $cond";
 457  
 458              // execute it
 459              $result = $this->Execute( $query );
 460  
 461              if( !$result )
 462                  return 0;
 463              
 464              // if no error, get the result
 465              $row = $result->FetchRow();
 466              $result->Close();            
 467  
 468              $total = $row["total"];
 469              if( $total == "" ) $total = 0;
 470  
 471              return $total;
 472          }
 473  
 474          /**
 475           * Initialize the Db and set the table-prefix.
 476           *
 477           * @private
 478           */
 479          function _initializeDb()
 480          {
 481              if ( !$this->_dbInitialized ) {
 482                  lt_include( PLOG_CLASS_PATH."class/database/db.class.php" );
 483  
 484                  $this->_db =& Db::getDb();
 485  
 486                  $this->_dbInitialized = true;
 487              }
 488          }
 489      }
 490  ?>


Généré le : Mon Nov 26 21:04:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics