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
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
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
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
00300
00301 function forceBools () {
00302 return;
00303 }
00304
00305
00306 function timeStampField () {
00307 return '';
00308 }
00309
00310
00311
00312 function notSQL () {
00313 return array ($this->rowKey);
00314 }
00315
00316 }