├── .gitignore ├── README.md ├── class.curl.php ├── class.db.php ├── class.filter.php ├── class.redis.php ├── class.session.php ├── class.timer.php ├── inc.filter.php └── lib.global.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Folders # 2 | !empty 3 | 4 | # Compiled source # 5 | ################### 6 | *.com 7 | *.class 8 | *.dll 9 | *.exe 10 | *.o 11 | *.so 12 | 13 | # Packages # 14 | ############ 15 | # it's better to unpack these files and commit the raw source 16 | # git has its own built in compression methods 17 | *.7z 18 | *.dmg 19 | *.gz 20 | *.iso 21 | *.jar 22 | *.rar 23 | *.tar 24 | *.zip 25 | 26 | # Logs and databases # 27 | ###################### 28 | *.log 29 | *.sql 30 | *.sqlite 31 | 32 | # OS generated files # 33 | ###################### 34 | .DS_Store* 35 | ehthumbs.db 36 | Icon? 37 | Thumbs.db 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | php 2 | === 3 | 4 | collection of php classes, libraries, and include files I use -------------------------------------------------------------------------------- /class.curl.php: -------------------------------------------------------------------------------- 1 | hashcode(); 37 | $this->cookie = "cache/cookies/$hash.txt"; 38 | 39 | if($_SERVER['HTTP_USER_AGENT']) $this->useragent = $_SERVER['HTTP_USER_AGENT']; 40 | else $this->useragent = $this->useragents[rand(0,count($this->useragents))]; 41 | 42 | //if($proxy) $this->getProxy(); 43 | } 44 | 45 | // get a random proxy 46 | /* function getProxy() 47 | { 48 | global $proxy; 49 | $this->proxy = $proxy->getProxy(); 50 | }*/ 51 | 52 | function hashcode() 53 | { 54 | return md5($_SERVER['REQUEST_TIME'].rand(1, 9999)); 55 | } 56 | 57 | function setcallback($func_name) 58 | { 59 | $this->callback = $func_name; 60 | } 61 | 62 | // If site requests basic Authentication 63 | function setLogin($user, $pass) 64 | { 65 | $this->login = true; 66 | $this->username = $user; 67 | $this->password = $pass; 68 | // login will be cleared after request 69 | } 70 | 71 | function dorequest($method, $url, $vars = array()) 72 | { 73 | $this->temp_redirect = $this->max_redirect; 74 | $curl_inst = true; 75 | if ( !extension_loaded("curl") && !dl("curl.so") ) $curl_inst = false; 76 | 77 | if ($curl_inst) { 78 | $ch = curl_init(); 79 | curl_setopt($ch, CURLOPT_URL, $url); 80 | if($this->login) curl_setopt($ch, CURLOPT_USERPWD, $this->username.":".$this->password); // if login was sucessful, clear it (see below) 81 | curl_setopt($ch, CURLOPT_REFERER, $this->referer); // Page url was found on 82 | 83 | curl_setopt($ch, CURLOPT_USERAGENT, $this->useragent); 84 | if ($this->proxy) { 85 | curl_setopt($ch, CURLOPT_PROXY, $this->proxy); 86 | //curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); 87 | //curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY); 88 | } 89 | if (substr($url, 0, 5) == 'https') { 90 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 91 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 92 | } 93 | curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookie); 94 | curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookie); 95 | curl_setopt($ch, CURLOPT_AUTOREFERER, true); 96 | if ($this->curl_follow) { 97 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 98 | curl_setopt($ch, CURLOPT_MAXREDIRS, $this->max_redirect); // auto redirect 99 | } 100 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 101 | curl_setopt($ch, CURLOPT_HEADER, $this->curl_header); // Return Header info (true,false) 102 | $httpheader[] = "Connection: Keep-Alive"; 103 | //$httpheader[] = "Accept-Encoding: compress, gzip"; // compressing inbound files -> gzuncompress($web_page['FILE']) to uncompress file 104 | //# Get sizes of compressed and uncompressed versions of web page Check LIB_download_image 105 | //$uncompressed_size = strlen($web_page['FILE']); 106 | //$compressed_size = strlen(gzcompress($web_page['FILE'], $compression_value = 9)); 107 | //$noformat_size = strlen(strip_tags($web_page['FILE'])); 108 | curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader); 109 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 110 | if ($method == "POST") { 111 | $query = $this->makeQuery($vars); 112 | curl_setopt($ch, CURLOPT_POST, 1); 113 | curl_setopt($ch, CURLOPT_POSTFIELDS, $query); 114 | } 115 | 116 | $return_array = $this->redirect_exec($ch); 117 | 118 | curl_close($ch); 119 | if($this->login) $this->login = false; // login was sucessful, clear it 120 | return $return_array; 121 | } 122 | 123 | $sockets_inst = true; 124 | if ( !extension_loaded("sockets") && !dl("sockets.so") ) $sockets_inst = false; 125 | 126 | if ($sockets_inst) { 127 | $purl = parse_url($url); 128 | $address = gethostbyname($purl['host']); 129 | $socket = socket_create(AF_INET, SOCK_STREAM, 0); 130 | if ($socket < 1) { 131 | echo 'socket < 1\n'; 132 | echo socket_strerror($socket).'\n'; 133 | echo 'address: '.$address.'\n'; 134 | echo 'purl: '.$purl.'\n'; 135 | echo 'url: '.$url.'\n'; 136 | return false; 137 | } 138 | //try { 139 | $res = socket_connect($socket, $address, 80); 140 | //} catch { 141 | //return false; 142 | //} 143 | if ($res < 1) { 144 | echo 'res < 1\n'; 145 | echo socket_strerror($res).'\n'; 146 | echo 'address: '.$address.'\n'; 147 | echo 'purl: '.$purl.'\n'; 148 | echo 'url: '.$url.'\n'; 149 | return false; 150 | } 151 | if ($method == "GET") { 152 | $request = "GET ".$purl['path']."?{$purl['query']} HTTP/1.0\r\n"; 153 | $request .= "Host: ".$purl['host']."\r\n"; 154 | $request .= "User-Agent: ".$_SERVER['HTTP_USER_AGENT']."\r\n"; 155 | $request .= "Connection: close\r\n\r\n"; 156 | } else if ($method == "POST") { 157 | $query = ""; 158 | foreach ($vars as $k => $v) { 159 | $query .= $k."=".$v."&"; 160 | } 161 | $query = substr($query, 0, -1); 162 | $request = "POST ".$purl['path']." HTTP/1.0\r\n"; 163 | $request .= "Host: ".$purl['host']."\r\n"; 164 | $request .= "User-Agent: ".$_SERVER['HTTP_USER_AGENT']."\r\n"; 165 | $request .= "Content-Type: application/x-www-form-urlencoded\r\n"; 166 | $request .= "Content-Length: ".strlen($query)."\r\n"; 167 | $request .= "Connection: close\r\n\r\n"; 168 | $request .= $query; 169 | } else { 170 | return false; 171 | } 172 | socket_write($socket, $request, strlen( $request) ); 173 | $data = ""; 174 | while ($resp = socket_read($socket, 2048)) { 175 | $data .= $resp; 176 | } 177 | if (preg_match("/HTTP\\/.\\.. 30./", $data)) { 178 | preg_match("/Location: (.*)/", $data, $matches); 179 | $purlm = "http://".$purl['host']."{$matches['1']}"; 180 | $purlm = rtrim($purlm); 181 | $data = $this->dorequest($method, $purlm, $vars); 182 | } 183 | $pos = strpos($data, "\r\n\r\n"); 184 | if ($pos != false) { 185 | $data = substr($data, $pos + 4); 186 | } 187 | return $data; 188 | } 189 | return false; 190 | } 191 | 192 | function redirect_exec($ch) 193 | { 194 | $return_array['FILE'] = curl_exec($ch); 195 | $return_array['STATUS'] = curl_getinfo($ch); 196 | $return_array['ERROR'] = curl_error($ch); 197 | if($this->curl_follow || !$this->curl_header) return $return_array; // internal curl took care of it 198 | 199 | // Full redirect 200 | // $curl_follow = false 201 | // $curl_header = true 202 | $data = $return_array['FILE']; 203 | $http_code = $return_array['STATUS']['http_code']; 204 | if ($http_code == 301 || $http_code == 302 || $http_code == 303) { 205 | list($header) = explode("\r\n\r\n", $data, 2); 206 | $matches = array(); 207 | preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); 208 | $url = trim(array_pop($matches)); 209 | $url_parsed = parse_url($url); 210 | if (isset($url_parsed['host'])) { 211 | curl_setopt($ch, CURLOPT_URL, $url); 212 | $this->temp_redirect--; 213 | return $this->redirect_exec($ch); 214 | } 215 | } elseif ($http_code == 200) { 216 | $matches = array(); 217 | preg_match('/(/', strtolower($data), $matches); 218 | $url = trim(array_pop($matches)); 219 | $url_parsed = parse_url($url); 220 | if (isset($url_parsed['host'])) { 221 | curl_setopt($ch, CURLOPT_URL, $url); 222 | $this->temp_redirect--; 223 | return $this->redirect_exec($ch); 224 | } 225 | } else if ($return_array['FILE'] === false || $http_code != 200) { 226 | // FAILED 227 | } 228 | return $return_array; 229 | } 230 | 231 | function get($url, $vars = array()) 232 | { 233 | $query = $this->makeQuery($vars); 234 | if($query && !strpos($url, "?")) $query = "?".$query; 235 | else if($query && strpos($url, "?")) $query = "&".$query; 236 | return $this->dorequest("GET", $url.$query, "null"); 237 | } 238 | 239 | function post($url, $vars = array()) 240 | { 241 | return $this->dorequest("POST", $url, $vars); 242 | } 243 | 244 | function clearCookie() 245 | { 246 | 247 | if (file_exists($this->cookie)) unlink($this->cookie); 248 | } 249 | 250 | function makeQuery($vars) 251 | { 252 | $query = ""; 253 | foreach ($vars as $k => $v) { 254 | $query .= $k."=".urlencode($v)."&"; 255 | } 256 | $query = substr($query, 0, -1); // remove trailing & 257 | return $query; 258 | } 259 | 260 | } 261 | 262 | ?> 263 | -------------------------------------------------------------------------------- /class.db.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2001 - 2012 willFarrell.ca 12 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 13 | * @version GIT: 14 | * @link http://willFarrell.ca 15 | */ 16 | 17 | /* 18 | 19 | Additional Notes: 20 | - Make sure the DB_USER only has permission for command your using 21 | 22 | */ 23 | 24 | // Set server default time, it's a life saver. seriously 25 | date_default_timezone_set('UTC'); 26 | 27 | if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1' || $_SERVER['HTTP_HOST'] == 'localhost:8888') { 28 | define('DB_SERVER','localhost'); 29 | define('DB_NAME','db'); 30 | define('DB_USER','root'); 31 | define('DB_PASS','localhost'); 32 | } else { 33 | define('DB_SERVER','localhost'); 34 | define('DB_NAME',''); 35 | define('DB_USER',''); 36 | define('DB_PASS',''); 37 | } 38 | 39 | /** 40 | * Database 41 | * 42 | * @category N/A 43 | * @package N/A 44 | * @author Original Author 45 | * @author Another Author 46 | * @copyright 2001 - 2011 willFarrell.ca 47 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 48 | * @version Release: 49 | * @link http://willFarrell.ca 50 | */ 51 | 52 | class MySQL 53 | { 54 | var $connection_mysql; //The MySQL database connection 55 | 56 | /** 57 | * Constructor 58 | */ 59 | function __construct() 60 | { 61 | $this->_connect(); 62 | } 63 | 64 | /** 65 | * Destructor 66 | */ 67 | function __destruct() 68 | { 69 | $this->_close(); 70 | } 71 | 72 | /** 73 | * create db connection 74 | * 75 | * @return null 76 | * @access private 77 | */ 78 | private function _connect() 79 | { 80 | $this->connection_mysql = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME) or die(mysql_error()); 81 | } 82 | /** 83 | * close db connection 84 | * 85 | * @return null 86 | * @access private 87 | */ 88 | private function _close() 89 | { 90 | mysqli_close($this->connection_mysql); 91 | } 92 | 93 | /** 94 | * Connection check 95 | * pings mysql service to see if still running, 96 | * if not, connects again 97 | * 98 | * @return true 99 | * @aceess puiblic 100 | */ 101 | function ping() 102 | { 103 | if (!mysqli_ping($this->connection_mysql)) { 104 | $this->_connect(); 105 | $this->ping(); 106 | } else { 107 | return true; 108 | } 109 | } 110 | 111 | 112 | /** 113 | * MySQL Query 114 | * runs the query through the MyQSL service 115 | * 116 | * @param string $query - MySQL Query 117 | * 118 | * @return MySQL Object 119 | * @aceess puiblic 120 | */ 121 | private function _run($query) 122 | { 123 | $return = mysqli_query($query, $this->connection_mysql); 124 | 125 | if (mysqli_error($this->connection_mysql)) { 126 | echo $query."
"; 127 | echo "".mysqli_error($this->connection_mysql)."
"; 128 | } 129 | return $return; 130 | } 131 | 132 | /** 133 | * checks the output of a MySQL query 134 | * 135 | * @param object $result MySQL Object 136 | * 137 | * @return MySQL Object 138 | * @aceess puiblic 139 | */ 140 | function resultCheck($result) 141 | { 142 | if (!$result || (mysqli_num_rows($result) < 1)) { 143 | return null; 144 | } 145 | return $result; 146 | } 147 | 148 | //** Functions **// 149 | /** 150 | * cleans all values of SQL injections 151 | * 152 | 153 | * @param array $array array of values to interact with the DB 154 | * 155 | * @return array of cleaned values 156 | * @aceess puiblic 157 | */ 158 | function cleanArray($array) 159 | { 160 | $array = array_map('trim', $array); 161 | $array = array_map('stripslashes', $array); 162 | $array = array_map('mysql_real_escape_string', $array); 163 | return $array; 164 | } 165 | 166 | /** 167 | * cleans a value of SQL injections 168 | * 169 | 170 | * @param string $value value to interact with the DB 171 | * 172 | * @return cleaned value 173 | * @aceess puiblic 174 | */ 175 | function cleanValue($value) 176 | { 177 | if (is_string($value)) { 178 | $value = trim($value); 179 | $value = stripslashes($value); 180 | $value = mysqli_real_escape_string($value); 181 | } 182 | 183 | return $value; 184 | } 185 | 186 | /** 187 | * FUTURE: cleans all values of SQL injections 188 | * 189 | * @param string $query - MySQL query 190 | * 191 | * @return cleaned query 192 | * @aceess puiblic 193 | */ 194 | function cleanQuery($query) 195 | { 196 | //echo $q; 197 | //preg_match_all("/[;]?(DROP TABLE|TRUNCATE)[\s]+/", $q, $matches); 198 | //print_r($matches); 199 | //if (count($matches) > 2) return null; 200 | return $query; 201 | } 202 | 203 | /** 204 | * Custom Query 205 | * runs a templates written query 206 | *l 207 | * @param string $query MySQL Query 208 | * @param array $value_array replace {{$key}} with $value in custom query 209 | * 210 | * @return object $object MySQL Object 211 | * @aceess puiblic 212 | */ 213 | function query($query, $value_array = NULL) 214 | { 215 | if ($value_array && is_array($value_array)) { 216 | $value_array = $this->cleanArray($value_array); 217 | $query = preg_replace("/{{([\w]+)}}/e", "\$value_array['\\1']", $query); 218 | /*foreach ($value_array as $key => $value) { 219 | $query = preg_replace("/{{".$key."}}/i", $value, $query); 220 | }*/ 221 | } else { 222 | //$q = $this->cleanQuery($q); 223 | } 224 | 225 | $check = (substr($query, 0, 6) == 'SELECT')?true:false; 226 | $result = $this->_run($query); 227 | $result = ($check)?$this->resultCheck($result):$result; 228 | return $result; 229 | } 230 | 231 | /** 232 | * Select Query 233 | * 234 | * @param string $table table where rows will be deleted 235 | * @param array $where_array `$key` = $value WHERE parameters 236 | * @param array $select_array `$key` = $value SELECT parameters 237 | * @param array $order_array `$key` = $value ORDER BY parameters 238 | * 239 | * @return ID of affected row 240 | * @access public 241 | */ 242 | function select($table, $where_array = null, $select_array = null, $order_array = null) 243 | { 244 | $where = ''; 245 | if ($where_array && is_array($where_array)) { 246 | $where_array = $this->cleanArray($where_array); 247 | $i = 0; 248 | 249 | foreach ($where_array as $key => $value) { 250 | $where .= ($i)?"AND ":''; 251 | $where .= "`$key` = '$value' "; 252 | $i++; 253 | } 254 | $where = ($where)?"WHERE ".$where:''; 255 | } 256 | 257 | $select = ''; 258 | if ($select_array && is_array($select_array)) { 259 | $select_array = $this->cleanArray($select_array); 260 | foreach ($select_array as $value) { 261 | $select .= ($select)?", ":''; 262 | $select .= "$value"; 263 | } 264 | $select = ($select) ? $select : "*"; 265 | } else { 266 | $select = "*"; 267 | } 268 | 269 | $order = ''; 270 | if ($order_array && is_array($order_array)) { 271 | $order_array = $this->cleanArray($order_array); 272 | foreach ($order_array as $value) { 273 | $order .= ($order)?", ":''; 274 | $order .= "$value"; 275 | } 276 | $order = ($order)?"ORDER BY ".$order:''; 277 | } 278 | 279 | $query = "SELECT $select FROM `$table` $where $order"; 280 | $result = $this->_run($query); 281 | $result = $this->resultCheck($result); 282 | return $result; 283 | } 284 | 285 | /** 286 | * Insert Query 287 | * 288 | * @param string $table table where rows will be deleted 289 | * @param array $set_array `$key` = $value SET parameters 290 | * @param array $update_array `$key` = $value ON DUPLICATE UPDATE parameters 291 | * 292 | * @return ID of affected row 293 | * @access public 294 | */ 295 | function insert($table, $set_array, $update_array = null) 296 | { 297 | if ($set_array && is_array($set_array)) { 298 | $set_array = $this->cleanArray($set_array); 299 | $set = ''; 300 | foreach ($set_array as $key => $value) { 301 | $set .= ($set)?", ":''; 302 | $set .= "`$key` = '$value' "; 303 | } 304 | if ($update_array && is_array($update_array)) { 305 | $update_array = $this->cleanArray($update_array); 306 | $update = ''; 307 | foreach ($update_array as $key => $value) { 308 | $update .= ($update)?", ":''; 309 | $update .= "`$key` = '$value' "; 310 | } 311 | } else { 312 | $update = $set; 313 | } 314 | $set = ($set)?"SET ".$set:''; 315 | $update = ($update)?"ON DUPLICATE KEY UPDATE ".$update:''; 316 | } 317 | 318 | $query = "INSERT INTO `$table` $set $update"; 319 | $this->_run($query); 320 | 321 | return mysqli_insert_id($this->connection_mysql); 322 | } 323 | 324 | /** 325 | * Update Query 326 | * 327 | * @param string $table table where rows will be deleted 328 | * @param array $set_array `$key` = $value SET parameters 329 | * @param array $where_array `$key` = $value WHERE parameters 330 | * 331 | * @return number of affected rows 332 | * @access public 333 | */ 334 | function update($table, $set_array, $where_array) 335 | { 336 | if ($set_array && is_array($set_array)) { 337 | $set_array = $this->cleanArray($set_array); 338 | $i = 0; 339 | $set = ''; 340 | foreach ($set_array as $key => $value) { 341 | $set .= ($i)?", ":''; 342 | $set .= "`$key` = '$value' "; 343 | $i++; 344 | } 345 | $set = ($set)?"SET ".$set:''; 346 | } 347 | 348 | if ($where_array && is_array($where_array)) { 349 | $where_array = $this->cleanArray($where_array); 350 | $i = 0; 351 | $where = ''; 352 | foreach ($where_array as $key => $value) { 353 | $where .= ($i)?"AND ":''; 354 | $where .= "`$key` = '$value' "; 355 | $i++; 356 | } 357 | $where = ($where)?"WHERE ".$where:''; 358 | } 359 | 360 | $query = "UPDATE `$table` $set $where"; 361 | $this->_run($query); 362 | 363 | return mysqli_affected_rows($this->connection_mysql); 364 | } 365 | 366 | /** 367 | * Delete Query 368 | * 369 | * @param string $table table where rows will be deleted 370 | * @param array $where_array array of `$key` = $value parameters 371 | * 372 | * @return number of affected rows 373 | * @access public 374 | */ 375 | function delete($table, $where_array) 376 | { 377 | if ($where_array && is_array($where_array)) { 378 | $where_array = $this->cleanArray($where_array); 379 | $i = 0; 380 | $where = ''; 381 | foreach ($where_array as $key => $value) { 382 | $where .= ($i)?"AND ":''; 383 | $where .= "`$key` = '$value' "; 384 | $i++; 385 | } 386 | $where = ($where)?"WHERE ".$where:''; 387 | } 388 | $query = "DELETE FROM `$table` $where"; 389 | $this->_run($query); 390 | return mysqli_affected_rows($this->connection_mysql); 391 | } 392 | 393 | }; 394 | 395 | $database = new MySQL; 396 | -------------------------------------------------------------------------------- /class.filter.php: -------------------------------------------------------------------------------- 1 | filter->set_request_data('keyword', $keyword); 54 | $this->filter->set_rules('keyword', 'trim'); 55 | if(!$this->filter->run()) { 56 | $return["errors"] = $this->filter->get_errors(); 57 | $return["alerts"] = $this->filter->get_alerts('error'); 58 | return $return; 59 | } 60 | $keyword = $this->filter->get_request_data('keyword'); 61 | 62 | 63 | 64 | // with groups and array of inputs 65 | $this->filter->set_request_data($request_data); 66 | $this->filter->set_group_rules('group_a,group_b'); 67 | $this->filter->set_key_rules(array('key_a', 'key_2'), 'required'); 68 | $this->filter->set_all_rules('trim|sanitize_string', true); // apply to all 69 | 70 | if(!$this->filter->run()) { 71 | $return["errors"] = $this->filter->get_errors(); 72 | return $return; 73 | } 74 | $request_data = $this->filter->get_request_data(); 75 | 76 | 77 | 78 | */ 79 | 80 | require_once 'inc.filter.php'; // config file 81 | //require_once 'test.filter.php'; 82 | 83 | class Filter { 84 | var $form = array(); 85 | 86 | // rule messages 87 | protected $_request_data = array(); 88 | protected $_field_data = array(); // params about a field 89 | protected $_config_rules = array(); 90 | protected $_defaut_messages = array( 91 | // CI_Form_validation rules 92 | 'required' => 'is empty', 93 | 'matches' => 'does not match', 94 | 'is_unique' => 'is already taken', 95 | 'min_length' => 'is too short', 96 | 'max_length' => 'is too long', 97 | 'exact_length' => 'is not the right length', 98 | 'greater_than' => 'is too small', 99 | 'less_than' => 'is too large', 100 | 'alpha' => 'contains non alphabetical characters', 101 | 'alpha_numeric' => 'contains non alpha-numeric characters', 102 | 'alpha_dash' => 'contains non alpha-numeric characters, underscores or dashes', 103 | 'numeric' => 'contains non numeric characters', 104 | 'boolean' => 'is not a boolean', 105 | 'integer' => 'is not an integer', 106 | 'decimal' => 'is not a decimal number', 107 | 'is_natural' => 'is not zero or a positive integer', // array values 108 | 'is_natural_no_zero' => 'is not a positive integer', // DB ID values 109 | 'valid_email' => 'is not a valid email', 110 | 'valid_emails' => 'are not a valid emails', 111 | 'valid_ip' => 'is not a valid IP', 112 | 'valid_base64' => 'is not in Base64', 113 | // custom 114 | 'valid_email_dns' => 'is not a valid email domain', 115 | 'valid_url' => 'is not a valid url', 116 | 'valid_mail_code' => 'is not a valid mail code', 117 | 'valid_phone' => 'is not a valid phone number', 118 | ); 119 | protected $_error_array = array(); 120 | protected $_error_messages = array(); 121 | protected $_error_prefix = '

'; 122 | protected $_error_suffix = '

'; 123 | protected $_safe_form_data = FALSE; 124 | 125 | function __construct($rules = array()){ 126 | global $database; 127 | $this->db = $database; 128 | 129 | $this->_config_rules = $rules; 130 | 131 | // copy sent params 132 | if (isset($_GET) && count($_GET)) $this->_request_data = $_GET; 133 | else if (isset($_POST) && count($_POST)) $this->_request_data = $_POST; 134 | else if (isset($_PUT) && count($_PUT)) $this->_request_data = $_PUT; 135 | 136 | // set default error messages 137 | foreach ($this->_defaut_messages as $key => $value) { 138 | $this->set_message($key, $value); 139 | } 140 | 141 | } 142 | 143 | function __destruct() { 144 | 145 | } 146 | 147 | function get_request_data($key = NULL) { 148 | if ($key != NULL) { 149 | return $this->_request_data[$key]; 150 | } else { 151 | return $this->_request_data; 152 | } 153 | } 154 | 155 | function set_request_data($request_data, $value = NULL) { 156 | if (is_array($request_data)) { 157 | $this->_request_data = $request_data; 158 | } else { 159 | $key = $request_data; 160 | $this->_request_data[$key] = $value; 161 | } 162 | } 163 | 164 | function get_error_array() { 165 | return $this->_error_array; 166 | } 167 | 168 | function get_errors($class = 'error') { 169 | $alerts = array(); 170 | foreach ($this->_field_data as $key => $value) { 171 | //if ($value['error']) $errors[$key] = $value['error']; 172 | if ($value['error']) $alerts[$key] = array('class' => $class, 'label' => $value['label'], 'message' => $value['error']); 173 | } 174 | 175 | return $alerts; 176 | } 177 | 178 | /** 179 | * Set Rules for an array of keys 180 | * 181 | * This function takes an array of field names and validation 182 | * rules as input, validates the info, and stores it 183 | * 184 | * @access public 185 | * @param mixed 186 | * @param string 187 | * @param bool 188 | * @return void 189 | */ 190 | function set_key_rules($keys, $rules, $pos = false) { 191 | if (is_array($keys)) { 192 | foreach ($keys as $key) { 193 | $spacer = ($this->_field_data[$key]['rules'] == '') ? '' : '|'; 194 | $this->_field_data[$key]['rules'] = $pos ? $this->_field_data[$key]['rules'].$spacer.$rules : $rules.$spacer.$this->_field_data[$key]['rules']; 195 | } 196 | } 197 | } 198 | 199 | function set_all_rules($rules, $pos = false) { 200 | foreach ($this->_field_data as $key => $value) { 201 | $spacer = ($value['rules'] == '') ? '' : '|'; 202 | $this->_field_data[$key]['rules'] = $pos ? $value['rules'].$spacer.$rules : $rules.$spacer.$value['rules']; 203 | } 204 | } 205 | 206 | /** 207 | * Set Rules from config groups 208 | * 209 | * @access public 210 | * @param mixed 211 | * @return void 212 | */ 213 | function set_group_rules($groups) { 214 | // Is there a validation rule for the particular group being accessed? 215 | $groups = ($groups == '') ? '' : explode(",", $groups); 216 | 217 | if (is_array($groups)) 218 | { 219 | foreach($groups as $group) { 220 | if ($groups != '' AND isset($this->_config_rules[$group])) 221 | { 222 | $this->set_rules($this->_config_rules[$group]); 223 | } 224 | } 225 | } 226 | } 227 | 228 | 229 | // -------------------------------------------------------------------- 230 | 231 | /** 232 | * Set Rules 233 | * 234 | * This function takes an array of field names and validation 235 | * rules as input, validates the info, and stores it 236 | * 237 | * @access public 238 | * @param mixed 239 | * @param string 240 | * @return void 241 | */ 242 | public function set_rules($field, $label = '', $rules = '') 243 | { 244 | // No reason to set rules if we have no POST data 245 | if (count($this->_request_data) == 0) 246 | { 247 | return $this; 248 | } 249 | 250 | // If an array was passed via the first parameter instead of indidual string 251 | // values we cycle through it and recursively call this function. 252 | if (is_array($field)) 253 | { 254 | foreach ($field as $row) 255 | { 256 | // Houston, we have a problem... 257 | if ( ! isset($row['field']) OR ! isset($row['rules'])) 258 | { 259 | continue; 260 | } 261 | 262 | // If the field label wasn't passed we use the field name 263 | $label = ( ! isset($row['label'])) ? $row['field'] : $row['label']; 264 | 265 | // Here we go! 266 | $this->set_rules($row['field'], $label, $row['rules']); 267 | } 268 | return $this; 269 | } 270 | 271 | // No fields? Nothing to do... 272 | if ( ! is_string($field) OR ! is_string($rules) OR $field == '') 273 | { 274 | return $this; 275 | } 276 | 277 | // If the field label wasn't passed we use the field name 278 | $label = ($label == '') ? $field : $label; 279 | 280 | // Is the field name an array? We test for the existence of a bracket "[" in 281 | // the field name to determine this. If it is an array, we break it apart 282 | // into its components so that we can fetch the corresponding POST data later 283 | if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches)) 284 | { 285 | // Note: Due to a bug in current() that affects some versions 286 | // of PHP we can not pass function call directly into it 287 | $x = explode('[', $field); 288 | $indexes[] = current($x); 289 | 290 | for ($i = 0; $i < count($matches['0']); $i++) 291 | { 292 | if ($matches['1'][$i] != '') 293 | { 294 | $indexes[] = $matches['1'][$i]; 295 | } 296 | } 297 | 298 | $is_array = TRUE; 299 | } 300 | else 301 | { 302 | $indexes = array(); 303 | $is_array = FALSE; 304 | } 305 | 306 | // Build our master array 307 | $this->_field_data[$field] = array( 308 | 'field' => $field, 309 | 'label' => $label, 310 | 'rules' => $rules, 311 | 'is_array' => $is_array, 312 | 'keys' => $indexes, 313 | 'postdata' => NULL, 314 | 'error' => '' 315 | ); 316 | 317 | return $this; 318 | } 319 | 320 | // -------------------------------------------------------------------- 321 | 322 | /** 323 | * Set Error Message 324 | * 325 | * Lets users set their own error messages on the fly. Note: The key 326 | * name has to match the function name that it corresponds to. 327 | * 328 | * @access public 329 | * @param string 330 | * @param string 331 | * @return string 332 | */ 333 | public function set_message($lang, $val = '') 334 | { 335 | if ( ! is_array($lang)) 336 | { 337 | $lang = array($lang => $val); 338 | } 339 | 340 | $this->_error_messages = array_merge($this->_error_messages, $lang); 341 | 342 | return $this; 343 | } 344 | 345 | // -------------------------------------------------------------------- 346 | 347 | /** 348 | * Set The Error Delimiter 349 | * 350 | * Permits a prefix/suffix to be added to each error message 351 | * 352 | * @access public 353 | * @param string 354 | * @param string 355 | * @return void 356 | */ 357 | public function set_error_delimiters($prefix = '

', $suffix = '

') 358 | { 359 | $this->_error_prefix = $prefix; 360 | $this->_error_suffix = $suffix; 361 | 362 | return $this; 363 | } 364 | 365 | // -------------------------------------------------------------------- 366 | 367 | /** 368 | * Get Error Message 369 | * 370 | * Gets the error message associated with a particular field 371 | * 372 | * @access public 373 | * @param string the field name 374 | * @return void 375 | */ 376 | public function error($field = '', $prefix = '', $suffix = '') 377 | { 378 | if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '') 379 | { 380 | return ''; 381 | } 382 | 383 | if ($prefix == '') 384 | { 385 | $prefix = $this->_error_prefix; 386 | } 387 | 388 | if ($suffix == '') 389 | { 390 | $suffix = $this->_error_suffix; 391 | } 392 | 393 | return $prefix.$this->_field_data[$field]['error'].$suffix; 394 | } 395 | 396 | // -------------------------------------------------------------------- 397 | 398 | /** 399 | * Error String 400 | * 401 | * Returns the error messages as a string, wrapped in the error delimiters 402 | * 403 | * @access public 404 | * @param string 405 | * @param string 406 | * @return str 407 | */ 408 | public function error_string($prefix = '', $suffix = '') 409 | { 410 | // No errrors, validation passes! 411 | if (count($this->_error_array) === 0) 412 | { 413 | return ''; 414 | } 415 | 416 | if ($prefix == '') 417 | { 418 | $prefix = $this->_error_prefix; 419 | } 420 | 421 | if ($suffix == '') 422 | { 423 | $suffix = $this->_error_suffix; 424 | } 425 | 426 | // Generate the error string 427 | $str = ''; 428 | foreach ($this->_error_array as $val) 429 | { 430 | if ($val != '') 431 | { 432 | $str .= $prefix.$val.$suffix."\n"; 433 | } 434 | } 435 | 436 | return $str; 437 | } 438 | 439 | // -------------------------------------------------------------------- 440 | 441 | /** 442 | * Run the Validator 443 | * 444 | * This function does all the work. 445 | * 446 | * @access public 447 | * @return bool 448 | */ 449 | public function run($groups = '') 450 | { 451 | // Do we even have any data to process? Mm? 452 | if (count($this->_request_data) == 0) 453 | { 454 | return FALSE; 455 | } 456 | 457 | // Does the _field_data array containing the validation rules exist? 458 | // If not, we look to see if they were assigned via a config file 459 | if (count($this->_field_data) == 0) 460 | { 461 | // No validation rules? We're done... 462 | if (count($this->_config_rules) == 0) 463 | { 464 | return FALSE; 465 | } 466 | 467 | // Is there a validation rule for the particular group being accessed? 468 | $groups = ($groups == '') ? '' : explode(",", $groups); 469 | 470 | if (is_array($groups)) 471 | { 472 | foreach($groups as $group) { 473 | if ($groups != '' AND isset($this->_config_rules[$group])) 474 | { 475 | $this->set_rules($this->_config_rules[$group]); 476 | } 477 | } 478 | } 479 | else 480 | { 481 | $this->set_rules($this->_config_rules); 482 | } 483 | 484 | // We're we able to set the rules correctly? 485 | if (count($this->_field_data) == 0) 486 | { 487 | //log_message('debug', "Unable to find validation rules"); 488 | return FALSE; 489 | } 490 | } 491 | 492 | // Load the language file containing error messages 493 | //$this->CI->lang->load('form_validation'); 494 | 495 | // Cycle through the rules for each field, match the 496 | // corresponding $_POST item and test for errors 497 | foreach ($this->_field_data as $field => $row) 498 | { 499 | // Fetch the data from the corresponding $_POST array and cache it in the _field_data array. 500 | // Depending on whether the field name is an array or a string will determine where we get it from. 501 | 502 | if ($row['is_array'] == TRUE) 503 | { 504 | $this->_field_data[$field]['postdata'] = $this->_reduce_array($this->_request_data, $row['keys']); 505 | } 506 | else 507 | { 508 | if (isset($this->_request_data[$field]) AND $this->_request_data[$field] != "") 509 | { 510 | $this->_field_data[$field]['postdata'] = $this->_request_data[$field]; 511 | } 512 | } 513 | 514 | $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']); 515 | } 516 | 517 | // Did we end up with any errors? 518 | $total_errors = count($this->_error_array); 519 | 520 | if ($total_errors > 0) 521 | { 522 | $this->_safe_form_data = TRUE; 523 | } 524 | 525 | // Now we need to re-set the POST data with the new, processed data 526 | $this->_reset_post_array(); 527 | 528 | // No errors, validation passes! 529 | if ($total_errors == 0) 530 | { 531 | return TRUE; 532 | } 533 | 534 | // Validation fails 535 | return FALSE; 536 | } 537 | 538 | // -------------------------------------------------------------------- 539 | 540 | /** 541 | * Traverse a multidimensional $this->_request_data array index until the data is found 542 | * 543 | * @access private 544 | * @param array 545 | * @param array 546 | * @param integer 547 | * @return mixed 548 | */ 549 | protected function _reduce_array($array, $keys, $i = 0) 550 | { 551 | if (is_array($array)) 552 | { 553 | if (isset($keys[$i])) 554 | { 555 | if (isset($array[$keys[$i]])) 556 | { 557 | $array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1)); 558 | } 559 | else 560 | { 561 | return NULL; 562 | } 563 | } 564 | else 565 | { 566 | return $array; 567 | } 568 | } 569 | 570 | return $array; 571 | } 572 | 573 | // -------------------------------------------------------------------- 574 | 575 | /** 576 | * Re-populate the _POST array with our finalized and processed data 577 | * 578 | * @access private 579 | * @return null 580 | */ 581 | protected function _reset_post_array() 582 | { 583 | foreach ($this->_field_data as $field => $row) 584 | { 585 | if ( ! is_null($row['postdata'])) 586 | { 587 | if ($row['is_array'] == FALSE) 588 | { 589 | if (isset($this->_request_data[$row['field']])) 590 | { 591 | $this->_request_data[$row['field']] = $this->prep_for_form($row['postdata']); 592 | } 593 | } 594 | else 595 | { 596 | // start with a reference 597 | $post_ref =& $this->_request_data; 598 | 599 | // before we assign values, make a reference to the right POST key 600 | if (count($row['keys']) == 1) 601 | { 602 | $post_ref =& $post_ref[current($row['keys'])]; 603 | } 604 | else 605 | { 606 | foreach ($row['keys'] as $val) 607 | { 608 | $post_ref =& $post_ref[$val]; 609 | } 610 | } 611 | 612 | if (is_array($row['postdata'])) 613 | { 614 | $array = array(); 615 | foreach ($row['postdata'] as $k => $v) 616 | { 617 | $array[$k] = $this->prep_for_form($v); 618 | } 619 | 620 | $post_ref = $array; 621 | } 622 | else 623 | { 624 | $post_ref = $this->prep_for_form($row['postdata']); 625 | } 626 | } 627 | } 628 | } 629 | } 630 | 631 | // -------------------------------------------------------------------- 632 | 633 | /** 634 | * Executes the Validation routines 635 | * 636 | * @access private 637 | * @param array 638 | * @param array 639 | * @param mixed 640 | * @param integer 641 | * @return mixed 642 | */ 643 | protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) 644 | { 645 | // If the $this->_request_data data is an array we will run a recursive call 646 | if (is_array($postdata)) 647 | { 648 | foreach ($postdata as $key => $val) 649 | { 650 | $this->_execute($row, $rules, $val, $cycles); 651 | $cycles++; 652 | } 653 | 654 | return; 655 | } 656 | 657 | // -------------------------------------------------------------------- 658 | 659 | // If the field is blank, but NOT required, no further tests are necessary 660 | $callback = FALSE; 661 | if ( ! in_array('required', $rules) AND is_null($postdata)) 662 | { 663 | // Before we bail out, does the rule contain a callback? 664 | if (preg_match("/(callback_\w+(\[.*?\])?)/", implode(' ', $rules), $match)) 665 | { 666 | $callback = TRUE; 667 | $rules = (array('1' => $match[1])); 668 | } 669 | else 670 | { 671 | return; 672 | } 673 | } 674 | 675 | // -------------------------------------------------------------------- 676 | 677 | // Isset Test. Typically this rule will only apply to checkboxes. 678 | if (is_null($postdata) AND $callback == FALSE) 679 | { 680 | if (in_array('isset', $rules, TRUE) OR in_array('required', $rules)) 681 | { 682 | // Set the message type 683 | $type = (in_array('required', $rules)) ? 'required' : 'isset'; 684 | 685 | if ( ! isset($this->_error_messages[$type])) 686 | { 687 | /*if (FALSE === ($line = $this->CI->lang->line($type))) 688 | {*/ 689 | $line = 'The field was not set'; 690 | /*}*/ 691 | } 692 | else 693 | { 694 | $line = $this->_error_messages[$type]; 695 | } 696 | 697 | // Build the error message 698 | $message = sprintf($line, $this->_translate_fieldname($row['label'])); 699 | 700 | // Save the error message 701 | $this->_field_data[$row['field']]['error'] = $message; 702 | 703 | if ( ! isset($this->_error_array[$row['field']])) 704 | { 705 | $this->_error_array[$row['field']] = $message; 706 | } 707 | } 708 | 709 | return; 710 | } 711 | 712 | // -------------------------------------------------------------------- 713 | 714 | // Cycle through each rule and run it 715 | foreach ($rules As $rule) 716 | { 717 | $_in_array = FALSE; 718 | 719 | // We set the $postdata variable with the current data in our master array so that 720 | // each cycle of the loop is dealing with the processed data from the last cycle 721 | if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata'])) 722 | { 723 | // We shouldn't need this safety, but just in case there isn't an array index 724 | // associated with this cycle we'll bail out 725 | if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles])) 726 | { 727 | continue; 728 | } 729 | 730 | $postdata = $this->_field_data[$row['field']]['postdata'][$cycles]; 731 | $_in_array = TRUE; 732 | } 733 | else 734 | { 735 | $postdata = $this->_field_data[$row['field']]['postdata']; 736 | } 737 | 738 | // -------------------------------------------------------------------- 739 | 740 | // Is the rule a callback? 741 | $callback = FALSE; 742 | if (substr($rule, 0, 9) == 'callback_') 743 | { 744 | $rule = substr($rule, 9); 745 | $callback = TRUE; 746 | } 747 | 748 | // Strip the parameter (if exists) from the rule 749 | // Rules can contain a parameter: max_length[5] 750 | $param = FALSE; 751 | if (preg_match("/(.*?)\[(.*)\]/", $rule, $match)) 752 | { 753 | $rule = $match[1]; 754 | $param = $match[2]; 755 | } 756 | 757 | // Call the function that corresponds to the rule 758 | if ($callback === TRUE) 759 | { 760 | 761 | // Run the function and grab the result 762 | $result = $this->$rule($postdata, $param); 763 | 764 | // Re-assign the result to the master data array 765 | if ($_in_array == TRUE) 766 | { 767 | $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result; 768 | } 769 | else 770 | { 771 | $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result; 772 | } 773 | 774 | // If the field isn't required and we just processed a callback we'll move on... 775 | if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE) 776 | { 777 | continue; 778 | } 779 | } 780 | else 781 | { 782 | if ( ! method_exists($this, $rule)) 783 | { 784 | // If our own wrapper function doesn't exist we see if a native PHP function does. 785 | // Users can use any native PHP function call that has one param. Now two, $value must be the first param 786 | if (function_exists($rule)) 787 | { 788 | if ($param) $result = $rule($postdata, $param); 789 | else $result = $rule($postdata); 790 | 791 | if ($_in_array == TRUE) 792 | { 793 | $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result; 794 | } 795 | else 796 | { 797 | $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result; 798 | } 799 | } 800 | else 801 | { 802 | //log_message('debug', "Unable to find validation rule: ".$rule); 803 | echo "Unable to find validation rule: ".$rule; 804 | } 805 | 806 | continue; 807 | } 808 | 809 | $result = $this->$rule($postdata, $param); 810 | if ($_in_array == TRUE) 811 | { 812 | $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result; 813 | } 814 | else 815 | { 816 | $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result; 817 | } 818 | 819 | // spaecial case 820 | if ($rule == 'cast_boolean') { 821 | $this->_field_data[$row['field']]['postdata'] = $result; 822 | $result = ""; 823 | } 824 | 825 | } 826 | 827 | // Did the rule test negatively? If so, grab the error. 828 | if ($result === FALSE) 829 | { 830 | if ( ! isset($this->_error_messages[$rule])) 831 | { 832 | //if (FALSE === ($line = $this->CI->lang->line($rule))) 833 | //{ 834 | $line = 'Unable to access an error message corresponding to your field name.'; 835 | //} 836 | } 837 | else 838 | { 839 | $line = $this->_error_messages[$rule]; 840 | } 841 | 842 | // Is the parameter we are inserting into the error message the name 843 | // of another field? If so we need to grab its "field label" 844 | if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label'])) 845 | { 846 | $param = $this->_translate_fieldname($this->_field_data[$param]['label']); 847 | } 848 | 849 | // Build the error message 850 | $message = sprintf($line, $this->_translate_fieldname($row['label']), $param); 851 | 852 | // Save the error message 853 | $this->_field_data[$row['field']]['error'] = $message; 854 | 855 | if ( ! isset($this->_error_array[$row['field']])) 856 | { 857 | $this->_error_array[$row['field']] = $message; 858 | } 859 | 860 | return; 861 | } 862 | } 863 | } 864 | 865 | // -------------------------------------------------------------------- 866 | 867 | /** 868 | * Translate a field name 869 | * 870 | * @access private 871 | * @param string the field name 872 | * @return string 873 | */ 874 | protected function _translate_fieldname($fieldname) 875 | { 876 | // Do we need to translate the field name? 877 | // We look for the prefix lang: to determine this 878 | if (substr($fieldname, 0, 5) == 'lang:') 879 | { 880 | // Grab the variable 881 | $line = substr($fieldname, 5); 882 | 883 | // Were we able to translate the field name? If not we use $line 884 | if (FALSE === ($fieldname = $this->CI->lang->line($line))) 885 | { 886 | return $line; 887 | } 888 | } 889 | 890 | return $fieldname; 891 | } 892 | 893 | // -------------------------------------------------------------------- 894 | 895 | /** 896 | * Required 897 | * 898 | * @access public 899 | * @param string 900 | * @return bool 901 | */ 902 | public function required($str) 903 | { 904 | if ( ! is_array($str)) 905 | { 906 | return (trim($str) == '') ? FALSE : TRUE; 907 | } 908 | else 909 | { 910 | return ( ! empty($str)); 911 | } 912 | } 913 | 914 | // -------------------------------------------------------------------- 915 | 916 | /** 917 | * Performs a Regular Expression match test. 918 | * 919 | * @access public 920 | * @param string 921 | * @param regex 922 | * @return bool 923 | */ 924 | public function regex_match($str, $regex) 925 | { 926 | if ( ! preg_match($regex, $str)) 927 | { 928 | return FALSE; 929 | } 930 | 931 | return TRUE; 932 | } 933 | 934 | // -------------------------------------------------------------------- 935 | 936 | /** 937 | * Match one field to another 938 | * 939 | * @access public 940 | * @param string 941 | * @param field 942 | * @return bool 943 | */ 944 | public function matches($str, $field) 945 | { 946 | if ( ! isset($this->_request_data[$field])) 947 | { 948 | return FALSE; 949 | } 950 | 951 | $field = $this->_request_data[$field]; 952 | 953 | return ($str !== $field) ? FALSE : TRUE; 954 | } 955 | 956 | // -------------------------------------------------------------------- 957 | 958 | /** 959 | * Match one field to another 960 | * 961 | * @access public 962 | * @param string 963 | * @param field 964 | * @return bool 965 | */ 966 | public function is_unique($str, $field) 967 | { 968 | list($table, $field)=explode('.', $field); 969 | $query = $this->db->select($table, array($field => $str)); 970 | 971 | return $query->num_rows() === 0; 972 | } 973 | 974 | // -------------------------------------------------------------------- 975 | 976 | /** 977 | * Minimum Length 978 | * 979 | * @access public 980 | * @param string 981 | * @param value 982 | * @return bool 983 | */ 984 | public function min_length($str, $val) 985 | { 986 | if (preg_match("/[^0-9]/", $val)) 987 | { 988 | return FALSE; 989 | } 990 | 991 | if (function_exists('mb_strlen')) 992 | { 993 | return (mb_strlen($str) < $val) ? FALSE : TRUE; 994 | } 995 | 996 | return (strlen($str) < $val) ? FALSE : TRUE; 997 | } 998 | 999 | // -------------------------------------------------------------------- 1000 | 1001 | /** 1002 | * Max Length 1003 | * 1004 | * @access public 1005 | * @param string 1006 | * @param value 1007 | * @return bool 1008 | */ 1009 | public function max_length($str, $val) 1010 | { 1011 | if (preg_match("/[^0-9]/", $val)) 1012 | { 1013 | return FALSE; 1014 | } 1015 | 1016 | if (function_exists('mb_strlen')) 1017 | { 1018 | return (mb_strlen($str) > $val) ? FALSE : TRUE; 1019 | } 1020 | 1021 | return (strlen($str) > $val) ? FALSE : TRUE; 1022 | } 1023 | 1024 | // -------------------------------------------------------------------- 1025 | 1026 | /** 1027 | * Exact Length 1028 | * 1029 | * @access public 1030 | * @param string 1031 | * @param value 1032 | * @return bool 1033 | */ 1034 | public function exact_length($str, $val) 1035 | { 1036 | if (preg_match("/[^0-9]/", $val)) 1037 | { 1038 | return FALSE; 1039 | } 1040 | 1041 | if (function_exists('mb_strlen')) 1042 | { 1043 | return (mb_strlen($str) != $val) ? FALSE : TRUE; 1044 | } 1045 | 1046 | return (strlen($str) != $val) ? FALSE : TRUE; 1047 | } 1048 | 1049 | // -------------------------------------------------------------------- 1050 | 1051 | /** 1052 | * Valid Email 1053 | * 1054 | * @access public 1055 | * @param string 1056 | * @return bool 1057 | */ 1058 | public function valid_email($str) 1059 | { 1060 | return filter_var($str, FILTER_VALIDATE_EMAIL); 1061 | // practical implementation of RFC 2822 1062 | return ( ! preg_match("/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9][a-z0-9-]*[a-z0-9]/ix", $str)) ? FALSE : TRUE; 1063 | // old php version 1064 | return ( ! preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/ix", $str)) ? FALSE : TRUE; 1065 | // CI version 1066 | return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,7}$/ix", $str)) ? FALSE : TRUE; 1067 | } 1068 | 1069 | // -------------------------------------------------------------------- 1070 | 1071 | /** 1072 | * Valid Email DNS 1073 | * 1074 | * Checks teh MX record of an email domain 1075 | * 1076 | * @access public 1077 | * @param string 1078 | * @return bool 1079 | */ 1080 | public function valid_email_dns($str) 1081 | { 1082 | if ($this->valid_email($str)) { 1083 | $host = substr($str, strpos($str, "@")+1); 1084 | return checkdnsrr($host, "MX"); 1085 | } else { 1086 | return FALSE; 1087 | } 1088 | } 1089 | 1090 | // -------------------------------------------------------------------- 1091 | 1092 | /** 1093 | * Valid Emails 1094 | * 1095 | * @access public 1096 | * @param string 1097 | * @return bool 1098 | */ 1099 | public function valid_emails($str) 1100 | { 1101 | if (strpos($str, ',') === FALSE) 1102 | { 1103 | return $this->valid_email(trim($str)); 1104 | } 1105 | 1106 | foreach (explode(',', $str) as $email) 1107 | { 1108 | if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE) 1109 | { 1110 | return FALSE; 1111 | } 1112 | } 1113 | 1114 | return TRUE; 1115 | } 1116 | 1117 | // -------------------------------------------------------------------- 1118 | 1119 | /** 1120 | * Valid URL 1121 | * 1122 | * Validates value as URL (according to » http://www.faqs.org/rfcs/rfc2396), 1123 | * optionally with required components. Note that the function will only find ASCII URLs 1124 | * to be valid; internationalized domain names (containing non-ASCII characters) will fail. 1125 | * 1126 | * @access public 1127 | * @param string 1128 | * @return bool 1129 | */ 1130 | public function valid_url($str) 1131 | { 1132 | return filter_var($str, FILTER_VALIDATE_URL); 1133 | } 1134 | 1135 | // -------------------------------------------------------------------- 1136 | 1137 | /** 1138 | * Validate IP Address 1139 | * 1140 | * @access public 1141 | * @param string 1142 | * @param string "ipv4" or "ipv6" to validate a specific ip format 1143 | * @return bool 1144 | */ 1145 | public function valid_ip($ip, $which = '') 1146 | { 1147 | $which = strtolower($which); 1148 | 1149 | // First check if filter_var is available 1150 | if (is_callable('filter_var')) 1151 | { 1152 | switch ($which) { 1153 | case 'ipv4': 1154 | $flag = FILTER_FLAG_IPV4; 1155 | break; 1156 | case 'ipv6': 1157 | $flag = FILTER_FLAG_IPV6; 1158 | break; 1159 | default: 1160 | $flag = ''; 1161 | break; 1162 | } 1163 | 1164 | return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag); 1165 | } 1166 | 1167 | if ($which !== 'ipv6' && $which !== 'ipv4') 1168 | { 1169 | if (strpos($ip, ':') !== FALSE) 1170 | { 1171 | $which = 'ipv6'; 1172 | } 1173 | elseif (strpos($ip, '.') !== FALSE) 1174 | { 1175 | $which = 'ipv4'; 1176 | } 1177 | else 1178 | { 1179 | return FALSE; 1180 | } 1181 | } 1182 | 1183 | $func = '_valid_'.$which; 1184 | return $this->$func($ip); 1185 | } 1186 | 1187 | // -------------------------------------------------------------------- 1188 | 1189 | /** 1190 | * Validate IPv4 Address 1191 | * 1192 | * Updated version suggested by Geert De Deckere 1193 | * 1194 | * @access protected 1195 | * @param string 1196 | * @return bool 1197 | */ 1198 | protected function _valid_ipv4($ip) 1199 | { 1200 | $ip_segments = explode('.', $ip); 1201 | 1202 | // Always 4 segments needed 1203 | if (count($ip_segments) !== 4) 1204 | { 1205 | return FALSE; 1206 | } 1207 | // IP can not start with 0 1208 | if ($ip_segments[0][0] == '0') 1209 | { 1210 | return FALSE; 1211 | } 1212 | 1213 | // Check each segment 1214 | foreach ($ip_segments as $segment) 1215 | { 1216 | // IP segments must be digits and can not be 1217 | // longer than 3 digits or greater then 255 1218 | if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3) 1219 | { 1220 | return FALSE; 1221 | } 1222 | } 1223 | 1224 | return TRUE; 1225 | } 1226 | 1227 | // -------------------------------------------------------------------- 1228 | 1229 | /** 1230 | * Validate IPv6 Address 1231 | * 1232 | * @access protected 1233 | * @param string 1234 | * @return bool 1235 | */ 1236 | protected function _valid_ipv6($str) 1237 | { 1238 | // 8 groups, separated by : 1239 | // 0-ffff per group 1240 | // one set of consecutive 0 groups can be collapsed to :: 1241 | 1242 | $groups = 8; 1243 | $collapsed = FALSE; 1244 | 1245 | $chunks = array_filter( 1246 | preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE) 1247 | ); 1248 | 1249 | // Rule out easy nonsense 1250 | if (current($chunks) == ':' OR end($chunks) == ':') 1251 | { 1252 | return FALSE; 1253 | } 1254 | 1255 | // PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well 1256 | if (strpos(end($chunks), '.') !== FALSE) 1257 | { 1258 | $ipv4 = array_pop($chunks); 1259 | 1260 | if ( ! $this->_valid_ipv4($ipv4)) 1261 | { 1262 | return FALSE; 1263 | } 1264 | 1265 | $groups--; 1266 | } 1267 | 1268 | while ($seg = array_pop($chunks)) 1269 | { 1270 | if ($seg[0] == ':') 1271 | { 1272 | if (--$groups == 0) 1273 | { 1274 | return FALSE; // too many groups 1275 | } 1276 | 1277 | if (strlen($seg) > 2) 1278 | { 1279 | return FALSE; // long separator 1280 | } 1281 | 1282 | if ($seg == '::') 1283 | { 1284 | if ($collapsed) 1285 | { 1286 | return FALSE; // multiple collapsed 1287 | } 1288 | 1289 | $collapsed = TRUE; 1290 | } 1291 | } 1292 | elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4) 1293 | { 1294 | return FALSE; // invalid segment 1295 | } 1296 | } 1297 | 1298 | return $collapsed OR $groups == 1; 1299 | } 1300 | 1301 | // -------------------------------------------------------------------- 1302 | 1303 | /** 1304 | * Boolean 1305 | * 1306 | * @access public 1307 | * @param string 1308 | * @return bool 1309 | */ 1310 | public function cast_boolean($str) 1311 | { 1312 | 1313 | switch ($str) { 1314 | case "true": return TRUE; break; 1315 | case "false": return FALSE; break; 1316 | case "1": return TRUE; break; 1317 | case "0": return FALSE; break; 1318 | case "yes": return TRUE; break; 1319 | case "no": return FALSE; break; 1320 | case "on": return TRUE; break; 1321 | case "off": return FALSE; break; 1322 | default: return $str; 1323 | } 1324 | } 1325 | 1326 | /** 1327 | * Boolean 1328 | * 1329 | * @access public 1330 | * @param string 1331 | * @return bool 1332 | */ 1333 | public function boolean($str) 1334 | { 1335 | return (bool) is_bool($str); 1336 | //return filter_var($str, FILTER_VALIDATE_BOOLEAN); 1337 | } 1338 | 1339 | // -------------------------------------------------------------------- 1340 | 1341 | /** 1342 | * Alpha 1343 | * 1344 | * @access public 1345 | * @param string 1346 | * @return bool 1347 | */ 1348 | public function alpha($str) 1349 | { 1350 | return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE; 1351 | } 1352 | 1353 | // -------------------------------------------------------------------- 1354 | 1355 | /** 1356 | * Alpha-numeric 1357 | * 1358 | * @access public 1359 | * @param string 1360 | * @return bool 1361 | */ 1362 | public function alpha_numeric($str) 1363 | { 1364 | return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE; 1365 | } 1366 | 1367 | // -------------------------------------------------------------------- 1368 | 1369 | /** 1370 | * Alpha-numeric with underscores and dashes 1371 | * 1372 | * @access public 1373 | * @param string 1374 | * @return bool 1375 | */ 1376 | public function alpha_dash($str) 1377 | { 1378 | return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE; 1379 | } 1380 | 1381 | // -------------------------------------------------------------------- 1382 | 1383 | /** 1384 | * Numeric 1385 | * 1386 | * @access public 1387 | * @param string 1388 | * @return bool 1389 | */ 1390 | public function numeric($str) 1391 | { 1392 | return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str); 1393 | 1394 | } 1395 | 1396 | // -------------------------------------------------------------------- 1397 | 1398 | /** 1399 | * Is Numeric 1400 | * 1401 | * @access public 1402 | * @param string 1403 | * @return bool 1404 | */ 1405 | public function is_numeric($str) 1406 | { 1407 | return ( ! is_numeric($str)) ? FALSE : TRUE; 1408 | } 1409 | 1410 | // -------------------------------------------------------------------- 1411 | 1412 | /** 1413 | * Integer 1414 | * 1415 | * @access public 1416 | * @param string 1417 | * @return bool 1418 | */ 1419 | public function integer($str) 1420 | { 1421 | return (bool) preg_match('/^[\-+]?[0-9]+$/', $str); 1422 | } 1423 | 1424 | // -------------------------------------------------------------------- 1425 | 1426 | /** 1427 | * Decimal number 1428 | * 1429 | * @access public 1430 | * @param string 1431 | * @return bool 1432 | */ 1433 | public function decimal($str) 1434 | { 1435 | return (bool) preg_match('/^[\-+]?[0-9]+\.[0-9]+$/', $str); 1436 | } 1437 | 1438 | // -------------------------------------------------------------------- 1439 | 1440 | /** 1441 | * Greather than 1442 | * 1443 | * @access public 1444 | * @param string 1445 | * @return bool 1446 | */ 1447 | public function greater_than($str, $min) 1448 | { 1449 | if ( ! is_numeric($str)) 1450 | { 1451 | return FALSE; 1452 | } 1453 | return $str > $min; 1454 | } 1455 | 1456 | // -------------------------------------------------------------------- 1457 | 1458 | /** 1459 | * Less than 1460 | * 1461 | * @access public 1462 | * @param string 1463 | * @return bool 1464 | */ 1465 | public function less_than($str, $max) 1466 | { 1467 | if ( ! is_numeric($str)) 1468 | { 1469 | return FALSE; 1470 | } 1471 | return $str < $max; 1472 | } 1473 | 1474 | // -------------------------------------------------------------------- 1475 | 1476 | /** 1477 | * Is a Natural number (0,1,2,3, etc.) 1478 | * 1479 | * @access public 1480 | * @param string 1481 | * @return bool 1482 | */ 1483 | public function is_natural($str) 1484 | { 1485 | return (bool) preg_match( '/^[0-9]+$/', $str); 1486 | } 1487 | 1488 | // -------------------------------------------------------------------- 1489 | 1490 | /** 1491 | * Is a Natural number, but not a zero (1,2,3, etc.) 1492 | * 1493 | * @access public 1494 | * @param string 1495 | * @return bool 1496 | */ 1497 | public function is_natural_no_zero($str) 1498 | { 1499 | if ( ! preg_match( '/^[0-9]+$/', $str)) 1500 | { 1501 | return FALSE; 1502 | } 1503 | 1504 | if ($str == 0) 1505 | { 1506 | return FALSE; 1507 | } 1508 | 1509 | return TRUE; 1510 | } 1511 | 1512 | // -------------------------------------------------------------------- 1513 | 1514 | /** 1515 | * Valid Base64 1516 | * 1517 | * Tests a string for characters outside of the Base64 alphabet 1518 | * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045 1519 | * 1520 | * @access public 1521 | * @param string 1522 | * @return bool 1523 | */ 1524 | public function valid_base64($str) 1525 | { 1526 | return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str); 1527 | } 1528 | 1529 | // -------------------------------------------------------------------- 1530 | 1531 | /** 1532 | * Valid Mail Code 1533 | * 1534 | * @access public 1535 | * @param string 1536 | * @param string 1537 | * @return bool 1538 | */ 1539 | public function valid_mail_code($str, $country_code) 1540 | { 1541 | return TRUE; 1542 | } 1543 | 1544 | // -------------------------------------------------------------------- 1545 | 1546 | /** 1547 | * Valid Phone Number 1548 | * 1549 | * @access public 1550 | * @param string 1551 | * @param string 1552 | * @return bool 1553 | */ 1554 | public function valid_phone($str, $type) 1555 | { 1556 | return TRUE; 1557 | switch ($type) { 1558 | case "+": // +1 (XXX) XXX-XXXX 1559 | return $this->match("/(\d)/", $str); 1560 | default: // (XXX) XXX-XXXX 1561 | return $this->match("/(\d)/", $str); 1562 | } 1563 | } 1564 | 1565 | // -------------------------------------------------------------------- 1566 | 1567 | /** 1568 | * Prep data for form 1569 | * 1570 | * This function allows HTML to be safely shown in a form. 1571 | * Special characters are converted. 1572 | * 1573 | * @access public 1574 | * @param string 1575 | * @return string 1576 | */ 1577 | public function prep_for_form($data = '') 1578 | { 1579 | if (is_array($data)) 1580 | { 1581 | foreach ($data as $key => $val) 1582 | { 1583 | $data[$key] = $this->prep_for_form($val); 1584 | } 1585 | 1586 | return $data; 1587 | } 1588 | 1589 | if ($this->_safe_form_data == FALSE OR $data === '') 1590 | { 1591 | return $data; 1592 | } 1593 | 1594 | return str_replace(array("'", '"', '<', '>'), array("'", """, '<', '>'), stripslashes($data)); 1595 | } 1596 | 1597 | // -------------------------------------------------------------------- 1598 | 1599 | /** 1600 | * Prep URL 1601 | * 1602 | * @access public 1603 | * @param string 1604 | * @return string 1605 | */ 1606 | public function prep_url($str = '') 1607 | { 1608 | if ($str == 'http://' OR $str == '') 1609 | { 1610 | return ''; 1611 | } 1612 | 1613 | if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://') 1614 | { 1615 | $str = 'http://'.$str; 1616 | } 1617 | 1618 | return $str; 1619 | } 1620 | 1621 | // -------------------------------------------------------------------- 1622 | 1623 | /** 1624 | * Strip Image Tags 1625 | * 1626 | * @access public 1627 | * @param string 1628 | * @return string 1629 | */ 1630 | /*public function strip_image_tags($str) 1631 | { 1632 | return $this->CI->input->strip_image_tags($str); 1633 | }*/ 1634 | 1635 | // -------------------------------------------------------------------- 1636 | 1637 | /** 1638 | * XSS Clean 1639 | * 1640 | * @access public 1641 | * @param string 1642 | * @return string 1643 | */ 1644 | /*public function xss_clean($str) 1645 | { 1646 | return $this->CI->security->xss_clean($str); 1647 | }*/ 1648 | 1649 | // -------------------------------------------------------------------- 1650 | 1651 | /** 1652 | * Convert PHP tags to entities 1653 | * 1654 | * @access public 1655 | * @param string 1656 | * @return string 1657 | */ 1658 | public function encode_php_tags($str) 1659 | { 1660 | return str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $str); 1661 | } 1662 | 1663 | // -------------------------------------------------------------------- 1664 | 1665 | /** 1666 | * sanitize strings 1667 | * 1668 | * @access public 1669 | * @param string 1670 | * @return string 1671 | */ 1672 | public function sanitize_string($str) 1673 | { 1674 | return filter_var($str, FILTER_SANITIZE_STRING); 1675 | } 1676 | } 1677 | 1678 | $filter = new Filter($config); 1679 | 1680 | 1681 | ?> -------------------------------------------------------------------------------- /class.redis.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2001 - 2012 willFarrell.ca 12 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 13 | * @version GIT: 14 | * @link http://willFarrell.ca 15 | */ 16 | 17 | require_once 'Predis/Autoloader.php'; // https://github.com/nrk/predis 18 | Predis\Autoloader::register(); 19 | 20 | /** 21 | * Database 22 | * 23 | * @category N/A 24 | * @package N/A 25 | * @author Original Author 26 | * @author Another Author 27 | * @copyright 2001 - 2011 willFarrell.ca 28 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 29 | * @version Release: 30 | * @link http://willFarrell.ca 31 | */ 32 | 33 | class Redis extends MySQL 34 | { 35 | var $connection_redis; //The redis database connection 36 | 37 | /** 38 | * Constructor 39 | * prefix in teh form of 'prefix:' 40 | */ 41 | function __construct($prefix = '') 42 | { 43 | $this->connection_redis = new Predis\Client( 44 | array( 45 | 'host' => '127.0.0.1', 46 | 'port' => 6379 47 | ), 48 | array('prefix' => $prefix) 49 | ); 50 | } 51 | 52 | /** 53 | * Destructor 54 | */ 55 | function __destruct() 56 | { 57 | 58 | } 59 | 60 | //-- Generic --// 61 | // http://redis.io/commands#generic 62 | function del($key) 63 | { 64 | return $this->connection_redis->del($key); 65 | } 66 | 67 | //-- String --// 68 | // http://redis.io/commands#string 69 | 70 | /*function mget($key_array = array()) 71 | { 72 | return json_decode($this->connection_redis->get($key)); 73 | }*/ 74 | function get($key) 75 | { 76 | return json_decode($this->connection_redis->get($key)); 77 | } 78 | 79 | /*function mset($key_value_array = array()) 80 | { 81 | return $this->connection_redis->set($key, json_encode($value)); 82 | }*/ 83 | function set($key, $value) 84 | { 85 | return $this->connection_redis->set($key, json_encode($value)); 86 | } 87 | 88 | 89 | 90 | //-- Hash --// 91 | // http://redis.io/commands#hash 92 | 93 | function hgetall($hash_key) 94 | { 95 | $object = $this->connection_redis->hgetall($hash_key); 96 | foreach ($object as $key => $value) { 97 | $object[$key] = json_decode($value); 98 | } 99 | return $object; 100 | } 101 | 102 | /*function hmget($hash_key, $field_array = array()) 103 | { 104 | $object = $this->connection_redis->hmget($hash_key); 105 | foreach ($object as $key => $value) { 106 | $object[$key] = json_decode($value); 107 | } 108 | return $object; 109 | }*/ 110 | 111 | function hget($hash_key, $field) 112 | { 113 | return json_decode($this->connection_redis->hget($hash_key, $field)); 114 | } 115 | 116 | function hmset($hash_key, $field_value_array = array()) 117 | { 118 | foreach ($field_value_array as $key => $value) { 119 | $this->hset($hash_key, $key, json_decode($value)); 120 | } 121 | return; 122 | } 123 | 124 | function hset($hash_key, $field, $value) 125 | { 126 | return $this->connection_redis->hset($hash_key, $field, json_encode($value)); 127 | } 128 | }; 129 | 130 | ?> -------------------------------------------------------------------------------- /class.session.php: -------------------------------------------------------------------------------- 1 | db = $database; 37 | $this->redis = new Redis('session:'); 38 | 39 | $this->domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false; 40 | ini_set('session.cookie_domain',$this->domain); 41 | ini_set('session.use_only_cookies','1'); 42 | 43 | $this->id = (isset($_COOKIE['PHPSESSID'])) ? $_COOKIE['PHPSESSID'] : 0; 44 | 45 | //if(!isset($_SERVER['HTTPS'])) putenv('HTTPS=off'); 46 | 47 | 48 | 49 | $data = $this->redis->get($this->id); 50 | 51 | if (!$data) { 52 | $this->create(); 53 | } else { 54 | foreach ($data as $key => $value) { 55 | $this->cookie[$key] = $value; 56 | } 57 | } 58 | $this->load(); 59 | 60 | //if(isset($_SESSION['URL'])) $_SESSION['LAST_URL'] = $_SESSION['URL']; 61 | //if(getenv("REQUEST_URI") != '/login') $_SESSION['URL'] = getenv("REQUEST_URI"); 62 | //echo $_SESSION['LAST_URL']." = ".$_SESSION['URL']; 63 | } 64 | 65 | function __destruct() { 66 | 67 | } 68 | 69 | function create() { 70 | $this->cookie["user_ID"] = 0; 71 | $this->cookie["company_ID"] = 0; 72 | $this->cookie["user_level"] = 0; 73 | 74 | $this->save(); 75 | } 76 | 77 | function save() { 78 | $this->redis->set($this->id, $this->cookie); 79 | } 80 | 81 | function load() { 82 | foreach ($this->cookie as $key => $value) { 83 | if (!defined($key)) define($key, $value); 84 | } 85 | } 86 | 87 | function clear() { 88 | $this->cookie = array(); 89 | $this->create(); 90 | } 91 | 92 | // reset session_ID for security 93 | function login($user, $pass) { 94 | 95 | $query = "SELECT * FROM users WHERE user_email = '{{user_email}}' LIMIT 0,1"; 96 | $result = $this->db->query($query, array('user_email' => $user)); 97 | if (!$result) return false; // user / pass combo not found 98 | 99 | $r = mysql_fetch_assoc($result); 100 | 101 | if (!bcrypt_check($pass, $r['password'])) { 102 | return false; // pass doesn't match 103 | } 104 | 105 | // load usesr data 106 | $return = array(); 107 | $return["user_ID"] = $this->cookie["user_ID"] = $r['user_ID']; 108 | $return["company_ID"] = $this->cookie["company_ID"] = $r['company_ID']; 109 | $return["user_name"] = $r['user_name']; 110 | $return["password_timestamp"] = $r['password_timestamp']; 111 | 112 | $this->cookie["user_level"] = $r['user_level']; 113 | 114 | $this->load(); 115 | $this->save(); 116 | return $return; 117 | } 118 | 119 | function logout() { 120 | $this->clear(); 121 | 122 | set_cookie_fix_domain('PHPSESSID', session_id(), $_SERVER['REQUEST_TIME']-COOKIE_EXPIRE, COOKIE_PATH, $this->domain); 123 | } 124 | 125 | 126 | 127 | }; 128 | 129 | $session = new Session; 130 | 131 | 132 | ?> -------------------------------------------------------------------------------- /class.timer.php: -------------------------------------------------------------------------------- 1 | id = $id; 17 | } 18 | 19 | function __destruct() { 20 | 21 | } 22 | 23 | /* start the timer */ 24 | function start($id=NULL) { 25 | if ($id==NULL) $id = $this->id; 26 | if (isset($this->timers[$id])) { 27 | $this->timers[$id]['count']++; 28 | } else { 29 | $this->timers[$id] = array( 30 | 'timer' => array(), 31 | 'count' => 0, 32 | ); 33 | } 34 | 35 | $this->timers[$id]['timer'][$this->timers[$id]['count']] = new Timer; 36 | $this->timers[$id]['timer'][$this->timers[$id]['count']]->start(); 37 | } 38 | 39 | /* pause the timer */ 40 | function pause($id=NULL) { 41 | if ($id==NULL) $id = $this->id; 42 | $this->timers[$id]['timer'][$this->timers[$id]['count']]->pause(); 43 | } 44 | 45 | /* unpause the timer */ 46 | function unpause($id=NULL) { 47 | if ($id==NULL) $id = $this->id; 48 | $this->timers[$id]['timer'][$this->timers[$id]['count']]->unpause(); 49 | } 50 | 51 | /* stop the timer */ 52 | function stop($id=NULL) { 53 | if ($id==NULL) $id = $this->id; 54 | $this->timers[$id]['timer'][$this->timers[$id]['count']]->stop(); 55 | } 56 | 57 | function results($id=NULL) { 58 | if ($id==NULL) $id = $this->id; 59 | 60 | $results = array(); 61 | $array_size = count($this->timers[$id]['timer']); 62 | for($i = 0; $i < $array_size; $i++) { 63 | $results[$i] = $this->timers[$id]['timer'][$i]->duration(); 64 | } 65 | 66 | $return = array(); 67 | $return['min'] = min($results); 68 | $return['max'] = max($results); 69 | $return['avg'] = array_sum($results) / $array_size; 70 | return $return; 71 | } 72 | 73 | function results_all() { 74 | $results = array(); 75 | foreach ($this->timers as $key => $value) { 76 | $results[$key] = $this->results($key); 77 | } 78 | return $results; 79 | } 80 | 81 | function clear($id=NULL) { 82 | if ($id==NULL) $id = $this->id; 83 | unset($this->timers[$id]); 84 | } 85 | 86 | function clear_all() { 87 | unset($this->timers); 88 | } 89 | } 90 | 91 | // source http://davidwalsh.name/php-timer-benchmark 92 | // duration added by will Farrell 93 | class Timer { 94 | 95 | function __construct() { 96 | 97 | } 98 | 99 | function __destruct() { 100 | 101 | } 102 | 103 | /* start the timer */ 104 | function start() { 105 | $this->start_time = $this->get_time(); 106 | $this->pause_time = 0; 107 | } 108 | 109 | /* pause the timer */ 110 | function pause() { 111 | $this->pause_time = $this->get_time(); 112 | } 113 | 114 | /* unpause the timer */ 115 | function unpause() { 116 | $this->start_time += ($this->get_time() - $this->pause_time); 117 | $this->pause_time = 0; 118 | } 119 | 120 | /* stop the timer */ 121 | function stop() { 122 | $this->stop_time = $this->get_time(); 123 | //return $this->stop_time; 124 | } 125 | 126 | /* duration the timer */ 127 | function duration() { 128 | $this->duration = (isset($this->stop_time) ? $this->stop_time : 0) - $this->start_time; 129 | return $this->duration; 130 | } 131 | 132 | /* get the current timer value */ 133 | function get($decimals = 8) { 134 | return round(($this->get_time() - $this->start),$decimals); 135 | } 136 | 137 | /* format the time in seconds */ 138 | function get_time() { 139 | list($usec,$sec) = explode(' ', microtime()); 140 | return ((float)$usec + (float)$sec); 141 | } 142 | } 143 | 144 | $timer = new Timers; 145 | 146 | ?> -------------------------------------------------------------------------------- /inc.filter.php: -------------------------------------------------------------------------------- 1 | array( 14 | array( 15 | 'field' => 'email', 16 | 'label' => 'Email', 17 | 'rules' => 'required' 18 | ), 19 | array( 20 | 'field' => 'password', 21 | 'label' => 'Password', 22 | 'rules' => 'required' 23 | ), 24 | ), 25 | 'email' => array( 26 | array( 27 | 'field' => 'email', 28 | 'label' => 'Email', 29 | 'rules' => 'trim|required|valid_email|valid_email_dns' 30 | ), 31 | ), 32 | 'password' => array( 33 | array( 34 | 'field' => 'password', 35 | 'label' => 'Password', 36 | 'rules' => 'required|min_length[8]' 37 | ), 38 | ), 39 | 'signature' => array( 40 | array( 41 | 'field' => 'signature', 42 | 'label' => 'Signature', 43 | 'rules' => 'required' 44 | ), 45 | ), 46 | 'approve_company' => array( 47 | array( 48 | 'field' => 'tender_ID', 49 | 'label' => 'Tender ID', 50 | 'rules' => 'required|is_natural_no_zero' 51 | ), 52 | array( 53 | 'field' => 'company_ID', 54 | 'label' => 'Company ID', 55 | 'rules' => 'required|is_natural_no_zero' 56 | ), 57 | array( 58 | 'field' => 'approve', 59 | 'label' => 'Approve', 60 | 'rules' => 'required|cast_boolean|boolean' 61 | ), 62 | ), 63 | 'keyword' => array( 64 | array( 65 | 'field' => 'keyword', 66 | 'label' => 'Keyword', 67 | 'rules' => 'trim' 68 | ), 69 | ), 70 | 71 | //-- DB Tables --// 72 | 'companies' => array( 73 | array( 74 | 'field' => 'company_ID', 75 | 'label' => 'Company ID', 76 | 'rules' => 'is_natural_no_zero' 77 | ), 78 | array( 79 | 'field' => 'username', 80 | 'label' => 'Username', 81 | 'rules' => '' 82 | ), 83 | array( 84 | 'field' => 'company_name', 85 | 'label' => 'Company Name', 86 | 'rules' => '' 87 | ), 88 | array( 89 | 'field' => 'company_url', 90 | 'label' => 'URL', 91 | 'rules' => 'prep_url|valid_url' 92 | ), 93 | array( 94 | 'field' => 'company_phone', 95 | 'label' => 'Company Phone', 96 | 'rules' => 'valid_phone' 97 | ), 98 | array( 99 | 'field' => 'company_fax', 100 | 'label' => 'Company Fax', 101 | 'rules' => 'valid_phone' 102 | ), 103 | array( 104 | 'field' => 'company_details', 105 | 'label' => 'Company Details', 106 | 'rules' => 'strip_tags[b,strong,i,strike,u,ul,li]' 107 | ), 108 | array( 109 | 'field' => 'categories', 110 | 'label' => 'Categories', 111 | 'rules' => '' 112 | ), 113 | array( 114 | 'field' => 'tags', 115 | 'label' => 'Tags', 116 | 'rules' => '' 117 | ), 118 | array( 119 | 'field' => 'user_ID', 120 | 'label' => 'User ID', 121 | 'rules' => 'is_natural_no_zero' 122 | ), 123 | array( 124 | 'field' => 'location_ID', 125 | 'label' => 'Location', 126 | 'rules' => 'is_natural_no_zero' 127 | ), 128 | array( 129 | 'field' => 'company_type', 130 | 'label' => 'Company Type', 131 | 'rules' => 'is_natural_no_zero' 132 | ), 133 | 134 | array( 135 | 'field' => 'timestamp_create', 136 | 'label' => 'Create Timestamp', 137 | 'rules' => 'integer' 138 | ), 139 | array( 140 | 'field' => 'timestamp_update', 141 | 'label' => 'Update Timestamp', 142 | 'rules' => 'integer' 143 | ), 144 | ), 145 | 'locations' => array( 146 | array( 147 | 'field' => 'location_ID', 148 | 'label' => 'Location', 149 | 'rules' => 'is_natural_no_zero' 150 | ), 151 | array( 152 | 'field' => 'company_ID', 153 | 'label' => 'Company ID', 154 | 'rules' => 'is_natural_no_zero' 155 | ), 156 | array( 157 | 'field' => 'location_name', 158 | 'label' => 'Location Name', 159 | 'rules' => '' 160 | ), 161 | array( 162 | 'field' => 'address_1', 163 | 'label' => 'Address', 164 | 'rules' => 'trim' 165 | ), 166 | array( 167 | 'field' => 'address_2', 168 | 'label' => 'Address', 169 | 'rules' => 'trim' 170 | ), 171 | array( 172 | 'field' => 'city', 173 | 'label' => 'City', 174 | 'rules' => 'trim' 175 | ), 176 | array( 177 | 'field' => 'region_code', 178 | 'label' => 'Region Code', 179 | 'rules' => 'exact_length[2]' 180 | ), 181 | array( 182 | 'field' => 'country_code', 183 | 'label' => 'Country Code', 184 | 'rules' => 'exact_length[2]' 185 | ), 186 | array( 187 | 'field' => 'mail_code', 188 | 'label' => 'Mail Code', 189 | 'rules' => 'valid_mail_code' 190 | ), 191 | array( 192 | 'field' => 'logitude', 193 | 'label' => 'Longitude', 194 | 'rules' => 'number' 195 | ), 196 | array( 197 | 'field' => 'latitude', 198 | 'label' => 'Latitude', 199 | 'rules' => 'number' 200 | ), 201 | array( 202 | 'field' => 'phone', 203 | 'label' => 'Location Phone', 204 | 'rules' => 'valid_phone' 205 | ), 206 | array( 207 | 'field' => 'fax', 208 | 'label' => 'Location Fax', 209 | 'rules' => 'valid_phone' 210 | ), 211 | ), 212 | 'users' => array( 213 | array( 214 | 'field' => 'user_ID', 215 | 'label' => 'User ID', 216 | 'rules' => 'is_natural_no_zero' 217 | ), 218 | array( 219 | 'field' => 'company_ID', 220 | 'label' => 'Company ID', 221 | 'rules' => 'is_natural_no_zero' 222 | ), 223 | array( 224 | 'field' => 'user_level', 225 | 'label' => 'Level', 226 | 'rules' => 'is_natural' 227 | ), 228 | array( 229 | 'field' => 'user_name', 230 | 'label' => 'Name', 231 | 'rules' => 'trim' 232 | ), 233 | array( 234 | 'field' => 'user_email', 235 | 'label' => 'User Email', 236 | 'rules' => 'valid_email|valid_email_dns',//|is_unique[users.user_email]' use when creating 237 | ), 238 | array( 239 | 'field' => 'user_cell', 240 | 'label' => 'Cell', 241 | 'rules' => 'valid_phone' 242 | ), 243 | array( 244 | 'field' => 'user_phone', 245 | 'label' => 'Phone', 246 | 'rules' => 'valid_phone' 247 | ), 248 | array( 249 | 'field' => 'user_fax', 250 | 'label' => 'Fax', 251 | 'rules' => 'valid_phone' 252 | ), 253 | array( 254 | 'field' => 'user_function', 255 | 'label' => 'Function', 256 | 'rules' => '' 257 | ), 258 | array( 259 | 'field' => 'password', 260 | 'label' => 'Password', 261 | 'rules' => 'min_length[8]' 262 | ), 263 | array( 264 | 'field' => 'password_timestamp', 265 | 'label' => 'Passowrd Timestamp', 266 | 'rules' => 'integer' 267 | ), 268 | 269 | array( 270 | 'field' => 'timestamp_create', 271 | 'label' => 'Create Timestamp', 272 | 'rules' => 'integer' 273 | ), 274 | array( 275 | 'field' => 'timestamp_update', 276 | 'label' => 'Update Timestamp', 277 | 'rules' => 'integer' 278 | ), 279 | 280 | // not in table, but needed for confirms 281 | array( 282 | 'field' => 'user_email_confirm', 283 | 'label' => 'User Email Confirm', 284 | 'rules' => 'matches[user_email]', 285 | ), 286 | array( 287 | 'field' => 'password_confirm', 288 | 'label' => 'Password Confirm', 289 | 'rules' => 'matches[password]', 290 | ), 291 | ), 292 | 'tenders' => array( 293 | array( 294 | 'field' => 'tender_ID', 295 | 'label' => 'Tender ID', 296 | 'rules' => 'is_natural_no_zero' 297 | ), 298 | array( 299 | 'field' => 'company_ID', 300 | 'label' => 'Company ID', 301 | 'rules' => 'is_natural_no_zero' 302 | ), 303 | array( 304 | 'field' => 'title', 305 | 'label' => 'Title', 306 | 'rules' => '' 307 | ), 308 | array( 309 | 'field' => 'ref_ID', 310 | 'label' => 'Reference ID', 311 | 'rules' => '' 312 | ), 313 | array( 314 | 'field' => 'tender_type', 315 | 'label' => 'Tender Type', 316 | 'rules' => 'is_natural_no_zero' 317 | ), 318 | array( 319 | 'field' => 'details', 320 | 'label' => 'Details', 321 | 'rules' => '' 322 | ), 323 | array( 324 | 'field' => 'categories', 325 | 'label' => 'Categories', 326 | 'rules' => '' 327 | ), 328 | array( 329 | 'field' => 'tags', 330 | 'label' => 'Tags', 331 | 'rules' => '' 332 | ), 333 | array( 334 | 'field' => 'users', 335 | 'label' => 'Users', 336 | 'rules' => '' 337 | ), 338 | array( 339 | 'field' => 'location_ID', 340 | 'label' => 'Location', 341 | 'rules' => 'is_natural_no_zero' 342 | ), 343 | array( 344 | 'field' => 'post_timestamp', 345 | 'label' => 'Post Date & Time', 346 | 'rules' => 'integer' 347 | ), 348 | array( 349 | 'field' => 'question_timestamp', 350 | 'label' => 'Question Date & Time', 351 | 'rules' => 'integer|greater_than[post_timestamp]' 352 | ), 353 | array( 354 | 'field' => 'close_timestamp', 355 | 'label' => 'Close Date & Time', 356 | 'rules' => 'integer|greater_than[question_timestamp]' 357 | ), 358 | array( 359 | 'field' => 'url', 360 | 'label' => 'URL', 361 | 'rules' => 'prep_url|valid_url' 362 | ), 363 | array( 364 | 'field' => 'nda_ID', 365 | 'label' => 'NDA ID', 366 | 'rules' => 'is_natural_no_zero' 367 | ), 368 | array( 369 | 'field' => 'approval_required', 370 | 'label' => 'Approval Required', 371 | 'rules' => 'cast_boolean|boolean' 372 | ), 373 | array( 374 | 'field' => 'timestamp_create', 375 | 'label' => 'Create Timestamp', 376 | 'rules' => 'integer' 377 | ), 378 | array( 379 | 'field' => 'timestamp_update', 380 | 'label' => 'Update Timestamp', 381 | 'rules' => 'integer' 382 | ), 383 | ), 384 | 'ndas' => array( 385 | array( 386 | 'field' => 'nda_ID', 387 | 'label' => 'NDA ID', 388 | 'rules' => 'is_natural_no_zero' 389 | ), 390 | array( 391 | 'field' => 'company_ID', 392 | 'label' => 'Company ID', 393 | 'rules' => 'is_natural_no_zero' 394 | ), 395 | array( 396 | 'field' => 'nda_title', 397 | 'label' => 'Title', 398 | 'rules' => 'trim' 399 | ), 400 | array( 401 | 'field' => 'nda_details', 402 | 'label' => 'Details', 403 | 'rules' => 'trim' 404 | ), 405 | array( 406 | 'field' => 'timestamp_create', 407 | 'label' => 'Create Timestamp', 408 | 'rules' => 'integer' 409 | ), 410 | array( 411 | 'field' => 'timestamp_update', 412 | 'label' => 'Update Timestamp', 413 | 'rules' => 'integer' 414 | ), 415 | ), 416 | 'bids' => array( 417 | array( 418 | 'field' => 'bid_ID', 419 | 'label' => 'Bid ID', 420 | 'rules' => 'is_natural_no_zero' 421 | ), 422 | array( 423 | 'field' => 'tender_ID', 424 | 'label' => 'Tender ID', 425 | 'rules' => 'is_natural_no_zero' 426 | ), 427 | array( 428 | 'field' => 'bid_value', 429 | 'label' => 'Value', 430 | 'rules' => 'trim|decimal' 431 | ), 432 | array( 433 | 'field' => 'bid_details', 434 | 'label' => 'Details', 435 | 'rules' => 'trim' 436 | ), 437 | array( 438 | 'field' => 'bid_timestamp', 439 | 'label' => 'Bid Timestamp', 440 | 'rules' => 'integer' 441 | ), 442 | array( 443 | 'field' => 'bid_awarded', 444 | 'label' => 'Awarded', 445 | 'rules' => 'cast_boolean|boolean' 446 | ), 447 | ), 448 | ); 449 | 450 | ?> -------------------------------------------------------------------------------- /lib.global.php: -------------------------------------------------------------------------------- 1 | 31) $work_factor = 8; 16 | $salt = 17 | '$2a$' . str_pad($work_factor, 2, '0', STR_PAD_LEFT) . '$' . 18 | substr( 19 | strtr(base64_encode(openssl_random_pseudo_bytes(16)), '+', '.'), 20 | 0, 22 21 | ) 22 | ; 23 | //echo "$password, $salt \n"; 24 | return crypt($password, $salt); 25 | } 26 | 27 | function bcrypt_check($password, $stored_hash, $legacy_handler = NULL) 28 | { 29 | if (version_compare(PHP_VERSION, '5.3') < 0) throw new Exception('Bcrypt requires PHP 5.3 or above'); 30 | 31 | if (bcrypt_is_legacy_hash($stored_hash)) { 32 | if ($legacy_handler) return call_user_func($legacy_handler, $password, $stored_hash); 33 | else throw new Exception('Unsupported hash format'); 34 | } 35 | 36 | return crypt($password, $stored_hash) == $stored_hash; 37 | } 38 | 39 | function bcrypt_is_legacy_hash($hash) { return substr($hash, 0, 4) != '$2a$'; } 40 | 41 | // other 42 | 43 | function br2nl($text) { 44 | return preg_replace('//i', '', $text); 45 | } 46 | 47 | function set_cookie_fix_domain($Name, $Value = '', $Expires = 0, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false) { 48 | if (!empty($Domain)) { 49 | // Fix the domain to accept domains with and without 'www.'. 50 | if (strtolower(substr($Domain, 0, 4)) == 'www.') $Domain = substr($Domain, 4); 51 | $Domain = '.' . $Domain; 52 | 53 | // Remove port information. 54 | $Port = strpos($Domain, ':'); 55 | if ($Port !== false) $Domain = substr($Domain, 0, $Port); 56 | } 57 | 58 | header('Set-Cookie: ' . rawurlencode($Name) . '=' . rawurlencode($Value) 59 | . (empty($Expires) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $Expires) . ' GMT') 60 | . (empty($Path) ? '' : '; path=' . $Path) 61 | . (empty($Domain) ? '' : '; domain=' . $Domain) 62 | . (!$Secure ? '' : '; secure') 63 | . (!$HTTPOnly ? '' : '; HttpOnly'), false); 64 | } 65 | 66 | function preg_replace_all($pattern,$replace,$text) { 67 | while(preg_match($pattern,$text)) 68 | $text = preg_replace($pattern,$replace,$text); 69 | return $text; 70 | } 71 | 72 | function getURL($uri = false) { 73 | $pageURL = 'http'; 74 | if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") $pageURL .= "s"; 75 | $pageURL .= "://"; 76 | if ($_SERVER["SERVER_PORT"] != "80") { 77 | $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"]; 78 | if($uri) $pageURL .= $_SERVER["REQUEST_URI"]; 79 | } else { 80 | $pageURL .= $_SERVER["SERVER_NAME"]; 81 | if($uri) $pageURL .= $_SERVER["REQUEST_URI"]; 82 | } 83 | return $pageURL; 84 | } 85 | 86 | function redirectToHTTPS($on = true) { 87 | if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']!=="on" && $on) { 88 | $redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; 89 | } else if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=="on" && !$on) { 90 | $redirect= "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; 91 | } else { 92 | return; 93 | } 94 | header("Location:$redirect"); 95 | } 96 | 97 | function url_exists($url) { 98 | // Version 4.x supported 99 | $handle = curl_init($url); 100 | if (false === $handle) { 101 | return false; 102 | } 103 | curl_setopt($handle, CURLOPT_HEADER, false); 104 | curl_setopt($handle, CURLOPT_FAILONERROR, true); // this works 105 | curl_setopt($handle, CURLOPT_HTTPHEADER, Array("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.15) Gecko/20080623 Firefox/2.0.0.15") ); // request as if Firefox 106 | curl_setopt($handle, CURLOPT_NOBODY, true); 107 | curl_setopt($handle, CURLOPT_RETURNTRANSFER, false); 108 | $connectable = curl_exec($handle); 109 | curl_close($handle); 110 | return $connectable; 111 | } 112 | 113 | function echoFile($folder, $file) 114 | { 115 | //header("Content-Type: " . mime_content_type($FileName)); 116 | // if you are not allowed to use mime_content_type, then hardcode MIME type 117 | // use application/octet-stream for any binary file 118 | // use application/x-executable-file for executables 119 | // use application/x-zip-compressed for zip files 120 | header("Content-Type: application/octet-stream"); 121 | header("Content-Length: " . filesize($folder.$file)); 122 | header("Content-Disposition: attachment; filename=\"$file\""); 123 | header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 124 | $fp = fopen($folder.$file,"rb"); 125 | fpassthru($fp); 126 | fclose($fp); 127 | } 128 | 129 | 130 | /******************************** 131 | * Retro-support of get_called_class() 132 | * Tested and works in PHP 5.2.4 133 | * http://www.sol1.com.au/ 134 | ********************************/ 135 | if (!function_exists('get_called_class')) { 136 | function get_called_class($bt = false, $l = 1) 137 | { 138 | if (!$bt) $bt = debug_backtrace(); 139 | if (!isset($bt[$l])) throw new Exception("Cannot find called class -> stack level too deep."); 140 | if (!isset($bt[$l]['type'])) { 141 | throw new Exception ('type not set'); 142 | } 143 | else switch ($bt[$l]['type']) { 144 | case '::': 145 | $lines = file($bt[$l]['file']); 146 | $i = 0; 147 | $callerLine = ''; 148 | do { 149 | $i++; 150 | $callerLine = $lines[$bt[$l]['line']-$i] . $callerLine; 151 | } while (stripos($callerLine,$bt[$l]['function']) === false); 152 | preg_match('/([a-zA-Z0-9\_]+)::'.$bt[$l]['function'].'/', 153 | $callerLine, 154 | $matches); 155 | if (!isset($matches[1])) { 156 | // must be an edge case. 157 | throw new Exception ("Could not find caller class: originating method call is obscured."); 158 | } 159 | switch ($matches[1]) { 160 | case 'self': 161 | case 'parent': 162 | return get_called_class($bt,$l+1); 163 | default: 164 | return $matches[1]; 165 | } 166 | // won't get here. 167 | case '->': switch ($bt[$l]['function']) { 168 | case '__get': 169 | // edge case -> get class of calling object 170 | if (!is_object($bt[$l]['object'])) throw new Exception ("Edge case fail. __get called on non object."); 171 | return get_class($bt[$l]['object']); 172 | default: return $bt[$l]['class']; 173 | } 174 | 175 | default: throw new Exception ("Unknown backtrace method type"); 176 | } 177 | } 178 | } 179 | 180 | 181 | /** 182 | * Convert an xml file or string to an associative array (including the tag attributes): 183 | * $domObj = new xmlToArrayParser($xml); 184 | * $elemVal = $domObj->array['element'] 185 | * Or: $domArr=$domObj->array; $elemVal = $domArr['element']. 186 | * 187 | * @version 2.0 188 | * @param Str $xml file/string. 189 | */ 190 | class xmlToArrayParser { 191 | /** The array created by the parser can be assigned to any variable: $anyVarArr = $domObj->array.*/ 192 | public $array = array(); 193 | public $parse_error = false; 194 | private $parser; 195 | private $pointer; 196 | 197 | /** Constructor: $domObj = new xmlToArrayParser($xml); */ 198 | public function __construct($xml) { 199 | $this->pointer =& $this->array; 200 | $this->parser = xml_parser_create("UTF-8"); 201 | xml_set_object($this->parser, $this); 202 | xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); 203 | xml_set_element_handler($this->parser, "tag_open", "tag_close"); 204 | xml_set_character_data_handler($this->parser, "cdata"); 205 | $this->parse_error = xml_parse($this->parser, ltrim($xml))? false : true; 206 | } 207 | 208 | /** Free the parser. */ 209 | public function __destruct() { xml_parser_free($this->parser);} 210 | 211 | /** Get the xml error if an an error in the xml file occured during parsing. */ 212 | public function get_xml_error() { 213 | if($this->parse_error) { 214 | $errCode = xml_get_error_code ($this->parser); 215 | $thisError = "Error Code [". $errCode ."] \"" . xml_error_string($errCode)."\", 216 | at char ".xml_get_current_column_number($this->parser) . " 217 | on line ".xml_get_current_line_number($this->parser).""; 218 | }else $thisError = $this->parse_error; 219 | return $thisError; 220 | } 221 | 222 | private function tag_open($parser, $tag, $attributes) { 223 | $this->convert_to_array($tag, 'attrib'); 224 | $idx=$this->convert_to_array($tag, 'cdata'); 225 | if(isset($idx)) { 226 | $this->pointer[$tag][$idx] = Array('@idx' => $idx,'@parent' => &$this->pointer); 227 | $this->pointer =& $this->pointer[$tag][$idx]; 228 | }else { 229 | $this->pointer[$tag] = Array('@parent' => &$this->pointer); 230 | $this->pointer =& $this->pointer[$tag]; 231 | } 232 | if (!empty($attributes)) { $this->pointer['attrib'] = $attributes; } 233 | } 234 | 235 | /** Adds the current elements content to the current pointer[cdata] array. */ 236 | private function cdata($parser, $cdata) { $this->pointer['cdata'] = trim($cdata); } 237 | 238 | private function tag_close($parser, $tag) { 239 | $current = & $this->pointer; 240 | if(isset($this->pointer['@idx'])) {unset($current['@idx']);} 241 | 242 | $this->pointer = & $this->pointer['@parent']; 243 | unset($current['@parent']); 244 | 245 | if(isset($current['cdata']) && count($current) == 1) { $current = $current['cdata'];} 246 | else if(empty($current['cdata'])) {unset($current['cdata']);} 247 | } 248 | 249 | /** Converts a single element item into array(element[0]) if a second element of the same name is encountered. */ 250 | private function convert_to_array($tag, $item) { 251 | if(isset($this->pointer[$tag][$item])) { 252 | $content = $this->pointer[$tag]; 253 | $this->pointer[$tag] = array((0) => $content); 254 | $idx = 1; 255 | }else if (isset($this->pointer[$tag])) { 256 | $idx = count($this->pointer[$tag]); 257 | if(!isset($this->pointer[$tag][0])) { 258 | foreach ($this->pointer[$tag] as $key => $value) { 259 | unset($this->pointer[$tag][$key]); 260 | $this->pointer[$tag][0][$key] = $value; 261 | }}}else $idx = null; 262 | return $idx; 263 | } 264 | } 265 | 266 | 267 | 268 | ?> --------------------------------------------------------------------------------