WYSIJA_model

The MailPoet Newsletters WYSIJA model class.

Defined (1)

The class is defined in the following location(s).

/core/model.php  
  1. class WYSIJA_model extends WYSIJA_object{ 
  2.  
  3. var $table_prefix='wysija'; 
  4. var $table_name=''; 
  5. var $pk=''; 
  6. var $values=array(); 
  7. var $conditions=array(); 
  8. var $orderby=array(); 
  9. var $groupby=false; 
  10. var $noCheck =false; 
  11. var $replaceQRY=false; 
  12. var $limitON=false; 
  13. var $dbg=false; 
  14. var $colCheck=true; 
  15. var $getFormat=ARRAY_A; 
  16. var $getOne=false; 
  17. var $fieldValid=true; 
  18. var $specialUpdate=false; 
  19. var $escapeFields=array(); 
  20. var $escapingOn=false; 
  21. var $tableWP=false; 
  22. var $columns=array(); 
  23. var $joins=array(); 
  24. var $ignore = false; 
  25. var $sql_error = false; 
  26. var $last_error = ''; 
  27. var $comparisonKeys = array('equal', 'notequal', 'like', 'greater', 'less', 'greater_eq', 'less_eq', 'is'); 
  28. var $time_start = 0; 
  29. var $query_duration = 0; 
  30.  
  31. function __construct($extensions='') { 
  32. if(defined('WYSIJA_DBG') && WYSIJA_DBG>0) $this->dbg=true; 
  33. global $wpdb; 
  34. $this->wpdb = $wpdb; 
  35. $this->wpprefix=$this->wpdb->prefix; 
  36. if($extensions) $this->table_prefix=$extensions; 
  37. /** 
  38. * since we reuse the same objects accross the whole application 
  39. * once in a while for instance between a delete and a select we need to reset the objects to update the conditions 
  40. */ 
  41. function reset() { 
  42. $this->values = array(); 
  43. $this->conditions = array(); 
  44. $this->orderby = array(); 
  45. $this->groupby = false; 
  46. $this->getFormat = ARRAY_A; 
  47. $this->getOne = false; 
  48. $this->limitON = false; 
  49. $this->sql_error = false; 
  50. $this->last_error = ''; 
  51.  
  52. /** 
  53. * @param type $columnsOrPKval 
  54. * @param type $conditions 
  55. * @return type 
  56. */ 
  57. function get($columnsOrPKval=false, $conditions=array()) { 
  58. /**then columns becomes the pk value*/ 
  59. if(!$conditions) { 
  60. $conditions=array('equal'=>array($this->pk=>$columnsOrPKval)); 
  61. $columnsOrPKval=false; 
  62. $this->noCheck=true; 
  63.  
  64. /** if we pass just the id strong in the get conditions then it's the pk*/ 
  65. if($conditions && !is_array($conditions)) { 
  66. $conditions=array('equal'=>array($this->pk=>$conditions)); 
  67. if($this->setConditions($conditions)) { 
  68. if($this->getOne) $results=$this->getRows($columnsOrPKval, 0, 1); 
  69. else $results=$this->getRows($columnsOrPKval); 
  70. //$this->escapeQuotesFromRes($results); 
  71. if($this->getOne && count($results)==1) { 
  72. switch($this->getFormat) { 
  73. case ARRAY_A: 
  74. foreach($results as $res)return $res; 
  75. break; 
  76. case OBJECT: 
  77. foreach($results as $res)return $res; 
  78. break; 
  79. else return $results; 
  80.  
  81. return false; 
  82.  
  83. function getOne($columnsOrPKval=false, $conditions=array()) { 
  84. $this->getOne=true; 
  85. $this->limitON=true; 
  86.  
  87. return $this->get($columnsOrPKval, $conditions); 
  88.  
  89. /** 
  90. * get a list of result based on a select query 
  91. * @param type $columns 
  92. * @param type $page 
  93. * @param type $limit 
  94. * @return type 
  95. */ 
  96. function getRows($columns=false, $page=0, $limit=false) { 
  97.  
  98. /**set the columns*/ 
  99. if($columns !== false) { 
  100. if(is_array($columns)) { 
  101.  
  102. foreach($columns as $column) { 
  103.  
  104. if(!isset($this->columns[$column])) { 
  105. $this->error(sprintf('Column does not exist.')); 
  106. return false; 
  107. $columns=implode(', ', $columns); 
  108. }else{ 
  109. if(!isset($this->columns[$columns])) { 
  110. $this->error(sprintf('Column does not exist.')); 
  111. return false; 
  112. }else{ 
  113. $columns='*'; 
  114.  
  115.  
  116.  
  117. $query='SELECT '.$columns.' FROM `'.$this->getSelectTableName()."`"; 
  118. $query.=$this->makeJoins(); 
  119. $query.=$this->makeWhere(); 
  120. $query.=$this->makeGroupBY(); 
  121. $query.=$this->makeOrderBY(); 
  122.  
  123. if($this->limitON) $query.=$this->setLimit($page, $limit); 
  124. $results=$this->query('get_res', $query, $this->getFormat); 
  125.  
  126. //$this->escapeQuotesFromRes($results); 
  127.  
  128. return $results; 
  129.  
  130. function escapeQuotesFromRes(&$results) { 
  131. if(!$this->escapingOn) return false; 
  132. foreach($results as $k =>$r) { 
  133.  
  134. if(in_array($this->getFormat, array(ARRAY_A, ARRAY_N))) { 
  135. foreach($r as $k1 =>$v1) { 
  136. if(in_array($k1, $this->escapeFields)) { 
  137. $results[$k][$k1]= stripslashes($v1); 
  138.  
  139. function setLimit($page=0, $limit=false) { 
  140. /**set the limit of the selection*/ 
  141.  
  142. if(!$this->getOne) { 
  143. if($page==0) { 
  144. if(isset($_REQUEST['pagi'])) { 
  145. $page=(int)$_REQUEST['pagi']; 
  146. if($page!=0) $page=$page-1; 
  147.  
  148. }else $page=$page-1; 
  149.  
  150. if(!$limit) { 
  151. if(isset($this->limit_pp)) $limit=$this->limit_pp; 
  152. else{ 
  153. $config=WYSIJA::get('config', 'model'); 
  154. $limit=$config->getValue('limit_listing'); 
  155.  
  156. $this->limit=(int)$limit; 
  157. $this->page=$page; 
  158. $this->limit_start=(int)($this->page*$this->limit); 
  159. $this->limit_end=(int)($this->limit_start+$this->limit); 
  160.  
  161. return " LIMIT $this->limit_start , $this->limit"; 
  162.  
  163. /** 
  164. * DEPRECATED 
  165. * to have a custom query through the model and get the result immediately 
  166. * @param type $query 
  167. * @return type 
  168. */ 
  169. function getResults($query, $type=ARRAY_A) { 
  170. return $this->query('get_res', $query, $type); 
  171.  
  172. /** 
  173. * to have a custom query through the model and get the result immediately 
  174. * @param type $query 
  175. * @return type 
  176. */ 
  177. public function get_results($query, $type=ARRAY_A) { 
  178. return $this->getResults($query, $type); 
  179.  
  180.  
  181. function getSelectTableName() { 
  182. if($this->joins && isset($this->joins['tablestart'])) { 
  183. if(isset($this->joins['prefstart'])) return $this->wpdb->prefix.$this->joins['prefstart'].'_'.$this->joins['tablestart']; 
  184. else return $this->getPrefix().$this->joins['tablestart']; 
  185. }else return $this->getPrefix().$this->table_name; 
  186.  
  187. /** 
  188. * simple SQL count 
  189. * @return type 
  190. */ 
  191. function count($query=false, $keygetcount=false) { 
  192. if(!$query) { 
  193. $groupBy=$this->makeGroupBY(); 
  194. $columnMore=''; 
  195. if($groupBy) $columnMore=', '.$this->groupby; 
  196. $query='SELECT COUNT('.$this->getPk().') as count '.$columnMore.' FROM `'.$this->getSelectTableName().'`'; 
  197. $query.=$this->makeJoins(); 
  198.  
  199. $query.=$this->makeWhere(); 
  200. $query.=$groupBy; 
  201.  
  202.  
  203. // if dbg is on we track the duration of the query 
  204. if($this->dbg) { 
  205. $this->timer_start(); 
  206. $results=$this->query('get_res', $query, $this->getFormat); 
  207.  
  208. // if dbg is on we track the duration of the query 
  209. if($this->dbg) { 
  210. $this->timer_stop(); 
  211. $this->keepQry('count'); 
  212.  
  213. if(!$results || count($results)>1) return $results; 
  214. else { 
  215. if($keygetcount) return $results[0][$keygetcount]; 
  216. else{ 
  217. foreach($results[0] as $key => $count) return $count; 
  218.  
  219.  
  220. return $results; 
  221.  
  222. /** 
  223. * make the SQL WHERE condition string 
  224. * @return string 
  225. */ 
  226. function makeWhere() { 
  227. $query=''; 
  228. if($this->conditions) { 
  229. /**set the WHERE clause*/ 
  230. $conditions=array(); 
  231. foreach($this->conditions as $type=>$values) { 
  232. if(!in_array($type, $this->comparisonKeys)) { 
  233. $conditionsss=$this->conditions; 
  234. $this->conditions=array(); 
  235. $this->conditions['equal']=$conditionsss; 
  236.  
  237. break; 
  238. foreach($this->conditions as $type=>$values) { 
  239. if($type=='like' && count($values)>1) { 
  240. if(is_array($values)) { 
  241. $total=count($values); 
  242. $i=1; 
  243. $likeCond=''; 
  244. foreach($values as $qfield => $qval) { 
  245. $qval = html_entity_decode($qval, ENT_QUOTES); 
  246. $likeCond.=$qfield." LIKE '%".esc_sql(addcslashes($qval, '%_' ))."%'"; 
  247. if($i<$total) { 
  248. $likeCond.=' OR '; 
  249. $i++; 
  250. $conditions[]='('.$likeCond.')'; 
  251. continue; 
  252.  
  253. foreach($values as $condK => $condVal) { 
  254.  
  255. //secure from injections 
  256. $this->_secureFieldVal($condK, $condVal); 
  257.  
  258. switch($type) { 
  259. case 'equal': 
  260. if(is_array($condVal)) { 
  261. $conditions[]=$condK.' IN ("'.implode('", "', $condVal).'")'; 
  262. }else{ 
  263. if(is_null($condVal)) { 
  264. $conditions[] = $condK.' IS NULL'; 
  265. } else { 
  266. if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; 
  267. $conditions[] = $condK.'='.$condVal; 
  268. break; 
  269. case 'notequal': 
  270. if(is_array($condVal)) { 
  271. $conditions[]=$condK.' NOT IN ("'.implode('", "', $condVal).'")'; 
  272. }else{ 
  273. //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 
  274. if(is_null($condVal)) { 
  275. $conditions[] = $condK.' IS NOT NULL'; 
  276. } else { 
  277. if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; 
  278. $conditions[] = $condK.' != '.$condVal; 
  279. break; 
  280. case 'like': 
  281. $conditions[]=$condK." LIKE '%".esc_sql(addcslashes($condVal, '%_' ))."%'"; 
  282. break; 
  283. case 'greater': 
  284. if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; 
  285. $conditions[]=$condK.' > '.$condVal; 
  286. break; 
  287. case 'less': 
  288. if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; 
  289. $conditions[]=$condK.' < '.$condVal; 
  290. break; 
  291. case 'greater_eq': 
  292. if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; 
  293. $conditions[]=$condK.' >= '.$condVal; 
  294. break; 
  295. case 'less_eq': 
  296. if(is_numeric($condVal) === false) $condVal = '"'.$condVal.'"'; 
  297. $conditions[]=$condK.' <= '.$condVal; 
  298. break; 
  299. case 'is': 
  300.  
  301. $conditions[]=$condK.' '.$condVal; 
  302. break; 
  303.  
  304.  
  305. $query.=' WHERE '.implode(' AND ', $conditions); 
  306.  
  307. return $query; 
  308.  
  309. /** 
  310. * make the SQL ORDER BY condition string 
  311. * @return string 
  312. */ 
  313. function makeOrderBY() { 
  314. $query=' ORDER BY '; 
  315. if($this->orderby) { 
  316. /**set the ORDER BY clause*/ 
  317. $query.=$this->orderby.' '.$this->orderbyt; 
  318. }else{ 
  319. /**by default we order by pk desc*/ 
  320. if(is_array($this->pk)) return ''; 
  321. $query.=$this->pk.' DESC'; 
  322. return $query; 
  323.  
  324.  
  325. function makeJoins() { 
  326.  
  327. if($this->joins) { 
  328. $join=' as A'; 
  329. $arrayLetters=array('B', 'C', 'D', 'E'); 
  330. foreach($this->joins['tablejoins'] as $table => $fk) { 
  331. $letter=array_shift($arrayLetters); 
  332. $join.=' JOIN `'.$this->getPrefix().$table.'` AS '.$letter." on $letter.$fk=A.".$this->joins['keystart'].' '; 
  333. /**set the ORDER BY clause*/ 
  334. return $join; 
  335. }else return ''; 
  336.  
  337. /** 
  338. * make the SQL ORDER BY condition string 
  339. * @return string 
  340. */ 
  341. function makeGroupBY() { 
  342.  
  343. if($this->groupby) { 
  344. /**set the ORDER BY clause*/ 
  345. return ' GROUP BY '.$this->groupby; 
  346. }else return ''; 
  347.  
  348. function groupBy($name) { 
  349.  
  350. if (!is_string($name) OR preg_match('|[^a-z0-9#_.-]|i', $name) !== 0 ) { 
  351. $this->groupby=false; 
  352. }else $this->groupby=$name; 
  353. function orderBy($name, $type = 'ASC') { 
  354.  
  355. if(is_array($name) and count($name) > 0) { 
  356. // set order by to empty string 
  357. $this->orderby = ''; 
  358. $this->ordert = ''; 
  359.  
  360. // count number of arguments 
  361. $count = count($name); 
  362.  
  363. // build order by query 
  364. for($i = 0; $i < $count; $i++) { 
  365.  
  366. $value = current($name); 
  367.  
  368. //security escaping 
  369. if(!is_string(key($name)) OR preg_match('|[^a-z0-9#_.-]|i', key($name)) !== 0 ) { 
  370. $orderByCol=""; 
  371. }else $orderByCol=key($name); 
  372. //security escaping 
  373. if(!is_string($value) OR preg_match('|[^a-z0-9#_.-]|i', $value) !== 0 ) { 
  374. $orderByVal=""; 
  375. }else $orderByVal=$value; 
  376.  
  377. if($i === ($count - 1)) { 
  378. $this->orderby .= $orderByCol; 
  379. $this->ordert = $orderByVal; 
  380. } else { 
  381. $this->orderby .=$orderByCol.' '.$orderByVal; 
  382. $this->orderby .= ', '; 
  383. next($name); 
  384. } else if(!is_string($name) OR preg_match('|[^a-z0-9#_.-]|i', $name) !== 0 ) { 
  385. $this->orderby=""; 
  386. }else { 
  387. $this->orderby=$name; 
  388.  
  389. if(!in_array($type, array('DESC', 'ASC'))) $type = 'DESC'; 
  390. $this->orderbyt=$type; 
  391.  
  392.  
  393.  
  394. /** 
  395. * prepare for an insert procedure 
  396. * @param type $values 
  397. */ 
  398. function insert($values, $ignore=false) { 
  399. if($ignore)$this->ignore=true; 
  400. if($this->setValues($values)) { 
  401. return $this->save(); 
  402. }else{ 
  403. $this->error(sprintf('missing values in model insert : %1$s.', get_class($this))); 
  404.  
  405.  
  406. function replace($values=array()) { 
  407. $this->replaceQRY=true; 
  408. $this->insert($values); 
  409. $this->replaceQRY=false; 
  410.  
  411. /** 
  412. * prepare for an update procedure 
  413. * @param type $values 
  414. * @param type $conditions 
  415. */ 
  416. function update($values=array(), $conditions=array()) { 
  417.  
  418. if($this->setValues($values)) { 
  419. /**if no condition is set then we set it mannualy based on the primary key*/ 
  420. if(!$conditions) { 
  421. if(!$this->conditions) { 
  422. if(isset($values[$this->pk]) && $values[$this->pk]) { 
  423.  
  424. $this->setConditions(array($this->pk => $values[$this->pk]), true); 
  425.  
  426. unset($values[$this->pk]); 
  427.  
  428. return $this->save(true); 
  429.  
  430. }else{ 
  431. $this->error(sprintf('missing pk value in model update : %1$s.', get_class($this))); 
  432.  
  433. }else{ 
  434. if($this->setConditions($conditions, true)) { 
  435. return $this->save(true); 
  436. }else{ 
  437. $this->error(sprintf('missing conditions in model update : %1$s.', get_class($this))); 
  438.  
  439. }else{ 
  440. $this->error(sprintf('missing values in model update : %1$s.', get_class($this))); 
  441.  
  442. /** 
  443. * UPDATE with a special where condition 
  444. * @param type $table 
  445. * @param type $data 
  446. * @param type $where 
  447. * @param type $format 
  448. * @param type $where_format 
  449. * @return type 
  450. */ 
  451. function specialUpdate( $table, $data, $where, $format = null, $where_format = null ) { 
  452. if ( ! is_array( $data ) || ! is_array( $where ) ) 
  453. return false; 
  454.  
  455. $formats = $format = (array) $format; 
  456. $bits = $wheres = array(); 
  457.  
  458. $i=0; 
  459. foreach ( $data as $field => $val) { 
  460. $this->_secureFieldVal($field, $val); 
  461.  
  462. switch($format[$i]) { 
  463. case "%d": 
  464. $bits[] = "`$field` = ".(int)$val; 
  465. break; 
  466. case '[increment]': 
  467. $bits[] = "`$field` = ".$field.'+1'; 
  468. break; 
  469. case '[decrement]': 
  470. $bits[] = "`$field` = ".$field.'-1'; 
  471. break; 
  472. default : 
  473. $bits[] = "`$field` = '".$val."'"; 
  474. $i++; 
  475.  
  476. $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' ' . $this->makeWhere(); 
  477. return $this->query( $sql ); 
  478.  
  479.  
  480. function _secureFieldVal( &$field, &$mixed ) { 
  481. if ( ! is_string( $field ) || preg_match( '|[^a-z0-9#_.-]|i', $field ) !== 0 ) { 
  482. die('field "'.$field .'" not secured'); 
  483. if ( is_string( $mixed ) || is_numeric( $mixed ) || is_bool( $mixed ) ) { 
  484. $mixed = esc_sql( $mixed ); 
  485. } else { 
  486. if(!empty($mixed) && is_array($mixed)) { 
  487. foreach ( $mixed as $key => &$value ) { 
  488. $this->_secureFieldVal( $field, $value ); 
  489. /** 
  490. * save information as an update or an insert 
  491. * @param type $update 
  492. * @return type 
  493. */ 
  494. function save($update=false) { 
  495.  
  496. if($update)$updateStr='Update'; 
  497. else $updateStr='Insert'; 
  498. $beforeSave='before'.$updateStr; 
  499. $afterSave='after'.$updateStr; 
  500.  
  501.  
  502.  
  503. if(!$update && isset($this->columns['created_at']))$this->values['created_at']=time(); 
  504. foreach($this->columns as $key => $params) { 
  505. /**check for auto columns */ 
  506. if((isset($params['autoup']) && $update) || (!$update && $key!='sent_at')) { 
  507. if(isset($params['type']) && !isset($this->values[$key])) { 
  508. switch($params['type']) { 
  509. case 'date': 
  510. $this->values[$key]=time(); 
  511. break; 
  512. case 'ip': 
  513. $userHelper=WYSIJA::get("user", "helper"); 
  514. /**record the ip and save the user*/ 
  515. $this->values[$key]=$userHelper->getIP(); 
  516. break; 
  517. case 'referer': 
  518. /**record the ip and save the user*/ 
  519. $this->values[$key]=$_SERVER['HTTP_REFERER']; 
  520. break; 
  521.  
  522.  
  523. if(method_exists($this, $beforeSave)) { 
  524. if(!$this->$beforeSave()) { 
  525. //$this->error(sprintf('Problem during validation "%2$s" in model : %1$s.', get_class($this), $beforeSave)); 
  526. return false; 
  527.  
  528. /**prepare a format list for the update and insert function*/ 
  529. $fieldsFormats=array(); 
  530. if(!is_array($this->pk) && isset($this->values[$this->pk])) unset($this->values[$this->pk]); 
  531. foreach($this->values as $key =>$val) { 
  532. if(!isset($this->columns[$key]['html'])) $this->values[$key]=strip_tags($val); 
  533. /** let's correct the type of the values based on the one defined in the model*/ 
  534. if(in_array($val, array('[increment]', '[decrement]'))) { 
  535. $fieldsFormats[]=$val; 
  536. $this->specialUpdate=true; 
  537. }else{ 
  538. //dbg($this->values); 
  539. if(!isset($this->columns[$key]['type'])) { 
  540. $this->columns[$key]['type']='default'; 
  541. switch($this->columns[$key]['type']) { 
  542. case 'integer': 
  543. case 'boolean': 
  544. $fieldsFormats[]="%d"; 
  545. break; 
  546. default: 
  547. $fieldsFormats[]="%s"; 
  548.  
  549.  
  550.  
  551. if($this->fieldValid && !$this->validateFields()) { 
  552. $this->error(__('Error Validating the fields', WYSIJA), true); 
  553. $this->stay=true; 
  554. return false; 
  555.  
  556. // if dbg is on we track the duration of the query 
  557. if($this->dbg) { 
  558. $this->timer_start(); 
  559.  
  560. if($update) { 
  561.  
  562. if( $this->specialUpdate || isset($this->conditions['equal']) || isset($this->conditions['notequal']) || isset($this->conditions['like'])) { 
  563.  
  564. $resultSave=$this->specialUpdate($this->getPrefix().$this->table_name, $this->values, $this->conditions, $fieldsFormats); 
  565. $this->logError(); 
  566. }else{ 
  567.  
  568. $this->wpdb->update($this->getPrefix().$this->table_name, $this->values, $this->conditions, $fieldsFormats); 
  569. $this->logError(); 
  570. $resultSave=$this->wpdb->result; 
  571.  
  572. }else{ 
  573. if($this->replaceQRY) { 
  574. $resultSave=$this->wpdb->replace($this->getPrefix().$this->table_name, $this->values, $fieldsFormats); 
  575. $this->logError(); 
  576. }else{ 
  577.  
  578. if($this->ignore) $resultSave=$this->wpdb->insert($this->getPrefix().$this->table_name, $this->values, $fieldsFormats); 
  579. else $resultSave=$this->wpdb->insert($this->getPrefix().$this->table_name, $this->values, $fieldsFormats); 
  580.  
  581. $this->logError(); 
  582. //dbg('hello'); 
  583.  
  584.  
  585. // if dbg is on we track the duration of the query 
  586. if($this->dbg) { 
  587. $this->timer_stop(); 
  588. $this->keepQry('save'); 
  589.  
  590. if(!$resultSave) { 
  591. $this->wpdb->show_errors(); 
  592. return false; 
  593. }else{ 
  594. if($update) { 
  595. if(isset($this->conditions[$this->getPk()])) { 
  596. $resultSave=$this->conditions[$this->getPk()]; 
  597. }else{ 
  598. if(isset($this->conditions[$this->getPk(1)])) $resultSave=$this->conditions[$this->getPk(1)]; 
  599.  
  600. }else{ 
  601. $resultSave=$this->wpdb->insert_id; 
  602.  
  603. $this->wpdb->flush(); 
  604.  
  605. if(method_exists($this, $afterSave)) { 
  606. if(!$this->$afterSave($resultSave)) { 
  607. //$this->error(sprintf('Problem during validation "%2$s" in model : %1$s.', get_class($this), $afterSave)); 
  608. return false; 
  609. return $resultSave; 
  610.  
  611.  
  612. function insertMany($values) { 
  613. $fields=array_keys($values[0]); 
  614.  
  615. $query='INSERT INTO `'.$this->getPrefix().$this->table_name.'` (`' . implode( '`, `', $fields ) . '`) VALUES '; 
  616.  
  617. $total=count($values); 
  618. $i=1; 
  619. foreach($values as &$vals) { 
  620. foreach($vals as &$v) $v=esc_sql($v); 
  621. $query.= "('" . implode( "', '", $vals )."')"; 
  622. if($i<$total) $query.=', '; 
  623. $i++; 
  624.  
  625. $this->query($query.$myvalues); 
  626.  
  627.  
  628. /** 
  629. * validate the fields type(defined in each model) in the save procedure 
  630. * @return type 
  631. */ 
  632. function validateFields() { 
  633. $error=false; 
  634. foreach($this->values as $key =>$val) { 
  635. if(isset($this->columns[$key]['req']) && !$val && !in_array( $this->columns[$key]['type'], array( 'boolean', 'integer' )) ) { 
  636. $this->error(sprintf(__('Field "%1$s" is required in table "%2$s".', WYSIJA), $key, $this->table_name), true); 
  637. $error=true; 
  638. /** let's correct the type of the values based on the one defined in the model*/ 
  639. switch($this->columns[$key]['type']) { 
  640. case 'email': 
  641. $userHelper = WYSIJA::get('user', 'helper'); 
  642. if(!$userHelper->validEmail($val)) { 
  643. $this->error(sprintf(__('Field "%1$s" needs to be a valid Email.', WYSIJA), $key), true); 
  644. $error=true; 
  645. break; 
  646.  
  647. if($error) return false; 
  648. return true; 
  649.  
  650. /** 
  651. * delete procedure 
  652. * @param type $conditions 
  653. * @return type 
  654. */ 
  655. function delete($conditions) { 
  656. $query='DELETE FROM `'.$this->getPrefix().$this->table_name.'`'; 
  657.  
  658. if($this->setConditions($conditions)) { 
  659. $whereQuery=$this->makeWhere(); 
  660. if(!$whereQuery) { 
  661. $this->error('Cannot delete element without conditions in model : '.get_class($this)); 
  662. }else{ 
  663. $this->error('Cannot delete element without conditions in model : '.get_class($this)); 
  664. return false; 
  665. $result=$this->beforeDelete($conditions); 
  666. if($result) $result=$this->query($query.$whereQuery); 
  667. else return false; 
  668. $this->afterDelete(); 
  669.  
  670. return true; 
  671.  
  672. function exists($conditions) { 
  673.  
  674. $query='SELECT '.$this->getPk().' FROM `'.$this->getSelectTableName().'`'; 
  675.  
  676. $query.=$this->makeJoins(); 
  677. if($this->setConditions($conditions)) { 
  678. $whereQuery=$this->makeWhere(); 
  679. if(!$whereQuery) { 
  680. $this->error('Cannot test element without conditions in model : '.get_class($this)); 
  681. }else{ 
  682. $this->error('Cannot test element without conditions in model : '.get_class($this)); 
  683. return false; 
  684. $res=$this->query('get_res', $query.$whereQuery, ARRAY_A); 
  685. if($res) return $res; 
  686. else return false; 
  687.  
  688. function getPk($numb=0) { 
  689. $pk=$this->pk; 
  690. if(is_array($pk)) $pk=$pk[$numb]; 
  691. return $pk; 
  692.  
  693. /** 
  694. * set the values after verifying them 
  695. * @param type $values 
  696. * @return type 
  697. */ 
  698. function setValues($values) { 
  699. if($this->colCheck && !$this->checkAreColumns($values)) return false; 
  700.  
  701. $this->values=array(); 
  702. $this->values=$values; 
  703. return true; 
  704.  
  705. /** 
  706. * @param type $values 
  707. * @return type 
  708. */ 
  709. function setJoin($joins) { 
  710. $this->joins=$joins; 
  711. return true; 
  712.  
  713. /** 
  714. * set the conditions after verifying them 
  715. * @param type $conditions 
  716. * @return type 
  717. */ 
  718. function setConditions($conditions, $update=false) { 
  719. if($conditions && is_array($conditions)) { 
  720.  
  721. $this->conditions=array(); 
  722. if($update) { 
  723. foreach($conditions as $key =>$cond) { 
  724. if($this->colCheck && !$this->checkAreColumns($conditions)) return false; 
  725.  
  726. if(is_array($cond)) { 
  727. $this->specialUpdate=true; 
  728. $this->conditions=$conditions; 
  729.  
  730. return true; 
  731. }else $this->conditions[$key]=$cond; 
  732.  
  733. } else { 
  734. foreach($conditions as $key => $cond) { 
  735. if(!in_array($key, $this->comparisonKeys /**array('like', 'equal', 'notequal', 'greater', 'less', 'greater_eq', 'less_eq')*/)) { 
  736. if($this->colCheck && !$this->checkAreColumns($conditions)) return false; 
  737. if(array_key_exists('equal', $this->conditions) === false) $this->conditions['equal'] = array(); 
  738. $this->conditions['equal'][$key] = $cond; 
  739. }else{ 
  740. if($this->colCheck && !$this->checkAreColumns($cond)) return false; 
  741. $this->conditions[$key]=$cond; 
  742.  
  743.  
  744. return true; 
  745. }else return false; 
  746.  
  747. /** 
  748. * check that the columns corresponds to the columns in the model 
  749. * @param type $arrayColumns 
  750. * @return type 
  751. */ 
  752. function checkAreColumns($columns) { 
  753. if($this->noCheck) return true; 
  754. foreach($columns as $column => $values) { 
  755. // skip when column is a comparison key 
  756. if(in_array($column, $this->comparisonKeys)) continue; 
  757.  
  758. $columnName = $column; 
  759. if(!isset($this->columns[$columnName])) { 
  760. $this->error(sprintf('Column %1$s does not exist in model : %2$s', $columnName, get_class($this))); 
  761. return false; 
  762. return true; 
  763.  
  764. function timer_start() { 
  765. $this->query_duration = 0; 
  766. $this->time_start = microtime( true ); 
  767. return true; 
  768.  
  769. function timer_stop() { 
  770. $this->query_duration = ( microtime( true ) - $this->time_start ); 
  771.  
  772. function query($query, $arg2='', $arg3=ARRAY_A) { 
  773. $this->sql_error = false; 
  774. if(!$arg2) $query = str_replace(array('[wysija]', '[wp]'), array($this->getPrefix(), $this->wpdb->prefix), $query); 
  775. else $arg2 = str_replace(array('[wysija]', '[wp]'), array($this->getPrefix(), $this->wpdb->prefix), $arg2); 
  776.  
  777. // if dbg is on we track the duration of the query 
  778. if($this->dbg) { 
  779. $this->timer_start(); 
  780.  
  781. switch($query) { 
  782. case 'get_row': 
  783. $result = $this->wpdb->get_row($arg2, $arg3); 
  784. $this->logError(); 
  785. break; 
  786. case 'get_res': 
  787. $result = $this->wpdb->get_results($arg2, $arg3); 
  788. //$this->escapeQuotesFromRes($results); 
  789. $this->logError(); 
  790. break; 
  791. default: 
  792. $result = $this->wpdb->query($query); 
  793. $this->logError(); 
  794.  
  795. // get the last insert id if it's an insert query 
  796. if(substr($query, 0, 6) == 'INSERT') $result = $this->wpdb->insert_id; 
  797.  
  798. // if dbg is on we track the duration of the query 
  799. if($this->dbg) { 
  800. $this->timer_stop(); 
  801. $this->keepQry('query'); 
  802. return $result; 
  803.  
  804. function logError() { 
  805. if(defined('WYSIJA_DBG') && WYSIJA_DBG>1) { 
  806. global $wysija_queries_errors; 
  807. if(!$wysija_queries_errors) $wysija_queries_errors = array(); 
  808.  
  809. $this->sql_error = $this->wpdb->last_error; 
  810.  
  811. if( $this->sql_error && 
  812. ( empty( $this->last_error ) || $this->last_error != $this->sql_error )) { 
  813. $this->last_error = $wysija_queries_errors[] = array('query' => $this->wpdb->last_query, 'error' => $this->sql_error); 
  814. $this->sql_error = false; 
  815. WYSIJA::log('queries_errors' , $this->sql_error , 'query_errors'); 
  816.  
  817.  
  818.  
  819. function keepQry($from = 'wpdb') { 
  820. global $wysija_queries; 
  821. $wysija_queries[$from][] = array('duration' => $this->query_duration , 'query' => $this->wpdb->last_query); 
  822.  
  823. function getAffectedRows() { 
  824. return $this->wpdb->rows_affected; 
  825.  
  826. function getErrorMsg() { 
  827. return $this->wpdb->show_errors(); 
  828. /** 
  829. * get the full prefix for the table 
  830. * @return type 
  831. */ 
  832. function getPrefix() { 
  833. if($this->tableWP) return $this->wpdb->prefix.$this->table_prefix; 
  834. else return $this->wpdb->prefix.$this->table_prefix.'_'; 
  835.  
  836. /** 
  837. * this function allows you to get the prefix from the main site on a multisite 
  838. * @return type 
  839. */ 
  840. function get_site_prefix($blog_id=1) { 
  841.  
  842. switch_to_blog( $blog_id ); 
  843. $main_site_prefix=$this->wpdb->prefix; 
  844. restore_current_blog(); 
  845.  
  846. if($this->tableWP) return $main_site_prefix.$this->table_prefix; 
  847. else return $main_site_prefix.$this->table_prefix.'_'; 
  848.  
  849. /** 
  850. * @param type $field_name name of field which will become a key 
  851. * @param array $dataset list of records 
  852. * @param boolean $removing_field_name decide if we should remove field name from output dataset 
  853. * @param string $field_name_as_value a field in which we consider its value as value of $field_name 
  854. * @return array field based indexed dataset 
  855. */ 
  856. protected function indexing_dataset_by_field($field_name, Array $dataset, $removing_field_name = false, $field_name_as_value = null) { 
  857. if (empty($dataset)) 
  858. return array(); 
  859. $tmp = array(); 
  860. foreach ($dataset as $record) { 
  861. if (isset($record[$field_name])) 
  862. if (!empty($field_name_as_value)) { 
  863. $tmp[$record[$field_name]] = isset($record[$field_name_as_value]) ? $record[$field_name_as_value] : null; 
  864. continue; 
  865. $tmp[$record[$field_name]] = $record; 
  866. if ($removing_field_name) 
  867. unset($tmp[$record[$field_name]][$field_name]); 
  868.  
  869. return $tmp; 
  870.  
  871. function beforeInsert() { 
  872. return true; 
  873.  
  874. function afterInsert($resultSaveID) { 
  875. return true; 
  876. function beforeDelete($conditions) { 
  877. return true; 
  878.  
  879. function afterDelete() { 
  880. return true; 
  881.  
  882. function beforeUpdate($id = null) { 
  883. return true; 
  884.  
  885. function afterUpdate($resultSaveID) { 
  886. return true; 
  887.