%PDF- %PDF-
Direktori : /proc/1857783/root/var/www/pn/wp-content/plugins/wysija-newsletters/core/ |
Current File : //proc/1857783/root/var/www/pn/wp-content/plugins/wysija-newsletters/core/model.php |
<?php defined('WYSIJA') or die('Restricted access'); class WYSIJA_model extends WYSIJA_object{ var $table_prefix='wysija'; var $table_name=''; var $pk=''; var $values=array(); var $conditions=array(); var $orderby=array(); var $groupby=false; var $noCheck =false; var $replaceQRY=false; var $limitON=false; var $dbg=false; var $colCheck=true; var $getFormat=ARRAY_A; var $getOne=false; var $fieldValid=true; var $specialUpdate=false; var $escapeFields=array(); var $escapingOn=false; var $tableWP=false; var $columns=array(); var $joins=array(); var $ignore = false; var $sql_error = false; var $last_error = ''; var $comparisonKeys = array('equal', 'notequal', 'like', 'greater', 'less', 'greater_eq', 'less_eq', 'is'); var $time_start = 0; var $query_duration = 0; function __construct($extensions=''){ if(defined('WYSIJA_DBG') && WYSIJA_DBG>0) $this->dbg=true; global $wpdb; $this->wpdb = $wpdb; $this->wpprefix=$this->wpdb->prefix; if($extensions) $this->table_prefix=$extensions; } /** * since we reuse the same objects accross the whole application * once in a while for instance between a delete and a select we need to reset the objects to update the conditions */ function reset(){ $this->values = array(); $this->conditions = array(); $this->orderby = array(); $this->groupby = false; $this->getFormat = ARRAY_A; $this->getOne = false; $this->limitON = false; $this->sql_error = false; $this->last_error = ''; } /** * * @param type $columnsOrPKval * @param type $conditions * @return type */ function get($columnsOrPKval=false,$conditions=array()){ /*then columns becomes the pk value*/ if(!$conditions){ $conditions=array('equal'=>array($this->pk=>$columnsOrPKval)); $columnsOrPKval=false; $this->noCheck=true; } /* if we pass just the id strong in the get conditions then it's the pk*/ if($conditions && !is_array($conditions)){ $conditions=array('equal'=>array($this->pk=>$conditions)); } if($this->setConditions($conditions)){ if($this->getOne) $results=$this->getRows($columnsOrPKval,0,1); else $results=$this->getRows($columnsOrPKval); //$this->escapeQuotesFromRes($results); if($this->getOne && count($results)==1){ switch($this->getFormat){ case ARRAY_A: foreach($results as $res)return $res; break; case OBJECT: foreach($results as $res)return $res; break; } } else return $results; } return false; } function getOne($columnsOrPKval=false,$conditions=array()){ $this->getOne=true; $this->limitON=true; return $this->get($columnsOrPKval,$conditions); } /** * get a list of result based on a select query * @param type $columns * @param type $page * @param type $limit * @return type */ function getRows($columns=false,$page=0,$limit=false){ /*set the columns*/ if($columns !== false){ if(is_array($columns)){ foreach($columns as $column){ if(!isset($this->columns[$column])){ $this->error(sprintf('Column does not exist.')); return false; } } $columns=implode(', ',$columns); }else{ if(!isset($this->columns[$columns])){ $this->error(sprintf('Column does not exist.')); return false; } } }else{ $columns='*'; } $query='SELECT '.$columns.' FROM `'.$this->getSelectTableName()."`"; $query.=$this->makeJoins(); $query.=$this->makeWhere(); $query.=$this->makeGroupBY(); $query.=$this->makeOrderBY(); if($this->limitON) $query.=$this->setLimit($page,$limit); $results=$this->query('get_res',$query,$this->getFormat); //$this->escapeQuotesFromRes($results); return $results; } function escapeQuotesFromRes(&$results){ if(!$this->escapingOn) return false; foreach($results as $k =>$r){ if(in_array($this->getFormat,array(ARRAY_A,ARRAY_N))){ foreach($r as $k1 =>$v1){ if(in_array($k1,$this->escapeFields)){ $results[$k][$k1]= stripslashes($v1); } } } } } function setLimit($page=0,$limit=false){ /*set the limit of the selection*/ if(!$this->getOne){ if($page==0){ if(isset($_REQUEST['pagi'])){ $page=(int)$_REQUEST['pagi']; if($page!=0) $page=$page-1; } }else $page=$page-1; } if(!$limit){ if(isset($this->limit_pp)) $limit=$this->limit_pp; else{ $config=WYSIJA::get('config','model'); $limit=$config->getValue('limit_listing'); } } $this->limit=(int)$limit; $this->page=$page; $this->limit_start=(int)($this->page*$this->limit); $this->limit_end=(int)($this->limit_start+$this->limit); return " LIMIT $this->limit_start , $this->limit"; } /** * DEPRECATED * to have a custom query through the model and get the result immediately * @param type $query * @return type */ function getResults($query,$type=ARRAY_A){ return $this->query('get_res',$query, $type); } /** * to have a custom query through the model and get the result immediately * @param type $query * @return type */ public function get_results($query,$type=ARRAY_A){ return $this->getResults($query,$type); } function getSelectTableName(){ if($this->joins && isset($this->joins['tablestart'])){ if(isset($this->joins['prefstart'])) return $this->wpdb->prefix.$this->joins['prefstart'].'_'.$this->joins['tablestart']; else return $this->getPrefix().$this->joins['tablestart']; }else return $this->getPrefix().$this->table_name; } /** * simple SQL count * @return type */ function count($query=false,$keygetcount=false){ if(!$query){ $groupBy=$this->makeGroupBY(); $columnMore=''; if($groupBy) $columnMore=','.$this->groupby; $query='SELECT COUNT('.$this->getPk().') as count '.$columnMore.' FROM `'.$this->getSelectTableName().'`'; $query.=$this->makeJoins(); $query.=$this->makeWhere(); $query.=$groupBy; } // if dbg is on we track the duration of the query if($this->dbg){ $this->timer_start(); } $results=$this->query('get_res',$query,$this->getFormat); // if dbg is on we track the duration of the query if($this->dbg){ $this->timer_stop(); $this->keepQry('count'); } if(!$results || count($results)>1) return $results; else { if($keygetcount) return $results[0][$keygetcount]; else{ foreach($results[0] as $key => $count) return $count; } } return $results; } /** * make the SQL WHERE condition string * @return string */ function makeWhere(){ $query=''; if($this->conditions){ /*set the WHERE clause*/ $conditions=array(); foreach($this->conditions as $type=>$values){ if(!in_array($type, $this->comparisonKeys)){ $conditionsss=$this->conditions; $this->conditions=array(); $this->conditions['equal']=$conditionsss; break; } } foreach($this->conditions as $type=>$values){ if($type=='like' && count($values)>1){ if(is_array($values)){ $total=count($values); $i=1; $likeCond=''; foreach($values as $qfield => $qval){ $qval = html_entity_decode($qval, ENT_QUOTES); $likeCond.=$qfield." LIKE '%".esc_sql(addcslashes($qval, '%_' ))."%'"; if($i<$total){ $likeCond.=' OR '; } $i++; } $conditions[]='('.$likeCond.')'; } continue; } foreach($values as $condK => $condVal){ //secure from injections $this->_secureFieldVal($condK, $condVal); switch($type){ case 'equal': if(is_array($condVal)){ $conditions[]=$condK.' IN ("'.implode('","', $condVal).'")'; }else{ if(is_null($condVal)) { $conditions[] = $condK.' IS NULL'; } else { if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; $conditions[] = $condK.'='.$condVal; } } break; case 'notequal': if(is_array($condVal)){ $conditions[]=$condK.' NOT IN ("'.implode('","', $condVal).'")'; }else{ //this means that if I delete something with a list of ids and the array happens to be empty array of ids it will just delete everything by if(is_null($condVal)) { $conditions[] = $condK.' IS NOT NULL'; } else { if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; $conditions[] = $condK.' != '.$condVal; } } break; case 'like': $conditions[]=$condK." LIKE '%".esc_sql(addcslashes($condVal, '%_' ))."%'"; break; case 'greater': if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; $conditions[]=$condK.' > '.$condVal; break; case 'less': if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; $conditions[]=$condK.' < '.$condVal; break; case 'greater_eq': if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; $conditions[]=$condK.' >= '.$condVal; break; case 'less_eq': if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; $conditions[]=$condK.' <= '.$condVal; break; case 'is': $conditions[]=$condK.' '.$condVal; break; } } } $query.=' WHERE '.implode(' AND ',$conditions); } return $query; } /** * make the SQL ORDER BY condition string * @return string */ function makeOrderBY(){ $query=' ORDER BY '; if($this->orderby){ /*set the ORDER BY clause*/ $query.=$this->orderby.' '.$this->orderbyt; }else{ /*by default we order by pk desc*/ if(is_array($this->pk)) return ''; $query.=$this->pk.' DESC'; } return $query; } function makeJoins(){ if($this->joins){ $join=' as A'; $arrayLetters=array('B','C','D','E'); foreach($this->joins['tablejoins'] as $table => $fk){ $letter=array_shift($arrayLetters); $join.=' JOIN `'.$this->getPrefix().$table.'` AS '.$letter." on $letter.$fk=A.".$this->joins['keystart'].' '; } /*set the ORDER BY clause*/ return $join; }else return ''; } /** * make the SQL ORDER BY condition string * @return string */ function makeGroupBY(){ if($this->groupby){ /*set the ORDER BY clause*/ return ' GROUP BY '.$this->groupby; }else return ''; } function groupBy($name){ if (!is_string($name) OR preg_match('|[^a-z0-9#_.-]|i',$name) !== 0 ){ $this->groupby=false; }else $this->groupby=$name; } function orderBy($name,$type = 'ASC'){ if(is_array($name) and count($name) > 0) { // set order by to empty string $this->orderby = ''; $this->ordert = ''; // count number of arguments $count = count($name); // build order by query for($i = 0; $i < $count; $i++) { $value = current($name); //security escaping if(!is_string(key($name)) OR preg_match('|[^a-z0-9#_.-]|i',key($name)) !== 0 ){ $orderByCol=""; }else $orderByCol=key($name); //security escaping if(!is_string($value) OR preg_match('|[^a-z0-9#_.-]|i',$value) !== 0 ){ $orderByVal=""; }else $orderByVal=$value; if($i === ($count - 1)) { $this->orderby .= $orderByCol; $this->ordert = $orderByVal; } else { $this->orderby .=$orderByCol.' '.$orderByVal; $this->orderby .= ', '; next($name); } } } else if(!is_string($name) OR preg_match('|[^a-z0-9#_.-]|i',$name) !== 0 ){ $this->orderby=""; }else { $this->orderby=$name; } if(!in_array($type,array('DESC','ASC'))) $type = 'DESC'; $this->orderbyt=$type; } /** * prepare for an insert procedure * @param type $values */ function insert($values,$ignore=false){ if($ignore)$this->ignore=true; if($this->setValues($values)){ return $this->save(); }else{ $this->error(sprintf('missing values in model insert : %1$s.', get_class($this))); } } function replace($values=array()){ $this->replaceQRY=true; $this->insert($values); $this->replaceQRY=false; } /** * prepare for an update procedure * @param type $values * @param type $conditions */ function update($values=array(),$conditions=array()){ if($this->setValues($values)){ /*if no condition is set then we set it mannualy based on the primary key*/ if(!$conditions){ if(!$this->conditions){ if(isset($values[$this->pk]) && $values[$this->pk]){ $this->setConditions(array($this->pk => $values[$this->pk]), true); unset($values[$this->pk]); return $this->save(true); }else{ $this->error(sprintf('missing pk value in model update : %1$s.', get_class($this))); } } }else{ if($this->setConditions($conditions,true)){ return $this->save(true); }else{ $this->error(sprintf('missing conditions in model update : %1$s.', get_class($this))); } } }else{ $this->error(sprintf('missing values in model update : %1$s.', get_class($this))); } } /** * UPDATE with a special where condition * @param type $table * @param type $data * @param type $where * @param type $format * @param type $where_format * @return type */ function specialUpdate( $table, $data, $where, $format = null, $where_format = null ) { if ( ! is_array( $data ) || ! is_array( $where ) ) return false; $formats = $format = (array) $format; $bits = $wheres = array(); $i=0; foreach ( $data as $field => $val) { $this->_secureFieldVal($field,$val); switch($format[$i]){ case "%d": $bits[] = "`$field` = ".(int)$val; break; case '[increment]': $bits[] = "`$field` = ".$field.'+1'; break; case '[decrement]': $bits[] = "`$field` = ".$field.'-1'; break; default : $bits[] = "`$field` = '".$val."'"; } $i++; } $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' ' . $this->makeWhere(); return $this->query( $sql ); } function _secureFieldVal( &$field, &$mixed ) { if ( ! is_string( $field ) || preg_match( '|[^a-z0-9#_.-]|i', $field ) !== 0 ) { die('field "'.$field .'" not secured'); } if ( is_string( $mixed ) || is_numeric( $mixed ) || is_bool( $mixed ) ) { $mixed = esc_sql( $mixed ); } else { if(!empty($mixed) && is_array($mixed)){ foreach ( $mixed as $key => &$value ) { $this->_secureFieldVal( $field, $value ); } } } } /** * save information as an update or an insert * @param type $update * @return type */ function save($update=false){ if($update)$updateStr='Update'; else $updateStr='Insert'; $beforeSave='before'.$updateStr; $afterSave='after'.$updateStr; if(!$update && isset($this->columns['created_at']))$this->values['created_at']=time(); foreach($this->columns as $key => $params){ /*check for auto columns */ if((isset($params['autoup']) && $update) || (!$update && $key!='sent_at')){ if(isset($params['type']) && !isset($this->values[$key])){ switch($params['type']){ case 'date': $this->values[$key]=time(); break; case 'ip': $userHelper=WYSIJA::get("user","helper"); /*record the ip and save the user*/ $this->values[$key]=$userHelper->getIP(); break; case 'referer': /*record the ip and save the user*/ $this->values[$key]=$_SERVER['HTTP_REFERER']; break; } } } } if(method_exists($this,$beforeSave)){ if(!$this->$beforeSave()){ //$this->error(sprintf('Problem during validation "%2$s" in model : %1$s.', get_class($this), $beforeSave)); return false; } } /*prepare a format list for the update and insert function*/ $fieldsFormats=array(); if(!is_array($this->pk) && isset($this->values[$this->pk])) unset($this->values[$this->pk]); foreach($this->values as $key =>$val){ if(!isset($this->columns[$key]['html'])) $this->values[$key]=strip_tags($val); /* let's correct the type of the values based on the one defined in the model*/ if(in_array($val, array('[increment]','[decrement]'))){ $fieldsFormats[]=$val; $this->specialUpdate=true; }else{ //dbg($this->values); if(!isset($this->columns[$key]['type'])){ $this->columns[$key]['type']='default'; } switch($this->columns[$key]['type']){ case 'integer': case 'boolean': $fieldsFormats[]="%d"; break; default: $fieldsFormats[]="%s"; } } } if($this->fieldValid && !$this->validateFields()) { $this->error(__('Error Validating the fields',WYSIJA),true); $this->stay=true; return false; } // if dbg is on we track the duration of the query if($this->dbg){ $this->timer_start(); } if($update){ if( $this->specialUpdate || isset($this->conditions['equal']) || isset($this->conditions['notequal']) || isset($this->conditions['like'])){ $resultSave=$this->specialUpdate($this->getPrefix().$this->table_name,$this->values,$this->conditions,$fieldsFormats); $this->logError(); }else{ $this->wpdb->update($this->getPrefix().$this->table_name,$this->values,$this->conditions,$fieldsFormats); $this->logError(); $resultSave=$this->wpdb->result; } }else{ if($this->replaceQRY){ $resultSave=$this->wpdb->replace($this->getPrefix().$this->table_name,$this->values,$fieldsFormats); $this->logError(); }else{ if($this->ignore) $resultSave=$this->wpdb->insert($this->getPrefix().$this->table_name,$this->values,$fieldsFormats); else $resultSave=$this->wpdb->insert($this->getPrefix().$this->table_name,$this->values,$fieldsFormats); $this->logError(); //dbg('hello'); } } // if dbg is on we track the duration of the query if($this->dbg){ $this->timer_stop(); $this->keepQry('save'); } if(!$resultSave){ $this->wpdb->show_errors(); return false; }else{ if($update){ if(isset($this->conditions[$this->getPk()])){ $resultSave=$this->conditions[$this->getPk()]; }else{ if(isset($this->conditions[$this->getPk(1)])) $resultSave=$this->conditions[$this->getPk(1)]; } }else{ $resultSave=$this->wpdb->insert_id; } } $this->wpdb->flush(); if(method_exists($this,$afterSave)){ if(!$this->$afterSave($resultSave)){ //$this->error(sprintf('Problem during validation "%2$s" in model : %1$s.', get_class($this), $afterSave)); return false; } } return $resultSave; } function insertMany($values){ $fields=array_keys($values[0]); $query='INSERT INTO `'.$this->getPrefix().$this->table_name.'` (`' . implode( '`,`', $fields ) . '`) VALUES '; $total=count($values); $i=1; foreach($values as &$vals){ foreach($vals as &$v) $v=esc_sql($v); $query.= "('" . implode( "','", $vals )."')"; if($i<$total) $query.=','; $i++; } $this->query($query.$myvalues); } /** * validate the fields type(defined in each model) in the save procedure * @return type */ function validateFields(){ $error=false; foreach($this->values as $key =>$val){ if(isset($this->columns[$key]['req']) && !$val && !in_array( $this->columns[$key]['type'], array( 'boolean', 'integer' )) ){ $this->error(sprintf(__('Field "%1$s" is required in table "%2$s".',WYSIJA), $key,$this->table_name),true); $error=true; } /* let's correct the type of the values based on the one defined in the model*/ switch($this->columns[$key]['type']){ case 'email': $userHelper = WYSIJA::get('user','helper'); if(!$userHelper->validEmail($val)){ $this->error(sprintf(__('Field "%1$s" needs to be a valid Email.',WYSIJA), $key),true); $error=true; } break; } } if($error) return false; return true; } /** * delete procedure * @param type $conditions * @return type */ function delete($conditions){ $query='DELETE FROM `'.$this->getPrefix().$this->table_name.'`'; if($this->setConditions($conditions)){ $whereQuery=$this->makeWhere(); if(!$whereQuery){ $this->error('Cannot delete element without conditions in model : '.get_class($this)); } }else{ $this->error('Cannot delete element without conditions in model : '.get_class($this)); return false; } $result=$this->beforeDelete($conditions); if($result) $result=$this->query($query.$whereQuery); else return false; $this->afterDelete(); return true; } function exists($conditions){ $query='SELECT '.$this->getPk().' FROM `'.$this->getSelectTableName().'`'; $query.=$this->makeJoins(); if($this->setConditions($conditions)){ $whereQuery=$this->makeWhere(); if(!$whereQuery){ $this->error('Cannot test element without conditions in model : '.get_class($this)); } }else{ $this->error('Cannot test element without conditions in model : '.get_class($this)); return false; } $res=$this->query('get_res',$query.$whereQuery, ARRAY_A); if($res) return $res; else return false; } function getPk($numb=0){ $pk=$this->pk; if(is_array($pk)) $pk=$pk[$numb]; return $pk; } /** * set the values after verifying them * @param type $values * @return type */ function setValues($values){ if($this->colCheck && !$this->checkAreColumns($values)) return false; $this->values=array(); $this->values=$values; return true; } /** * * @param type $values * @return type */ function setJoin($joins){ $this->joins=$joins; return true; } /** * set the conditions after verifying them * @param type $conditions * @return type */ function setConditions($conditions,$update=false){ if($conditions && is_array($conditions)){ $this->conditions=array(); if($update){ foreach($conditions as $key =>$cond){ if($this->colCheck && !$this->checkAreColumns($conditions)) return false; if(is_array($cond)){ $this->specialUpdate=true; $this->conditions=$conditions; return true; }else $this->conditions[$key]=$cond; } } else { foreach($conditions as $key => $cond) { if(!in_array($key, $this->comparisonKeys /*array('like','equal','notequal','greater','less','greater_eq','less_eq')*/)){ if($this->colCheck && !$this->checkAreColumns($conditions)) return false; if(array_key_exists('equal', $this->conditions) === false) $this->conditions['equal'] = array(); $this->conditions['equal'][$key] = $cond; }else{ if($this->colCheck && !$this->checkAreColumns($cond)) return false; $this->conditions[$key]=$cond; } } } return true; }else return false; } /** * check that the columns corresponds to the columns in the model * @param type $arrayColumns * @return type */ function checkAreColumns($columns){ if($this->noCheck) return true; foreach($columns as $column => $values) { // skip when column is a comparison key if(in_array($column, $this->comparisonKeys)) continue; $columnName = $column; if(!isset($this->columns[$columnName])){ $this->error(sprintf('Column %1$s does not exist in model : %2$s', $columnName, get_class($this))); return false; } } return true; } function timer_start() { $this->query_duration = 0; $this->time_start = microtime( true ); return true; } function timer_stop() { $this->query_duration = ( microtime( true ) - $this->time_start ); } function query($query,$arg2='',$arg3=ARRAY_A){ $this->sql_error = false; if(!$arg2) $query = str_replace(array('[wysija]','[wp]'),array($this->getPrefix(),$this->wpdb->prefix),$query); else $arg2 = str_replace(array('[wysija]','[wp]'),array($this->getPrefix(),$this->wpdb->prefix),$arg2); // if dbg is on we track the duration of the query if($this->dbg){ $this->timer_start(); } switch($query){ case 'get_row': $result = $this->wpdb->get_row($arg2,$arg3); $this->logError(); break; case 'get_res': $result = $this->wpdb->get_results($arg2,$arg3); //$this->escapeQuotesFromRes($results); $this->logError(); break; default: $result = $this->wpdb->query($query); $this->logError(); // get the last insert id if it's an insert query if(substr($query, 0, 6) == 'INSERT') $result = $this->wpdb->insert_id; } // if dbg is on we track the duration of the query if($this->dbg){ $this->timer_stop(); $this->keepQry('query'); } return $result; } function logError(){ if(defined('WYSIJA_DBG') && WYSIJA_DBG>1){ global $wysija_queries_errors; if(!$wysija_queries_errors) $wysija_queries_errors = array(); $this->sql_error = $this->wpdb->last_error; if( $this->sql_error && ( empty( $this->last_error ) || $this->last_error != $this->sql_error )) { $this->last_error = $wysija_queries_errors[] = array('query' => $this->wpdb->last_query, 'error' => $this->sql_error); $this->sql_error = false; WYSIJA::log('queries_errors' , $this->sql_error , 'query_errors'); } } } function keepQry($from = 'wpdb'){ global $wysija_queries; $wysija_queries[$from][] = array('duration' => $this->query_duration , 'query' => $this->wpdb->last_query); } function getAffectedRows(){ return $this->wpdb->rows_affected; } function getErrorMsg(){ return $this->wpdb->show_errors(); } /** * get the full prefix for the table * @return type */ function getPrefix(){ if($this->tableWP) return $this->wpdb->prefix.$this->table_prefix; else return $this->wpdb->prefix.$this->table_prefix.'_'; } /** * this function allows you to get the prefix from the main site on a multisite * @return type */ function get_site_prefix($blog_id=1){ switch_to_blog( $blog_id ); $main_site_prefix=$this->wpdb->prefix; restore_current_blog(); if($this->tableWP) return $main_site_prefix.$this->table_prefix; else return $main_site_prefix.$this->table_prefix.'_'; } /** * * @param type $field_name name of field which will become a key * @param array $dataset list of records * @param boolean $removing_field_name decide if we should remove field name from output dataset * @param string $field_name_as_value a field in which we consider its value as value of $field_name * @return array field based indexed dataset */ protected function indexing_dataset_by_field($field_name, Array $dataset, $removing_field_name = false, $field_name_as_value = null){ if (empty($dataset)) return array(); $tmp = array(); foreach ($dataset as $record){ if (isset($record[$field_name])) { if (!empty($field_name_as_value)){ $tmp[$record[$field_name]] = isset($record[$field_name_as_value]) ? $record[$field_name_as_value] : null; continue; } $tmp[$record[$field_name]] = $record; if ($removing_field_name) unset($tmp[$record[$field_name]][$field_name]); } } return $tmp; } function beforeInsert(){ return true; } function afterInsert($resultSaveID){ return true; } function beforeDelete($conditions){ return true; } function afterDelete(){ return true; } function beforeUpdate($id = null){ return true; } function afterUpdate($resultSaveID){ return true; } }