aliroDatabaseRow.php

Go to the documentation of this file.
00001 <?php
00002 
00003 class aliroDBRowFactory {
00004 
00005     static public function makeObject ($classname, $key=null) {
00006         if (is_subclass_of($classname, 'aliroDBGeneralRow')) {
00007             $object = new $classname;
00008             if (!empty($key)) $object->load($key);
00009             return $object;
00010         }
00011         else trigger_error(T_('Asked aliroDBRowFactory to create object not subclassed from aliroDBGeneralRow'));
00012     }
00013 }
00014 
00015 abstract class aliroDBGeneralRow {
00016     public $_error = '';
00017 
00018     public function check() {
00019         return true;
00020     }
00021 
00022     public function getDatabase () {
00023         return call_user_func(array($this->DBclass, 'getInstance'));
00024     }
00025 
00026     public function getNumRows( $cur=null ) {
00027         return $this->getDatabase()->getNumRows($cur);
00028     }
00029 
00030     public function getAffectedRows () {
00031         return $this->getDatabase()->getAffectedRows();
00032     }
00033 
00034     public function insert () {
00035         return $this->getDatabase()->insertObject($this->tableName, $this, $this->rowKey);
00036     }
00037 
00038     public function update ($updateNulls=true) {
00039         return $this->getDatabase()->updateObject($this->tableName, $this, $this->rowKey, $updateNulls);
00040     }
00041 
00042     public function load( $key=null ) {
00043         $k = $this->rowKey;
00044         if (null !== $key) $this->$k = $key;
00045         if (empty($this->$k)) return false;
00046         $this->getDatabase()->setQuery("SELECT * FROM $this->tableName WHERE $this->rowKey='{$this->$k}'" );
00047         return $this->getDatabase()->loadObject($this);
00048     }
00049 
00050     public function store( $updateNulls=false ) {
00051         $k = $this->rowKey;
00052         $ret = $this->$k ? $this->update($updateNulls) : $this->insert();
00053         if (!$ret) $this->_error = strtolower(get_class( $this ))."::store failed <br />" . $this->getDatabase()->getErrorMsg();
00054         return $ret;
00055     }
00056 
00057     public function bind( $array, $ignore='', $strip=true ) {
00058         $fields = $this->getDatabase()->getAllFieldNames ($this->tableName);
00059         foreach ($fields as $key=>$field) if (false !== strpos($ignore, $field)) unset($fields[$key]);
00060         return $this->bindDoWork ($array, $fields, $strip);
00061     }
00062 
00063     public function bindOnly ($array, $accept='', $strip=true) {
00064         $fields = $this->getDatabase()->getAllFieldNames ($this->tableName);
00065         foreach ($fields as $key=>$field) if (false === strpos($accept, $field)) unset($fields[$key]);
00066         return $this->bindDoWork ($array, $fields, $strip);
00067     }
00068 
00069     private function bindDoWork ($array, $fields, $strip) {
00070         if (is_array($array)) {
00071             $request = aliroRequest::getInstance();
00072             foreach ($fields as $field) if (isset($array[$field])) {
00073                 $this->$field = $strip ? $this->stripMagicQuotes($array[$field]) : $array[$field];
00074                 if ('params' != $field AND (false !== strpos($this->$field, '&') OR false !== strpos($this->$field, '<'))) {
00075                     $this->$field = $request->doPurify($this->$field);
00076                 }
00077             }
00078             return true;
00079         }
00080         $this->_error = strtolower(get_class($this)).T_('::bind failed, parameter not an array');
00081         return false;
00082     }
00083     
00084     private function stripMagicQuotes ($field) {
00085         return (get_magic_quotes_gpc() AND is_string($field)) ? stripslashes($field) : $field;
00086     }
00087 
00088     public function lacks( $property ) {
00089         if (in_array($property, $this->getDatabase()->getAllFieldNames($this->tableName))) return false;
00090         $this->_error = sprintf (T_('WARNING: %s does not support %s.'), get_class($this), $property);
00091         return true;
00092     }
00093 
00094     public function move( $direction, $where='' ) {
00095         $compops = array (-1 => '<', 0 => '=', 1 => '>');
00096         $relation = $compops[($direction>0)-($direction<0)];
00097         $ordering = ($relation == '<' ? 'DESC' : 'ASC');
00098         $k = $this->rowKey;
00099         $o1 = $this->ordering;
00100         $k1 = $this->$k;
00101         $database = $this->getDatabase();
00102         $sql = "SELECT $k, ordering FROM $this->tableName WHERE ordering $relation $o1";
00103         $sql .= ($where ? "\n AND $where" : '').' ORDER BY ordering '.$ordering.' LIMIT 1';
00104         $database->setQuery( $sql );
00105         if ($database->loadObject($row)) {
00106             $o2 = $row->ordering;
00107             $k2 = $row->$k;
00108             $sql = "UPDATE $this->tableName SET ordering = (ordering=$o1)*$o2 + (ordering=$o2)*$o1 WHERE $k = $k1 OR $k = $k2";
00109             $database->doSQL($sql);
00110         }
00111     }
00112 
00113     // public function updateOrder( $where='', $cfid=null, $order=null ) {
00114     public function updateOrder ($where='', $sequence='', $orders=array()) {
00115         if ($this->lacks('ordering')) return false;
00116         $sql = "SELECT $this->rowKey, ordering FROM $this->tableName"
00117             .($where ? "\n WHERE $where" : '')
00118             ."\n ORDER BY ordering"
00119             .($sequence ? ','.$sequence : '');
00120         $rows = $this->getDatabase()->doSQLget($sql, 'stdClass', $this->rowKey);
00121         $allrows = array();
00122         foreach ($rows as $key=>$row) $allrows[(isset($orders[$key]) ? $orders[$key] : $row->ordering)] = $key;
00123         ksort($allrows);
00124         $cases = '';
00125         $order = 10;
00126         foreach ($allrows as $ordering=>$id) {
00127             if ($order != $rows[$id]->ordering) $cases .= " WHEN $this->rowKey = $id THEN $order ";
00128             $order += 10;
00129         }
00130         if ($cases) $this->getDatabase()->doSQL("UPDATE $this->tableName SET ordering = CASE ".$cases.' ELSE ordering END');
00131         return true;
00132     }
00133 
00134     // Caller needs to find out the number of affected rows, not rely on true or false return
00135     function delete( $key=null ) {
00136         $k = $this->rowKey;
00137         if ($key) $this->$k = intval( $key );
00138         $this->getDatabase()->doSQL( "DELETE FROM $this->tableName WHERE $this->rowKey = '".$this->$k."'" );
00139         return true;
00140     }
00141 
00142     function checkout( $who, $key=null ) {
00143         if ($this->lacks('checked_out')) return false;
00144         $k = $this->rowKey;
00145         if (null !== $key) $this->$k = $key;
00146         $time = date( "%Y-%m-%d H:i:s" );
00147         $this->getDatabase()->doSQL( "UPDATE $this->tableName"
00148         . "\nSET checked_out='$who', checked_out_time='$time'"
00149         . "\nWHERE $k='".$this->$k."'"
00150         );
00151         return true;
00152     }
00153 
00154     function checkin( $key=null ) {
00155         if ($this->lacks('checked_out')) return false;
00156         $k = $this->rowKey;
00157         if (null !== $key) $this->$k = $key;
00158         $this->getDatabase()->doSQL( "UPDATE $this->tableName"
00159         . "\nSET checked_out='0', checked_out_time='0000-00-00 00:00:00'"
00160         . "\nWHERE $k='".$this->$k."'"
00161         );
00162         return true;
00163     }
00164 
00165     function isCheckedOut ($userid=0) {
00166         return ($this->checked_out AND $userid != $this->checked_out) ? true : false;
00167     }
00168 
00169 }
00170 
00171 // This class provided for backwards compatibility
00172 abstract class mosDBTable extends aliroDBGeneralRow {
00173     protected $DBclass = 'aliroDatabase';
00174     public $_tbl = '';
00175     public $_tbl_key = '';
00176     protected $tableName = '';
00177     protected $rowKey = '';
00178 
00179     public function mosDBTable ($table='', $keyname='id') {
00180         $this->_tbl = $this->tableName = $table;
00181         $this->_tbl_key = $this->rowKey = $keyname;
00182     }
00183 
00184     function __call ($method, $args) {
00185         if ('mosDBTable' == $method) {
00186             call_user_func_array(array($this, '__construct'), $args);
00187         }
00188         else trigger_error(T_('Invalid method call to mosDBTable'));
00189     }
00190 
00191     protected function __get ($name) {
00192         if ($name == '_db') return call_user_func (array($this->DBclass, 'getInstance'));
00193         else return null;
00194     }
00195 
00196     function filter( $ignoreList=null ) {
00197         $request = aliroRequest::getInstance();
00198         foreach ($this->getDatabase()->getAllFieldNames($this->tableName) as $k) {
00199             if (!is_array($ignoreList) OR !in_array($k, $ignoreList)) {
00200                 $this->$k = $request->doPurify($this->$k);
00201             }
00202         }
00203     }
00204 
00205     function getError() {
00206         return $this->_error;
00207     }
00208 
00209     function get( $_property ) {
00210         return isset($this->$_property) ? $this->$_property :null;
00211     }
00212 
00213     function set( $_property, $_value ) {
00214         $this->$_property = $_value;
00215     }
00216 
00217     function reset ($value=null) {
00218         foreach ($this->getDatabase()->getAllFieldNames($this->tableName) as $k) $this->$k = $value;
00219     }
00220 
00221     function hit( $keyvalue=null ) {
00222         $k = $this->rowKey;
00223         if (null !== $keyvalue) $this->$k = intval($keyvalue);
00224         $this->getDatabase()->doSQL( "UPDATE $this->tableName SET hits=(hits+1) WHERE $this->rowKey='{$this->$k}'" );
00225 
00226         if (aliroRequest::getInstance()->getCfg('enable_log_items')) {
00227             $now = date( "Y-m-d" );
00228             $this->getDatabase()->doSQL("INSERT INTO #__core_log_items VALUES"
00229                 ."\n ('$now','$this->tableName','".$this->$k."','1')"
00230                 ."\n ON DUPLICATE KEY UPDATE hits=(hits+1)");
00231         }
00232     }
00233 
00234     function save( $source, $order_filter ) {
00235         if (!$this->bind($source) OR !$this->check() OR !$this->store()OR !$this->checkin()) return false;
00236         $this->updateOrder( ($order_filter AND !empty($this->$order_filter)) ? "`$order_filter`='{$this->getDatabase()->getEscaped($this->$order_filter)}'" : "" );
00237         $this->_error = '';
00238         return true;
00239     }
00240 
00241     function publish_array( $cid=null, $publish=1, $myid=0 ) {
00242         if (!is_array( $cid ) OR count( $cid ) < 1) {
00243             $this->_error = "No items selected.";
00244             return false;
00245         }
00246         foreach ($cid as $i=>$id) $cid[$i] = intval($id);
00247         $cids = implode( ',', $cid );
00248         $publish = $publish ? 1 : 0;
00249         $myid = intval($myid);
00250         $this->getDatabase()->doSQL( "UPDATE $this->tableName SET published=$publish"
00251         . "\nWHERE $this->rowKey IN ($cids) AND (checked_out=0 OR checked_out=$myid)"
00252         );
00253         return true;
00254     }
00255 
00256     function publish( $cid=null, $publish=1, $user_id=0 ) {
00257         $this->publish_array($cid, $publish, $myid);
00258     }
00259 
00260     function toXML( $mapKeysToText=false ) {
00261         if ($mapKeysToText) $attrib = ' mapkeystotext="true"';
00262         $middle = '';
00263         foreach ($this->getDatabase()->getAllFieldNames($this->tableName) as $k) {
00264             $v = $this->$k;
00265             if (is_null($v) OR is_array($v) OR is_object($v) OR (is_string($v) AND '_' == $v[0])) continue;
00266             $middle .= "<$k><![CDATA[$v]]></$k>";
00267         }
00268         return <<<TO_XML
00269 <record table="$this->tableName"$attrib>
00270 $middle
00271 </record>
00272 TO_XML;
00273 
00274     }
00275 }
00276 
00288 abstract class aliroDatabaseRow extends aliroDBGeneralRow {
00289 
00290     function __get ($property) {
00291         $database = $this->getDatabase();
00292         if ('_db' == $property) return $database;
00293         $field = $database->getFieldInfo ($this->tableName, $property);
00294         if (!is_object($field)) trigger_error(T_('Database row attempt to obtain invalid property: ').$property);
00295         else if ('auto_increment' == $field->Extra) return 0;
00296         return $field ? $field->Default : null;
00297     }
00298 
00299     /* Provided in case child class does not implement it.  Can force any values */
00300     /* within some limited range.  In particular, can force bools to be 0 or 1 */
00301     function forceBools () {
00302         return;
00303     }
00304 
00305     /* Provided in case the child class does not provide a method for timeStampField */
00306     function timeStampField () {
00307         return '';
00308     }
00309 
00310     /* Default method for identifying fields not to be written to the DB */
00311     /* The child classes may override this and return more items in the array */
00312     function notSQL () {
00313         return array ($this->rowKey);
00314     }
00315 
00316 }

Generated on Thu Apr 17 13:03:26 2008 for ALIRO by  doxygen 1.5.5