Advertisement
Guest User

Untitled

a guest
Aug 18th, 2017
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.89 KB | None | 0 0
  1. <?php
  2. /*
  3. UserSpice 4
  4. An Open Source PHP User Management System
  5. by the UserSpice Team at http://UserSpice.com
  6.  
  7.  
  8. This program is free software: you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation, either version 3 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. class DB {
  22.     private static $_instance = null;
  23.     private $_pdo, $_query, $_error = false, $_errorInfo, $_results, $_resultsArray, $_count = 0, $_lastId, $_queryCount=0;
  24.  
  25.     private function __construct(){
  26.         if (!$opts = Config::get('mysql/options'))
  27.             $opts = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION sql_mode = ''");
  28.         try{
  29.             $this->_pdo = new PDO('mysql:host=' .
  30.                 Config::get('mysql/host') .';dbname='.
  31.                 Config::get('mysql/db') . ';charset=utf8',
  32.                 Config::get('mysql/username'),
  33.                 Config::get('mysql/password'),
  34.                 $opts);
  35.         } catch(PDOException $e){
  36.             die($e->getMessage());
  37.         }
  38.     }
  39.  
  40.     public static function getInstance(){
  41.         if (!isset(self::$_instance)) {
  42.             self::$_instance = new DB();
  43.         }
  44.         return self::$_instance;
  45.     }
  46.  
  47.     public function query($sql, $params = array()){
  48.         //echo "DEBUG: query(sql=$sql, params=".print_r($params,true).")<br />\n";
  49.         $this->_queryCount++;
  50.         $this->_error = false;
  51.         $this->_errorInfo = array(0, null, null);
  52.         $this->_resultsArray = [];
  53.         $this->_count = 0;
  54.         $this->_lastId = 0;
  55.         if ($this->_query = $this->_pdo->prepare($sql)) {
  56.             $x = 1;
  57.             if (count($params)) {
  58.                 foreach ($params as $param) {
  59.                     $this->_query->bindValue($x, $param);
  60.                     $x++;
  61.                 }
  62.             }
  63.  
  64.             if ($this->_query->execute()) {
  65.                 $type = substr($sql, 0, 6);
  66.                 if ($type == 'SELECT' && $this->_query->columnCount() > 0) {
  67.                     $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
  68.                     $this->_resultsArray = json_decode(json_encode($this->_results), true);
  69.                 }
  70.                 if ($type == 'INSERT') {
  71.                     $this->_lastId = $this->_pdo->lastInsertId();
  72.                 }
  73.                 $this->_count = $this->_query->rowCount();
  74.             } else {
  75.                 $this->_error = true;
  76.                 $this->_errorInfo = $this->_query->errorInfo();
  77.             }
  78.         }
  79.         return $this;
  80.     }
  81.  
  82.     public function findAll($table){
  83.         return $this->action('SELECT *',$table);
  84.     }
  85.  
  86.     public function findById($id,$table){
  87.         return $this->action('SELECT *',$table,array('id','=',$id));
  88.     }
  89.  
  90.     public function action($action, $table, $where = array()){
  91.         $sql    = "{$action} FROM {$table}";
  92.         $values = array();
  93.         $is_ok  = true;
  94.  
  95.         if ($where_text = $this->_calcWhere($where, $values, "and", $is_ok))
  96.             $sql .= " WHERE $where_text";
  97.  
  98.         if ($is_ok)
  99.             if (!$this->query($sql, $values)->error())
  100.                 return $this;
  101.  
  102.         return false;
  103.     }
  104.  
  105.     private function _calcWhere($w, &$vals, $comboparg='and', &$is_ok=NULL) {
  106.         #echo "DEBUG: Entering _calcwhere(w=".print_r($w,true).",...)<br />\n";
  107.         if (is_array($w)) {
  108.                 #echo "DEBUG: is_array - check<br />\n";
  109.             $comb_ops   = ['and', 'or', 'and not', 'or not'];
  110.             $valid_ops  = ['=', '<', '>', '<=', '>=', '<>', '!=', 'LIKE', 'NOT LIKE', 'ALIKE', 'NOT ALIKE', 'REGEXP', 'NOT REGEXP'];
  111.             $two_args   = ['IS NULL', 'IS NOT NULL'];
  112.             $four_args  = ['BETWEEN', 'NOT BETWEEN'];
  113.             $arr_arg    = ['IN', 'NOT IN'];
  114.             $nested_arg = ['ANY', 'ALL', 'SOME'];
  115.             $nested     = ['EXISTS', 'NOT EXISTS'];
  116.             $nestedIN   = ['IN SELECT', 'NOT IN SELECT'];
  117.             $wcount     = count($w);
  118.  
  119.             if ($wcount == 0)
  120.                 return "";
  121.  
  122.             # believe it or not, this appears to be the fastest way to check
  123.             # sequential vs associative. Particularly with our expected short
  124.             # arrays it shouldn't impact memory usage
  125.             # https://gist.github.com/Thinkscape/1965669
  126.             if (array_values($w) === $w) { // sequential array
  127.                         #echo "DEBUG: Sequential array - check!<br />\n";
  128.                 if (in_array(strtolower($w[0]), $comb_ops)) {
  129.                             #echo "DEBUG: w=".print_r($w,true)."<br />\n";
  130.                     $sql = '';
  131.                     $combop = '';
  132.                     for ($i = 1; $i < $wcount; $i++) {
  133.                         $sql .= ' '. $combop . ' ' . $this->_calcWhere($w[$i], $vals, "and", $is_ok);
  134.                         $combop = $w[0];
  135.                     }
  136.                     return '('.$sql.')';
  137.  
  138.                 } elseif ($wcount==3  &&  in_array($w[1],$valid_ops)) {
  139.                     #echo "DEBUG: normal condition w=".print_r($w,true)."<br />\n";
  140.                     $vals[] = $w[2];
  141.                     return "{$w[0]} {$w[1]} ?";
  142.  
  143.                 } elseif ($wcount==2  &&  in_array($w[1],$two_args)) {
  144.                     return "{$w[0]} {$w[1]}";
  145.  
  146.                 } elseif ($wcount==4  &&  in_array($w[1],$four_args)) {
  147.                     $vals[] = $w[2];
  148.                     $vals[] = $w[3];
  149.                     return "{$w[0]} {$w[1]} ? AND ?";
  150.  
  151.                 } elseif ($wcount==3  &&  in_array($w[1],$arr_arg)  &&  is_array($w[2])) {
  152.                     $vals = array_merge($vals,$w[2]);
  153.                     return "{$w[0]} {$w[1]} (" . substr( str_repeat(",?",count($w[2])), 1) . ")";
  154.  
  155.                 } elseif (($wcount==5 || $wcount==6 && is_array($w[5]))  &&  in_array($w[1],$valid_ops)  &&  in_array($w[2],$nested_arg)) {
  156.                     return  "{$w[0]} {$w[1]} {$w[2]}" . $this->get_subquery_sql($w[4],$w[3],$w[5],$vals,$is_ok);
  157.  
  158.                 } elseif (($wcount==3 || $wcount==4 && is_array($w[3]))  &&  in_array($w[0],$nested)) {
  159.                     return $w[0] . $this->get_subquery_sql($w[2],$w[1],$w[3],$vals,$is_ok);
  160.  
  161.                 } elseif (($wcount==4 || $wcount==5 && is_array($w[4]))  &&  in_array($w[1],$nestedIN)) {
  162.                     return "{$w[0]} " . substr($w[1],0,-7) . $this->get_subquery_sql($w[3],$w[2],$w[4],$vals,$is_ok);
  163.  
  164.                 } else {
  165.                     echo "ERROR: w=".print_r($w,true)."<br />\n";
  166.                     $is_ok = false;
  167.                 }
  168.             } else { // associative array ['field' => 'value']
  169.                 #echo "DEBUG: Associative<br />\n";
  170.                 $sql = '';
  171.                 $combop = '';
  172.                 foreach ($w as $k=>$v) {
  173.                     if (in_array(strtolower($k), $comb_ops)) {
  174.                         #echo "DEBUG: A<br />\n";
  175.                         #echo "A: k=$k, v=".print_r($v,true)."<br />\n";
  176.                         $sql .= $combop . ' (' . $this->_calcWhere($v, $vals, $k, $is_ok) . ') ';
  177.                         $combop = $comboparg;
  178.                     } else {
  179.                         #echo "DEBUG: B<br />\n";
  180.                         #echo "B: k=$k, v=".print_r($v,true)."<br />\n";
  181.                         $vals[] = $v;
  182.                         if (in_array(substr($k,-1,1), array('=', '<', '>'))) // 'field !='=>'value'
  183.                             $sql .= $combop . ' ' . $k . ' ? ';
  184.                         else // 'field'=>'value'
  185.                             $sql .= $combop . ' ' . $k . ' = ? ';
  186.                         $combop = $comboparg;
  187.                     }
  188.                 }
  189.                 return ' ('.$sql.') ';
  190.             }
  191.         } else {
  192.             echo "ERROR: No array in $w<br />\n";
  193.             $is_ok = false;
  194.         }
  195.     }
  196.  
  197.     public function get($table, $where){
  198.         return $this->action('SELECT *', $table, $where);
  199.     }
  200.  
  201.     public function delete($table, $where){
  202.         return empty($where) ? false : $this->action('DELETE', $table, $where);
  203.     }
  204.  
  205.     public function deleteById($table,$id){
  206.         return $this->action('DELETE',$table,array('id','=',$id));
  207.     }
  208.  
  209.     public function insert($table, $fields=[], $update=false) {
  210.         $keys    = array_keys($fields);
  211.         $values  = [];
  212.         $records = 0;
  213.  
  214.         foreach ($fields as $field) {
  215.             $count = is_array($field) ? count($field) : 1;
  216.  
  217.             if (!isset($first_time)  ||  $count<$records) {
  218.                 $first_time = true;
  219.                 $records    = $count;
  220.             }
  221.         }
  222.  
  223.         for ($i=0; $i<$records; $i++)
  224.             foreach ($fields as $field)
  225.                 $values[] = is_array($field) ? $field[$i] : $field;
  226.  
  227.         $col = ",(" . substr( str_repeat(",?",count($fields)), 1) . ")";
  228.         $sql = "INSERT INTO {$table} (`". implode('`,`', $keys)."`) VALUES ". substr( str_repeat($col,$records), 1);
  229.  
  230.         if ($update) {
  231.             $sql .= " ON DUPLICATE KEY UPDATE";
  232.  
  233.             foreach ($keys as $key)
  234.                 if ($key != "id")
  235.                     $sql .= " `$key` = VALUES(`$key`),";
  236.  
  237.             if (!empty($keys))
  238.                 $sql = substr($sql, 0, -1);
  239.         }
  240.  
  241.         return !$this->query($sql, $values)->error();
  242.     }
  243.  
  244.     public function update($table, $id, $fields){
  245.         $sql   = "UPDATE {$table} SET " . (empty($fields) ? "" : "`") . implode("` = ? , `", array_keys($fields)) . (empty($fields) ? "" : "` = ? ");
  246.         $is_ok = true;
  247.  
  248.         if (!is_array($id)) {
  249.             $sql     .= "WHERE id = ?";
  250.             $fields[] = $id;
  251.         } else {
  252.             if (empty($id))
  253.                 return false;
  254.  
  255.             if ($where_text = $this->_calcWhere($id, $fields, "and", $is_ok))
  256.                 $sql .= "WHERE $where_text";
  257.         }
  258.  
  259.         if ($is_ok)
  260.             if (!$this->query($sql, $fields)->error())
  261.                 return true;
  262.  
  263.         return false;
  264.     }
  265.  
  266.     public function results($assoc = false){
  267.         if($assoc) return $this->_resultsArray;
  268.         return $this->_results;
  269.     }
  270.  
  271.     public function first($assoc = false){
  272.         return (!$assoc || $assoc && $this->count()>0)  ?  $this->results($assoc)[0]  :  [];
  273.     }
  274.  
  275.     public function count(){
  276.         return $this->_count;
  277.     }
  278.  
  279.     public function error(){
  280.         return $this->_error;
  281.     }
  282.  
  283.     public function errorInfo() {
  284.         return $this->_errorInfo;
  285.     }
  286.  
  287.     public function errorString() {
  288.         return 'ERROR #'.$this->_errorInfo[0].': '.$this->_errorInfo[2];
  289.     }
  290.  
  291.     public function lastId(){
  292.         return $this->_lastId;
  293.     }
  294.  
  295.     public function getQueryCount(){
  296.         return $this->_queryCount;
  297.     }
  298.  
  299.     private function get_subquery_sql($action, $table, $where, &$values, &$is_ok) {
  300.         if (is_array($where))
  301.             if ($where_text = $this->_calcWhere($where, $values, "and", $is_ok))
  302.                 $where_text = " WHERE $where_text";
  303.  
  304.         return " (SELECT $action FROM $table$where_text)";
  305.     }
  306.  
  307.     public function cell($tablecolumn, $id=[]) {
  308.         $input = explode(".", $tablecolumn, 2);
  309.  
  310.         if (count($input) != 2)
  311.             return null;
  312.  
  313.         $result = $this->action("SELECT {$input[1]}", $input[0], (is_numeric($id) ? ["id","=",$id] : $id));
  314.  
  315.         return ($result && $this->_count>0)  ?  $this->_resultsArray[0][$input[1]]  :  null;
  316.     }
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement