diff --git a/.gitattributes b/.gitattributes index ff0ff58..2a7e9ef 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,5 +4,4 @@ .travis.yml export-ignore tests/ export-ignore CI/ export-ignore -Application/ export-ignore DCO export-ignore \ No newline at end of file diff --git a/.htaccess b/.htaccess deleted file mode 100644 index e25cb61..0000000 --- a/.htaccess +++ /dev/null @@ -1,4 +0,0 @@ -RewriteEngine On -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule (.*) index.php?path=$1 [QSA,L] diff --git a/src/Config/config.cache.php b/src/Config/config.cache.php deleted file mode 100644 index 352820f..0000000 --- a/src/Config/config.cache.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'cache_query_string' => false, - 'memcached' => array( - 'default' => array( - 'hostname' => '127.0.0.1', - 'port' => '11211', - 'weight' => '1', - ) - ), - 'redis' => array( - '' => '' - ) -); \ No newline at end of file diff --git a/src/Config/config.contact.php b/src/Config/config.contact.php deleted file mode 100644 index 39549c6..0000000 --- a/src/Config/config.contact.php +++ /dev/null @@ -1,42 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'contact_email' => '', - 'contact_name' => '', - 'contact_adress' => '', - 'contact_phone' => '', - 'contact_postal_code' => '', - 'contact_region' => '', - 'contact_country' => '', - 'contact_city' => '', -); diff --git a/src/Config/config.database.php b/src/Config/config.database.php deleted file mode 100644 index eaf3da7..0000000 --- a/src/Config/config.database.php +++ /dev/null @@ -1,63 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'active_group' => 'default', - 'query_builder' => true, - 'databases' => array( - - 'default' => array( - 'dsn' => '', - 'hostname' => '', - 'username' => '', - 'password' => '', - 'database' => '', - 'dbdriver' => '', - 'subdriver'=> '', - 'dbprefix' => '', - 'pconnect' => FALSE, - 'db_debug' => FALSE, - 'cache_on' => FALSE, - 'char_set' => 'utf8', - 'dbcollat' => 'utf8_general_ci', - 'swap_pre' => '', - 'encrypt' => FALSE, - 'compress' => FALSE, - 'stricton' => FALSE, - 'failover' => array(), - ), - - - ), -); - - diff --git a/src/Config/config.encryption.php b/src/Config/config.encryption.php deleted file mode 100644 index 56e72ef..0000000 --- a/src/Config/config.encryption.php +++ /dev/null @@ -1,35 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - 'encryption_key' => '', -); diff --git a/src/Config/config.error.php b/src/Config/config.error.php index 3b0bd5f..518cbb0 100644 --- a/src/Config/config.error.php +++ b/src/Config/config.error.php @@ -31,7 +31,9 @@ */ return array( - 'error_reporting' => true, + 'fuzeworks_error_reporting' => true, + 'tracy_error_reporting' => true, + 'php_error_reporting' => false, 'log_to_file' => false, 'logger_template' => 'logger_default', ); \ No newline at end of file diff --git a/src/Config/config.main.php b/src/Config/config.main.php index 6799127..8298c19 100644 --- a/src/Config/config.main.php +++ b/src/Config/config.main.php @@ -42,7 +42,6 @@ return array( 'application_prefix' => 'MY_', 'charset' => 'UTF-8', - 'language' => 'english', /* |-------------------------------------------------------------------------- diff --git a/src/Config/config.mimes.php b/src/Config/config.mimes.php deleted file mode 100644 index f83d854..0000000 --- a/src/Config/config.mimes.php +++ /dev/null @@ -1,196 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -/* -| ------------------------------------------------------------------- -| MIME TYPES -| ------------------------------------------------------------------- -| This file contains an array of mime types. It is used by the -| Upload class to help identify allowed file types. -| -*/ -return array( - 'hqx' => array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'), - 'cpt' => 'application/mac-compactpro', - 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'), - 'bin' => array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'), - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => array('application/octet-stream', 'application/x-msdownload'), - 'class' => 'application/octet-stream', - 'psd' => array('application/x-photoshop', 'image/vnd.adobe.photoshop'), - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'), - 'ai' => array('application/pdf', 'application/postscript'), - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'), - 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'), - 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'), - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'gzip' => 'application/x-gzip', - 'php' => array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'), - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => array('application/x-javascript', 'text/plain'), - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), - 'z' => 'application/x-compress', - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'), - 'rar' => array('application/x-rar', 'application/rar', 'application/x-rar-compressed'), - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), - 'aif' => array('audio/x-aiff', 'audio/aiff'), - 'aiff' => array('audio/x-aiff', 'audio/aiff'), - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), - 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'), - 'gif' => 'image/gif', - 'jpeg' => array('image/jpeg', 'image/pjpeg'), - 'jpg' => array('image/jpeg', 'image/pjpeg'), - 'jpe' => array('image/jpeg', 'image/pjpeg'), - 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'png' => array('image/png', 'image/x-png'), - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'css' => array('text/css', 'text/plain'), - 'html' => array('text/html', 'text/plain'), - 'htm' => array('text/html', 'text/plain'), - 'shtml' => array('text/html', 'text/plain'), - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => array('text/plain', 'text/x-log'), - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => array('application/xml', 'text/xml', 'text/plain'), - 'xsl' => array('application/xml', 'text/xsl', 'text/xml'), - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'), - 'movie' => 'video/x-sgi-movie', - 'doc' => array('application/msword', 'application/vnd.ms-office'), - 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'), - 'dot' => array('application/msword', 'application/vnd.ms-office'), - 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'), - 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'), - 'word' => array('application/msword', 'application/octet-stream'), - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - 'json' => array('application/json', 'text/json'), - 'pem' => array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'), - 'p10' => array('application/x-pkcs10', 'application/pkcs10'), - 'p12' => 'application/x-pkcs12', - 'p7a' => 'application/x-pkcs7-signature', - 'p7c' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), - 'p7m' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'crt' => array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'), - 'crl' => array('application/pkix-crl', 'application/pkcs-crl'), - 'der' => 'application/x-x509-ca-cert', - 'kdb' => 'application/octet-stream', - 'pgp' => 'application/pgp', - 'gpg' => 'application/gpg-keys', - 'sst' => 'application/octet-stream', - 'csr' => 'application/octet-stream', - 'rsa' => 'application/x-pkcs7', - 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'), - '3g2' => 'video/3gpp2', - '3gp' => array('video/3gp', 'video/3gpp'), - 'mp4' => 'video/mp4', - 'm4a' => 'audio/x-m4a', - 'f4v' => array('video/mp4', 'video/x-f4v'), - 'flv' => 'video/x-flv', - 'webm' => 'video/webm', - 'aac' => 'audio/x-acc', - 'm4u' => 'application/vnd.mpegurl', - 'm3u' => 'text/plain', - 'xspf' => 'application/xspf+xml', - 'vlc' => 'application/videolan', - 'wmv' => array('video/x-ms-wmv', 'video/x-ms-asf'), - 'au' => 'audio/x-au', - 'ac3' => 'audio/ac3', - 'flac' => 'audio/x-flac', - 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'), - 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'), - 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'), - 'ics' => 'text/calendar', - 'ical' => 'text/calendar', - 'zsh' => 'text/x-scriptzsh', - '7zip' => array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), - 'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'), - 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), - 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), - 'svg' => array('image/svg+xml', 'application/xml', 'text/xml'), - 'vcf' => 'text/x-vcard', - 'srt' => array('text/srt', 'text/plain'), - 'vtt' => array('text/vtt', 'text/plain'), - 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon') -); diff --git a/src/Config/config.routes.php b/src/Config/config.routes.php deleted file mode 100644 index f736b58..0000000 --- a/src/Config/config.routes.php +++ /dev/null @@ -1,50 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.4 - */ - -/** - * Possible values: - * Default callable: Adds a route that changes the URL structure. Sends all matches to the defaultCallable router - * 'routingString' - * - * Custom callable: Adds a route that sends all matches to the provided callable. Allows user to replace defaultCallable - * 'routingString' => array('callable' => array(CALLABLE)) - * - * Dynamic rewrite: Adds a route that rewrites an URL to a specific controller and method configuration, using a callable. The callable can dynamically determine which page to load. - * 'routingString' => CALLABLE - * - * Static rewrite: Adds a route that rewrites and URL to a specific controller and method using a fixed route. This allows for pre-determined rewrites of pages. - * 'routingString' => 'standard/index' - * - * Example routingString: '/^(?P.*?)(|\/(?P.*?)(|\/(?P.*?)))$/' - */ -return array( -); diff --git a/src/Config/config.routing.php b/src/Config/config.routing.php deleted file mode 100644 index df14674..0000000 --- a/src/Config/config.routing.php +++ /dev/null @@ -1,131 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - - /* - |-------------------------------------------------------------------------- - | Enable Query Strings - |-------------------------------------------------------------------------- - | - | By default CodeIgniter uses search-engine friendly segment based URLs: - | example.com/who/what/where/ - | - | By default CodeIgniter enables access to the $_GET array. If for some - | reason you would like to disable it, set 'allow_get_array' to FALSE. - | - | You can optionally enable standard query string based URLs: - | example.com?who=me&what=something&where=here - | - | Options are: TRUE or FALSE (boolean) - | - | The other items let you set the query string 'words' that will - | invoke your controllers and its functions: - | example.com/index.php?c=controller&m=function - | - | Please note that some of the helpers won't work as expected when - | this feature is enabled, since CodeIgniter is designed primarily to - | use segment based URLs. - | - */ - 'allow_get_array' => TRUE, - 'enable_query_strings' => FALSE, - 'controller_trigger' => 'c', - 'function_trigger' => 'm', - 'directory_trigger' => 'd', - - - /* - |-------------------------------------------------------------------------- - | Allowed URL Characters - |-------------------------------------------------------------------------- - | - | This lets you specify which characters are permitted within your URLs. - | When someone tries to submit a URL with disallowed characters they will - | get a warning message. - | - | As a security measure you are STRONGLY encouraged to restrict URLs to - | as few characters as possible. By default only these are allowed: a-z 0-9~%.:_- - | - | Leave blank to allow all characters -- but only if you are insane. - | - | The configured value is actually a regular expression character group - | and it will be executed as: ! preg_match('/^[]+$/i - | - | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! - | - */ - 'permitted_uri_chars' => 'a-z 0-9~%.:_\-', - - /* - |-------------------------------------------------------------------------- - | Translate URI Dashes - |-------------------------------------------------------------------------- - | Determines whether dashes in controller & method segments - | should be automatically replaced by underscores. - | - */ - 'translate_uri_dashes' => FALSE, - - /* - |-------------------------------------------------------------------------- - | URI PROTOCOL - |-------------------------------------------------------------------------- - | - | This item determines which server global should be used to retrieve the - | URI string. The default setting of 'REQUEST_URI' works for most servers. - | If your links do not seem to work, try one of the other delicious flavors: - | - | 'REQUEST_URI' Uses $_SERVER['REQUEST_URI'] - | 'QUERY_STRING' Uses $_SERVER['QUERY_STRING'] - | 'PATH_INFO' Uses $_SERVER['PATH_INFO'] - | - | WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! - */ - 'uri_protocol' => 'REQUEST_URI', - - /* - |-------------------------------------------------------------------------- - | URL suffix - |-------------------------------------------------------------------------- - | - | This option allows you to add a suffix to all URLs generated by CodeIgniter. - | For more information please see the user guide: - | - | https://codeigniter.com/user_guide/general/urls.html - */ - 'url_suffix' => '', - - 'default_controller' => 'standard', - 'default_function' => 'index', - -); diff --git a/src/Config/config.security.php b/src/Config/config.security.php deleted file mode 100644 index d35bfd1..0000000 --- a/src/Config/config.security.php +++ /dev/null @@ -1,102 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.1 - * - * @version Version 1.1.1 - */ - -return array( - - /* - |-------------------------------------------------------------------------- - | Cross Site Request Forgery - |-------------------------------------------------------------------------- - | Enables a CSRF cookie token to be set. When set to TRUE, token will be - | checked on a submitted form. If you are accepting user data, it is strongly - | recommended CSRF protection be enabled. - | - | 'csrf_token_name' = The token name - | 'csrf_cookie_name' = The cookie name - | 'csrf_expire' = The number in seconds the token should expire. - | 'csrf_regenerate' = Regenerate token on every submission - | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks - */ - 'csrf_protection' => true, - 'csrf_token_name' => 'fw_csrf_token', - 'csrf_cookie_name' => 'fw_csrf_cookie', - 'csrf_expire' => 7200, - 'csrf_regenerate' => TRUE, - 'csrf_exclude_uris' => array(), - - /* - |-------------------------------------------------------------------------- - | Standardize newlines - |-------------------------------------------------------------------------- - | - | Determines whether to standardize newline characters in input data, - | meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value. - | - | This is particularly useful for portability between UNIX-based OSes, - | (usually \n) and Windows (\r\n). - | - */ - 'standardize_newlines' => FALSE, - - /* - |-------------------------------------------------------------------------- - | Global XSS Filtering - |-------------------------------------------------------------------------- - | - | Determines whether the XSS filter is always active when GET, POST or - | COOKIE data is encountered - | - | WARNING: This feature is DEPRECATED and currently available only - | for backwards compatibility purposes! - | - */ - 'global_xss_filtering' => FALSE, - - /* - |-------------------------------------------------------------------------- - | Reverse Proxy IPs - |-------------------------------------------------------------------------- - | - | If your server is behind a reverse proxy, you must whitelist the proxy - | IP addresses from which CodeIgniter should trust headers such as - | HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify - | the visitor's IP address. - | - | You can use both an array or a comma-separated list of proxy addresses, - | as well as specifying whole subnets. Here are a few examples: - | - | Comma-separated: '10.0.1.200,192.168.5.0/24' - | Array: array('10.0.1.200', '192.168.5.0/24') - */ - 'proxy_ips' => '' - -); diff --git a/src/Database/DB.php b/src/Database/DB.php deleted file mode 100644 index 1be8fbb..0000000 --- a/src/Database/DB.php +++ /dev/null @@ -1,201 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; -use FuzeWorks\Database; -use FuzeWorks\Exception\DatabaseException; -use FuzeWorks\Core; - -/** - * Initialize the database - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - * - * @param string|string[] $params - * @param bool $query_builder_override - * Determines if query builder should be used or not - */ -function &DB($params = '', $query_builder_override = NULL) -{ - // Load the DB config file if a DSN string wasn't passed - if (is_string($params) && strpos($params, '://') === FALSE) - { - // First retrieve the config file - try { - $config = Factory::getInstance()->config->get('database'); - } catch (ConfigException $e) { - throw new DatabaseException($e->getMessage(), 1); - } - - // Determine if there are actually settings in the config file - if ( ! isset($config->databases) OR count($config->databases) === 0) - { - throw new DatabaseException('No database connection settings were found in the database config file.', 1); - } - - // Define the active group - $active_group = ($params !== '' ? $params : $config->active_group); - - if ( ! isset($active_group)) - { - throw new DatabaseException('You have not specified a database connection group via $active_group in your config.database.php file.', 1); - } - elseif ( ! isset($config->databases[$active_group])) - { - throw new DatabaseException('You have specified an invalid database connection group ('.$active_group.') in your config.database.php file.', 1); - } - - $params = $config->databases[$active_group]; - } - elseif (is_string($params)) - { - /** - * Parse the URL from the DSN string - * Database settings can be passed as discreet - * parameters or as a data source name in the first - * parameter. DSNs must have this prototype: - * $dsn = 'driver://username:password@hostname/database'; - */ - if (($dsn = @parse_url($params)) === FALSE) - { - throw new DatabaseException('Invalid DB Connection String', 1); - } - - $params = array( - 'dbdriver' => $dsn['scheme'], - 'hostname' => isset($dsn['host']) ? rawurldecode($dsn['host']) : '', - 'port' => isset($dsn['port']) ? rawurldecode($dsn['port']) : '', - 'username' => isset($dsn['user']) ? rawurldecode($dsn['user']) : '', - 'password' => isset($dsn['pass']) ? rawurldecode($dsn['pass']) : '', - 'database' => isset($dsn['path']) ? rawurldecode(substr($dsn['path'], 1)) : '' - ); - - // Were additional config items set? - if (isset($dsn['query'])) - { - parse_str($dsn['query'], $extra); - - foreach ($extra as $key => $val) - { - if (is_string($val) && in_array(strtoupper($val), array('TRUE', 'FALSE', 'NULL'))) - { - $val = var_export($val, TRUE); - } - - $params[$key] = $val; - } - } - } - - // No DB specified yet? Beat them senseless... - if (empty($params['dbdriver'])) - { - throw new DatabaseException('You have not selected a database type to connect to.', 1); - } - - // Load the DB classes. Note: Since the query builder class is optional - // we need to dynamically create a class that extends proper parent class - // based on whether we're using the query builder class or not. - if ($query_builder_override !== NULL) - { - $query_builder = $query_builder_override; - } - // Backwards compatibility work-around for keeping the - // $active_record config variable working. Should be - // removed in v3.1 - elseif ( ! isset($query_builder) && isset($active_record)) - { - $query_builder = $active_record; - } - - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_driver.php'); - - if ( ! isset($query_builder) OR $query_builder === TRUE) - { - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_query_builder.php'); - if ( ! class_exists('FW_DB', FALSE)) - { - /** - * FW_DB - * - * Acts as an alias for both FW_DB_driver and FW_DB_query_builder. - * - * @see FW_DB_query_builder - * @see FW_DB_driver - */ - class FW_DB extends FW_DB_query_builder { } - } - } - elseif ( ! class_exists('FW_DB', FALSE)) - { - /** - * @ignore - */ - class FW_DB extends FW_DB_driver { } - } - - // Load the DB driver - $driver_file = Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$params['dbdriver'].DS.$params['dbdriver'].'_driver.php'; - - if (!file_exists($driver_file)) - { - throw new DatabaseException("Invalid DB Driver", 1); - } - - require_once($driver_file); - - // Instantiate the DB adapter - $driver = 'FW_DB_'.$params['dbdriver'].'_driver'; - $DB = new $driver($params); - - // Check for a subdriver - if ( ! empty($DB->subdriver)) - { - $driver_file = Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$DB->dbdriver.DS.'subdrivers'.DS.$DB->dbdriver.'_'.$DB->subdriver.'_driver.php'; - - if (file_exists($driver_file)) - { - require_once($driver_file); - $driver = 'FW_DB_'.$DB->dbdriver.'_'.$DB->subdriver.'_driver'; - $DB = new $driver($params); - } - } - - $DB->initialize(); - return $DB; -} diff --git a/src/Database/DB_cache.php b/src/Database/DB_cache.php deleted file mode 100644 index 8e5daa4..0000000 --- a/src/Database/DB_cache.php +++ /dev/null @@ -1,216 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use Fuzeworks\Factory; -use FuzeWorks\Core; - -/** - * Database Cache Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_Cache { - - /** - * Database object - * - * Allows passing of DB object so that multiple database connections - * and returned DB objects can be supported. - * - * @var object - */ - public $db; - - /** - * The FuzeWorks factory class - * - * @var Fuzeworks\Factory; - */ - private $factory; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param object &$db - * @return void - */ - public function __construct(&$db) - { - $this->db =& $db; - $this->factory = Factory::getInstance(); - $this->factory->helpers->load('file'); - - $this->check_path(); - } - - // -------------------------------------------------------------------- - - /** - * Set Cache Directory Path - * - * @param string $path Path to the cache directory - * @return bool - */ - public function check_path($path = '') - { - $path = ($path === '' ? Core::$tempDir . DS . 'Database' : $path); - - // Add a trailing slash to the path if needed - $path = realpath($path) - ? rtrim(realpath($path), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR - : rtrim($path, '/').'/'; - - if ( ! is_dir($path)) - { - if (!mkdir($path, 0777, false)) - { - Logger::logDebug('DB cache path error: '.$path); - - // If the path is wrong we'll turn off caching - return $this->db->cache_off(); - } - } - - if ( ! Core::isReallyWritable($path)) - { - Logger::logDebug('DB cache dir not writable: '.$path); - - // If the path is not really writable we'll turn off caching - return $this->db->cache_off(); - } - - $this->db->cachedir = $path; - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Retrieve a cached query - * - * The URI being requested will become the name of the cache sub-folder. - * An MD5 hash of the SQL statement will become the cache file name. - * - * @param string $sql - * @return string - */ - public function read($sql) - { - $segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1); - $segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2); - $filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql); - - if (FALSE === ($cachedata = @file_get_contents($filepath))) - { - return FALSE; - } - - return unserialize($cachedata); - } - - // -------------------------------------------------------------------- - - /** - * Write a query to a cache file - * - * @param string $sql - * @param object $object - * @return bool - */ - public function write($sql, $object) - { - $segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1); - $segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2); - $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'; - $filename = md5($sql); - - if ( ! is_dir($dir_path) && ! @mkdir($dir_path, 0750)) - { - return FALSE; - } - - if (write_file($dir_path.$filename, serialize($object)) === FALSE) - { - return FALSE; - } - - chmod($dir_path.$filename, 0640); - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Delete cache files within a particular directory - * - * @param string $segment_one - * @param string $segment_two - * @return void - */ - public function delete($segment_one = '', $segment_two = '') - { - if ($segment_one === '') - { - $segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1); - } - - if ($segment_two === '') - { - $segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2); - } - - $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'; - delete_files($dir_path, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Delete all existing cache files - * - * @return void - */ - public function delete_all() - { - delete_files($this->db->cachedir, TRUE, TRUE); - } - -} diff --git a/src/Database/DB_driver.php b/src/Database/DB_driver.php deleted file mode 100644 index daee2c0..0000000 --- a/src/Database/DB_driver.php +++ /dev/null @@ -1,1997 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Core; -use FuzeWorks\Logger; -use FuzeWorks\Utf8; -use FuzeWorks\Language; -use FuzeWorks\DatabaseTracyBridge; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Driver Class - * - * This is the platform-independent base DB implementation class. - * This class will not be called directly. Rather, the adapter - * class for the specific database will extend and instantiate it. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -abstract class FW_DB_driver { - - /** - * Data Source Name / Connect string - * - * @var string - */ - public $dsn; - - /** - * Username - * - * @var string - */ - public $username; - - /** - * Password - * - * @var string - */ - public $password; - - /** - * Hostname - * - * @var string - */ - public $hostname; - - /** - * Database name - * - * @var string - */ - public $database; - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'mysqli'; - - /** - * Sub-driver - * - * @used-by FW_DB_pdo_driver - * @var string - */ - public $subdriver; - - /** - * Table prefix - * - * @var string - */ - public $dbprefix = ''; - - /** - * Character set - * - * @var string - */ - public $char_set = 'utf8'; - - /** - * Collation - * - * @var string - */ - public $dbcollat = 'utf8_general_ci'; - - /** - * Encryption flag/data - * - * @var mixed - */ - public $encrypt = FALSE; - - /** - * Swap Prefix - * - * @var string - */ - public $swap_pre = ''; - - /** - * Database port - * - * @var int - */ - public $port = ''; - - /** - * Persistent connection flag - * - * @var bool - */ - public $pconnect = FALSE; - - /** - * Connection ID - * - * @var object|resource - */ - public $conn_id = FALSE; - - /** - * Result ID - * - * @var object|resource - */ - public $result_id = FALSE; - - /** - * Debug flag - * - * Whether to display error messages. - * - * @var bool - */ - public $db_debug = TRUE; - - /** - * Benchmark time - * - * @var int - */ - public $benchmark = 0; - - /** - * Executed queries count - * - * @var int - */ - public $query_count = 0; - - /** - * Bind marker - * - * Character used to identify values in a prepared statement. - * - * @var string - */ - public $bind_marker = '?'; - - /** - * Save queries flag - * - * Whether to keep an in-memory history of queries for debugging purposes. - * - * @var bool - */ - public $save_queries = TRUE; - - /** - * Queries list - * - * @see FW_DB_driver::$save_queries - * @var string[] - */ - public $queries = array(); - - /** - * Data of performed queries - * - * @see FW_DB_driver::$save_queries - * @var array - */ - public $query_data = array(); - - /** - * Query times - * - * A list of times that queries took to execute. - * - * @var array - */ - public $query_times = array(); - - /** - * Data cache - * - * An internal generic value cache. - * - * @var array - */ - public $data_cache = array(); - - /** - * Transaction enabled flag - * - * @var bool - */ - public $trans_enabled = TRUE; - - /** - * Strict transaction mode flag - * - * @var bool - */ - public $trans_strict = TRUE; - - /** - * Transaction depth level - * - * @var int - */ - protected $_trans_depth = 0; - - /** - * Transaction status flag - * - * Used with transactions to determine if a rollback should occur. - * - * @var bool - */ - protected $_trans_status = TRUE; - - /** - * Transaction failure flag - * - * Used with transactions to determine if a transaction has failed. - * - * @var bool - */ - protected $_trans_failure = FALSE; - - /** - * Cache On flag - * - * @var bool - */ - public $cache_on = FALSE; - - /** - * Cache directory path - * - * @var bool - */ - public $cachedir = ''; - - /** - * Cache auto-delete flag - * - * @var bool - */ - public $cache_autodel = FALSE; - - /** - * DB Cache object - * - * @see FW_DB_cache - * @var object - */ - public $CACHE; - - /** - * Protect identifiers flag - * - * @var bool - */ - protected $_protect_identifiers = TRUE; - - /** - * List of reserved identifiers - * - * Identifiers that must NOT be escaped. - * - * @var string[] - */ - protected $_reserved_identifiers = array('*'); - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '"'; - - /** - * ESCAPE statement string - * - * @var string - */ - protected $_like_escape_str = " ESCAPE '%s' "; - - /** - * ESCAPE character - * - * @var string - */ - protected $_like_escape_chr = '!'; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RAND()', 'RAND(%d)'); - - /** - * COUNT string - * - * @used-by FW_DB_driver::count_all() - * @used-by FW_DB_query_builder::count_all_results() - * - * @var string - */ - protected $_count_string = 'SELECT COUNT(*) AS '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - if (is_array($params)) - { - foreach ($params as $key => $val) - { - $this->$key = $val; - } - } - - Logger::log('Database Driver ' . get_class($this) . ' Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Initialize Database Settings - * - * @return bool - */ - public function initialize() - { - /* If an established connection is available, then there's - * no need to connect and select the database. - * - * Depending on the database driver, conn_id can be either - * boolean TRUE, a resource or an object. - */ - if ($this->conn_id) - { - return TRUE; - } - - // ---------------------------------------------------------------- - - // Connect to the database and set the connection ID - $this->conn_id = $this->db_connect($this->pconnect); - - // No connection resource? Check if there is a failover else throw an error - if ( ! $this->conn_id) - { - // Check if there is a failover set - if ( ! empty($this->failover) && is_array($this->failover)) - { - // Go over all the failovers - foreach ($this->failover as $failover) - { - // Replace the current settings with those of the failover - foreach ($failover as $key => $val) - { - $this->$key = $val; - } - - // Try to connect - $this->conn_id = $this->db_connect($this->pconnect); - - // If a connection is made break the foreach loop - if ($this->conn_id) - { - break; - } - } - } - - // We still don't have a connection? - if ( ! $this->conn_id) - { - Logger::logError('Unable to connect to the database'); - - if ($this->db_debug) - { - $this->display_error('db_unable_to_connect'); - } - - return FALSE; - } - } - - // Now we set the character set and that's all - return $this->db_set_charset($this->char_set); - } - - // -------------------------------------------------------------------- - - /** - * DB connect - * - * This is just a dummy method that all drivers will override. - * - * @return mixed - */ - public function db_connect() - { - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Persistent database connection - * - * @return mixed - */ - public function db_pconnect() - { - return $this->db_connect(TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout. - * - * This is just a dummy method to allow drivers without such - * functionality to not declare it, while others will override it. - * - * @return void - */ - public function reconnect() - { - } - - // -------------------------------------------------------------------- - - /** - * Select database - * - * This is just a dummy method to allow drivers without such - * functionality to not declare it, while others will override it. - * - * @return bool - */ - public function db_select() - { - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Last error - * - * @return array - */ - public function error() - { - return array('code' => NULL, 'message' => NULL); - } - - // -------------------------------------------------------------------- - - /** - * Set client character set - * - * @param string - * @return bool - */ - public function db_set_charset($charset) - { - if (method_exists($this, '_db_set_charset') && ! $this->_db_set_charset($charset)) - { - Logger::logError('Unable to set database connection charset: '.$charset); - - if ($this->db_debug) - { - $this->display_error('db_unable_to_set_charset', $charset); - } - - return FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * The name of the platform in use (mysql, mssql, etc...) - * - * @return string - */ - public function platform() - { - return $this->dbdriver; - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * Returns a string containing the version of the database being used. - * Most drivers will override this method. - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if (FALSE === ($sql = $this->_version())) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - $query = $this->query($sql)->row(); - return $this->data_cache['version'] = $query->ver; - } - - // -------------------------------------------------------------------- - - /** - * Version number query string - * - * @return string - */ - protected function _version() - { - return 'SELECT VERSION() AS ver'; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * Accepts an SQL string as input and returns a result object upon - * successful execution of a "read" type query. Returns boolean TRUE - * upon successful execution of a "write" type query. Returns boolean - * FALSE upon failure, and if the $db_debug variable is set to TRUE - * will raise an error. - * - * @param string $sql - * @param array $binds = FALSE An array of binding data - * @param bool $return_object = NULL - * @return mixed - */ - public function query($sql, $binds = FALSE, $return_object = NULL) - { - if ($sql === '') - { - return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; - } - elseif ( ! is_bool($return_object)) - { - $return_object = ! $this->is_write_type($sql); - } - - // Verify table prefix and replace if necessary - if ($this->dbprefix !== '' && $this->swap_pre !== '' && $this->dbprefix !== $this->swap_pre) - { - $sql = preg_replace('/(\W)'.$this->swap_pre.'(\S+?)/', '\\1'.$this->dbprefix.'\\2', $sql); - } - - // Compile binds if needed - if ($binds !== FALSE) - { - $sql = $this->compile_binds($sql, $binds); - } - - // Is query caching enabled? If the query is a "read type" - // we will load the caching class and return the previously - // cached query if it exists - if ($this->cache_on === TRUE && $return_object === TRUE && $this->_cache_init()) - { - $this->load_rdriver(); - if (FALSE !== ($cache = $this->CACHE->read($sql))) - { - return $cache; - } - } - - // Save the query for debugging - if ($this->save_queries === TRUE) - { - $this->queries[] = $sql; - } - - // Start the Query Timer - $time_start = microtime(TRUE); - - // Run the Query - if (FALSE === ($this->result_id = $this->simple_query($sql))) - { - if ($this->save_queries === TRUE) - { - $this->query_times[] = 0; - $this->query_data[] = array('error' => $this->error(), 'rows' => 0); - } - - // This will trigger a rollback if transactions are being used - if ($this->_trans_depth !== 0) - { - $this->_trans_status = FALSE; - } - - // Grab the error now, as we might run some additional queries before displaying the error - $error = $this->error(); - - if ($this->db_debug) - { - // We call this function in order to roll-back queries - // if transactions are enabled. If we don't call this here - // the error message will trigger an exit, causing the - // transactions to remain in limbo. - while ($this->_trans_depth !== 0) - { - $trans_depth = $this->_trans_depth; - $this->trans_complete(); - if ($trans_depth === $this->_trans_depth) - { - Logger::logError('Database: Failure during an automated transaction commit/rollback!'); - break; - } - } - - // Display errors - return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql)); - } - - return FALSE; - } - - // Stop and aggregate the query time results - $time_end = microtime(TRUE); - $this->benchmark += $time_end - $time_start; - - // Increment the query counter - $this->query_count++; - - // Will we have a result object instantiated? If not - we'll simply return TRUE - if ($return_object !== TRUE) - { - // If caching is enabled we'll auto-cleanup any existing files related to this particular URI - if ($this->cache_on === TRUE && $this->cache_autodel === TRUE && $this->_cache_init()) - { - $this->CACHE->delete(); - } - - return TRUE; - } - - // Load and instantiate the result driver - $driver = $this->load_rdriver(); - $RES = new $driver($this); - - if ($this->save_queries === TRUE) - { - $this->query_times[] = $time_end - $time_start; - $this->query_data[] = array('error' => $this->error(), 'rows' => $RES->num_rows()); - } - - // Is query caching enabled? If so, we'll serialize the - // result object and save it to a cache file. - if ($this->cache_on === TRUE && $this->_cache_init()) - { - // We'll create a new instance of the result object - // only without the platform specific driver since - // we can't use it with cached data (the query result - // resource ID won't be any good once we've cached the - // result object, so we'll have to compile the data - // and save it) - $CR = new FW_DB_result($this); - $CR->result_object = $RES->result_object(); - $CR->result_array = $RES->result_array(); - $CR->num_rows = $RES->num_rows(); - - // Reset these since cached objects can not utilize resource IDs. - $CR->conn_id = NULL; - $CR->result_id = NULL; - - $this->CACHE->write($sql, $CR); - } - - return $RES; - } - - // -------------------------------------------------------------------- - - /** - * Load the result drivers - * - * @return string the name of the result class - */ - public function load_rdriver() - { - $driver = 'FW_DB_'.$this->dbdriver.'_result'; - - if ( ! class_exists($driver, FALSE)) - { - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_result.php'); - require_once(Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$this->dbdriver.DS.$this->dbdriver.'_result.php'); - } - - return $driver; - } - - // -------------------------------------------------------------------- - - /** - * Simple Query - * This is a simplified version of the query() function. Internally - * we only use it when running transaction commands since they do - * not require all the features of the main query() function. - * - * @param string the sql query - * @return mixed - */ - public function simple_query($sql) - { - if ( ! $this->conn_id) - { - if ( ! $this->initialize()) - { - return FALSE; - } - } - - return $this->_execute($sql); - } - - // -------------------------------------------------------------------- - - /** - * Disable Transactions - * This permits transactions to be disabled at run-time. - * - * @return void - */ - public function trans_off() - { - $this->trans_enabled = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Enable/disable Transaction Strict Mode - * - * When strict mode is enabled, if you are running multiple groups of - * transactions, if one group fails all subsequent groups will be - * rolled back. - * - * If strict mode is disabled, each group is treated autonomously, - * meaning a failure of one group will not affect any others - * - * @param bool $mode = TRUE - * @return void - */ - public function trans_strict($mode = TRUE) - { - $this->trans_strict = is_bool($mode) ? $mode : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Start Transaction - * - * @param bool $test_mode = FALSE - * @return bool - */ - public function trans_start($test_mode = FALSE) - { - if ( ! $this->trans_enabled) - { - return FALSE; - } - - return $this->trans_begin($test_mode); - } - - // -------------------------------------------------------------------- - - /** - * Complete Transaction - * - * @return bool - */ - public function trans_complete() - { - if ( ! $this->trans_enabled) - { - return FALSE; - } - - // The query() function will set this flag to FALSE in the event that a query failed - if ($this->_trans_status === FALSE OR $this->_trans_failure === TRUE) - { - $this->trans_rollback(); - - // If we are NOT running in strict mode, we will reset - // the _trans_status flag so that subsequent groups of - // transactions will be permitted. - if ($this->trans_strict === FALSE) - { - $this->_trans_status = TRUE; - } - - Logger::logDebug('DB Transaction Failure'); - return FALSE; - } - - return $this->trans_commit(); - } - - // -------------------------------------------------------------------- - - /** - * Lets you retrieve the transaction flag to determine if it has failed - * - * @return bool - */ - public function trans_status() - { - return $this->_trans_status; - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @param bool $test_mode - * @return bool - */ - public function trans_begin($test_mode = FALSE) - { - if ( ! $this->trans_enabled) - { - return FALSE; - } - // When transactions are nested we only begin/commit/rollback the outermost ones - elseif ($this->_trans_depth > 0) - { - $this->_trans_depth++; - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - - if ($this->_trans_begin()) - { - $this->_trans_depth++; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - public function trans_commit() - { - if ( ! $this->trans_enabled OR $this->_trans_depth === 0) - { - return FALSE; - } - // When transactions are nested we only begin/commit/rollback the outermost ones - elseif ($this->_trans_depth > 1 OR $this->_trans_commit()) - { - $this->_trans_depth--; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - public function trans_rollback() - { - if ( ! $this->trans_enabled OR $this->_trans_depth === 0) - { - return FALSE; - } - // When transactions are nested we only begin/commit/rollback the outermost ones - elseif ($this->_trans_depth > 1 OR $this->_trans_rollback()) - { - $this->_trans_depth--; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Compile Bindings - * - * @param string the sql statement - * @param array an array of bind data - * @return string - */ - public function compile_binds($sql, $binds) - { - if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) - { - return $sql; - } - elseif ( ! is_array($binds)) - { - $binds = array($binds); - $bind_count = 1; - } - else - { - // Make sure we're using numeric keys - $binds = array_values($binds); - $bind_count = count($binds); - } - - // We'll need the marker length later - $ml = strlen($this->bind_marker); - - // Make sure not to replace a chunk inside a string that happens to match the bind marker - if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) - { - $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', - str_replace($matches[0], - str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]), - $sql, $c), - $matches, PREG_OFFSET_CAPTURE); - - // Bind values' count must match the count of markers in the query - if ($bind_count !== $c) - { - return $sql; - } - } - elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) - { - return $sql; - } - - do - { - $c--; - $escaped_value = $this->escape($binds[$c]); - if (is_array($escaped_value)) - { - $escaped_value = '('.implode(',', $escaped_value).')'; - } - $sql = substr_replace($sql, $escaped_value, $matches[0][$c][1], $ml); - } - while ($c !== 0); - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Calculate the aggregate query elapsed time - * - * @param int The number of decimal places - * @return string - */ - public function elapsed_time($decimals = 6) - { - return number_format($this->benchmark, $decimals); - } - - // -------------------------------------------------------------------- - - /** - * Returns the total number of queries - * - * @return int - */ - public function total_queries() - { - return $this->query_count; - } - - // -------------------------------------------------------------------- - - /** - * Returns the last query that was executed - * - * @return string - */ - public function last_query() - { - return end($this->queries); - } - - // -------------------------------------------------------------------- - - /** - * "Smart" Escape String - * - * Escapes data based on type - * Sets boolean and null types - * - * @param string - * @return mixed - */ - public function escape($str) - { - if (is_array($str)) - { - $str = array_map(array(&$this, 'escape'), $str); - return $str; - } - elseif (is_string($str) OR (is_object($str) && method_exists($str, '__toString'))) - { - return "'".$this->escape_str($str)."'"; - } - elseif (is_bool($str)) - { - return ($str === FALSE) ? 0 : 1; - } - elseif ($str === NULL) - { - return 'NULL'; - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Escape String - * - * @param string|string[] $str Input string - * @param bool $like Whether or not the string will be used in a LIKE condition - * @return string - */ - public function escape_str($str, $like = FALSE) - { - if (is_array($str)) - { - foreach ($str as $key => $val) - { - $str[$key] = $this->escape_str($val, $like); - } - - return $str; - } - - $str = $this->_escape_str($str); - - // escape LIKE condition wildcards - if ($like === TRUE) - { - return str_replace( - array($this->_like_escape_chr, '%', '_'), - array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'), - $str - ); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Escape LIKE String - * - * Calls the individual driver for platform - * specific escaping for LIKE conditions - * - * @param string|string[] - * @return mixed - */ - public function escape_like_str($str) - { - return $this->escape_str($str, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return str_replace("'", "''", Utf8::remove_invisible_characters($str)); - } - - // -------------------------------------------------------------------- - - /** - * Primary - * - * Retrieves the primary key. It assumes that the row in the first - * position is the primary key - * - * @param string $table Table name - * @return string - */ - public function primary($table) - { - $fields = $this->list_fields($table); - return is_array($fields) ? current($fields) : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * "Count All" query - * - * Generates a platform-specific query string that counts all records in - * the specified database - * - * @param string - * @return int - */ - public function count_all($table = '') - { - if ($table === '') - { - return 0; - } - - $query = $this->query($this->_count_string.$this->escape_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE)); - if ($query->num_rows() === 0) - { - return 0; - } - - $query = $query->row(); - $this->_reset_select(); - return (int) $query->numrows; - } - - // -------------------------------------------------------------------- - - /** - * Returns an array of table names - * - * @param string $constrain_by_prefix = FALSE - * @return array - */ - public function list_tables($constrain_by_prefix = FALSE) - { - // Is there a cached result? - if (isset($this->data_cache['table_names'])) - { - return $this->data_cache['table_names']; - } - - if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix))) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - $this->data_cache['table_names'] = array(); - $query = $this->query($sql); - - foreach ($query->result_array() as $row) - { - // Do we know from which column to get the table name? - if ( ! isset($key)) - { - if (isset($row['table_name'])) - { - $key = 'table_name'; - } - elseif (isset($row['TABLE_NAME'])) - { - $key = 'TABLE_NAME'; - } - else - { - /* We have no other choice but to just get the first element's key. - * Due to array_shift() accepting its argument by reference, if - * E_STRICT is on, this would trigger a warning. So we'll have to - * assign it first. - */ - $key = array_keys($row); - $key = array_shift($key); - } - } - - $this->data_cache['table_names'][] = $row[$key]; - } - - return $this->data_cache['table_names']; - } - - // -------------------------------------------------------------------- - - /** - * Determine if a particular table exists - * - * @param string $table_name - * @return bool - */ - public function table_exists($table_name) - { - return in_array($this->protect_identifiers($table_name, TRUE, FALSE, FALSE), $this->list_tables()); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * @param string $table Table name - * @return array - */ - public function list_fields($table) - { - // Is there a cached result? - if (isset($this->data_cache['field_names'][$table])) - { - return $this->data_cache['field_names'][$table]; - } - - if (FALSE === ($sql = $this->_list_columns($table))) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - $query = $this->query($sql); - $this->data_cache['field_names'][$table] = array(); - - foreach ($query->result_array() as $row) - { - // Do we know from where to get the column's name? - if ( ! isset($key)) - { - if (isset($row['column_name'])) - { - $key = 'column_name'; - } - elseif (isset($row['COLUMN_NAME'])) - { - $key = 'COLUMN_NAME'; - } - else - { - // We have no other choice but to just get the first element's key. - $key = key($row); - } - } - - $this->data_cache['field_names'][$table][] = $row[$key]; - } - - return $this->data_cache['field_names'][$table]; - } - - // -------------------------------------------------------------------- - - /** - * Determine if a particular field exists - * - * @param string - * @param string - * @return bool - */ - public function field_exists($field_name, $table_name) - { - return in_array($field_name, $this->list_fields($table_name)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table the table name - * @return array - */ - public function field_data($table) - { - $query = $this->query($this->_field_data($this->protect_identifiers($table, TRUE, NULL, FALSE))); - return ($query) ? $query->field_data() : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Escape the SQL Identifiers - * - * This function escapes column and table names - * - * @param mixed - * @return mixed - */ - public function escape_identifiers($item) - { - if ($this->_escape_char === '' OR empty($item) OR in_array($item, $this->_reserved_identifiers)) - { - return $item; - } - elseif (is_array($item)) - { - foreach ($item as $key => $value) - { - $item[$key] = $this->escape_identifiers($value); - } - - return $item; - } - // Avoid breaking functions and literal values inside queries - elseif (ctype_digit($item) OR $item[0] === "'" OR ($this->_escape_char !== '"' && $item[0] === '"') OR strpos($item, '(') !== FALSE) - { - return $item; - } - - static $preg_ec = array(); - - if (empty($preg_ec)) - { - if (is_array($this->_escape_char)) - { - $preg_ec = array( - preg_quote($this->_escape_char[0], '/'), - preg_quote($this->_escape_char[1], '/'), - $this->_escape_char[0], - $this->_escape_char[1] - ); - } - else - { - $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char, '/'); - $preg_ec[2] = $preg_ec[3] = $this->_escape_char; - } - } - - foreach ($this->_reserved_identifiers as $id) - { - if (strpos($item, '.'.$id) !== FALSE) - { - return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?\./i', $preg_ec[2].'$1'.$preg_ec[3].'.', $item); - } - } - - return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?(\.)?/i', $preg_ec[2].'$1'.$preg_ec[3].'$2', $item); - } - - // -------------------------------------------------------------------- - - /** - * Generate an insert string - * - * @param string the table upon which the query will be performed - * @param array an associative array data of key/values - * @return string - */ - public function insert_string($table, $data) - { - $fields = $values = array(); - - foreach ($data as $key => $val) - { - $fields[] = $this->escape_identifiers($key); - $values[] = $this->escape($val); - } - - return $this->_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields, $values); - } - - // -------------------------------------------------------------------- - - /** - * Insert statement - * - * Generates a platform-specific insert string from the supplied data - * - * @param string the table name - * @param array the insert keys - * @param array the insert values - * @return string - */ - protected function _insert($table, $keys, $values) - { - return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - // -------------------------------------------------------------------- - - /** - * Generate an update string - * - * @param string the table upon which the query will be performed - * @param array an associative array data of key/values - * @param mixed the "where" statement - * @return string - */ - public function update_string($table, $data, $where) - { - if (empty($where)) - { - return FALSE; - } - - $this->where($where); - - $fields = array(); - foreach ($data as $key => $val) - { - $fields[$this->protect_identifiers($key)] = $this->escape($val); - } - - $sql = $this->_update($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields); - $this->_reset_write(); - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string the table name - * @param array the update data - * @return string - */ - protected function _update($table, $values) - { - foreach ($values as $key => $val) - { - $valstr[] = $key.' = '.$val; - } - - return 'UPDATE '.$table.' SET '.implode(', ', $valstr) - .$this->_compile_wh('qb_where') - .$this->_compile_order_by() - .($this->qb_limit ? ' LIMIT '.$this->qb_limit : ''); - } - - // -------------------------------------------------------------------- - - /** - * Tests whether the string has an SQL operator - * - * @param string - * @return bool - */ - protected function _has_operator($str) - { - return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str)); - } - - // -------------------------------------------------------------------- - - /** - * Returns the SQL string operator - * - * @param string - * @return string - */ - protected function _get_operator($str) - { - static $_operators; - - if (empty($_operators)) - { - $_les = ($this->_like_escape_str !== '') - ? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr)), '/') - : ''; - $_operators = array( - '\s*(?:<|>|!)?=\s*', // =, <=, >=, != - '\s*<>?\s*', // <, <> - '\s*>\s*', // > - '\s+IS NULL', // IS NULL - '\s+IS NOT NULL', // IS NOT NULL - '\s+EXISTS\s*\(.*\)', // EXISTS(sql) - '\s+NOT EXISTS\s*\(.*\)', // NOT EXISTS(sql) - '\s+BETWEEN\s+', // BETWEEN value AND value - '\s+IN\s*\(.*\)', // IN(list) - '\s+NOT IN\s*\(.*\)', // NOT IN (list) - '\s+LIKE\s+\S.*('.$_les.')?', // LIKE 'expr'[ ESCAPE '%s'] - '\s+NOT LIKE\s+\S.*('.$_les.')?' // NOT LIKE 'expr'[ ESCAPE '%s'] - ); - - } - - return preg_match('/'.implode('|', $_operators).'/i', $str, $match) - ? $match[0] : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Enables a native PHP function to be run, using a platform agnostic wrapper. - * - * @param string $function Function name - * @return mixed - */ - public function call_function($function) - { - $driver = ($this->dbdriver === 'postgre') ? 'pg_' : $this->dbdriver.'_'; - - if (FALSE === strpos($driver, $function)) - { - $function = $driver.$function; - } - - if ( ! function_exists($function)) - { - return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE; - } - - return (func_num_args() > 1) - ? call_user_func_array($function, array_slice(func_get_args(), 1)) - : call_user_func($function); - } - - // -------------------------------------------------------------------- - - /** - * Set Cache Directory Path - * - * @param string the path to the cache directory - * @return void - */ - public function cache_set_path($path = '') - { - $this->cachedir = $path; - } - - // -------------------------------------------------------------------- - - /** - * Enable Query Caching - * - * @return bool cache_on value - */ - public function cache_on() - { - return $this->cache_on = TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Disable Query Caching - * - * @return bool cache_on value - */ - public function cache_off() - { - return $this->cache_on = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Delete the cache files associated with a particular URI - * - * @param string $segment_one = '' - * @param string $segment_two = '' - * @return bool - */ - public function cache_delete($segment_one = '', $segment_two = '') - { - return $this->_cache_init() - ? $this->CACHE->delete($segment_one, $segment_two) - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Delete All cache files - * - * @return bool - */ - public function cache_delete_all() - { - return $this->_cache_init() - ? $this->CACHE->delete_all() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Initialize the Cache Class - * - * @return bool - */ - protected function _cache_init() - { - if ( ! class_exists('FW_DB_Cache', FALSE)) - { - require_once(Core::$coreDir . DS . 'Database'.DS.'DB_cache.php'); - } - elseif (is_object($this->CACHE)) - { - return TRUE; - } - - $this->CACHE = new FW_DB_Cache($this); // pass db object to support multiple db connections and returned db objects - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - public function close() - { - if ($this->conn_id) - { - $this->_close(); - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * This method would be overridden by most of the drivers. - * - * @return void - */ - protected function _close() - { - $this->conn_id = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Display an error message - * - * @param string the error message - * @param string any "swap" values - * @param bool whether to localize the message - * @return string sends the application/layout/errors/error_db.php template - */ - public function display_error($error = '', $swap = '', $native = FALSE) - { - // First load the language - Language::get('db'); - - $heading = Language::line('db_error_heading'); - - if ($native === TRUE) - { - $message = (array) $error; - } - else - { - $message = is_array($error) ? $error : array(str_replace('%s', $swap, Language::line($error))); - } - - // Find the most likely culprit of the error by going through - // the backtrace until the source file is no longer in the - // database folder. - $trace = debug_backtrace(); - $file = ''; - $line = ''; - foreach ($trace as $call) - { - if (isset($call['file'], $call['class'])) - { - // We'll need this on Windows, as APPPATH and BASEPATH will always use forward slashes - if (DIRECTORY_SEPARATOR !== '/') - { - $call['file'] = str_replace('\\', '/', $call['file']); - } - - if (strpos($call['file'], Core::$coreDir . DS . 'Database') === FALSE && strpos($call['class'], 'Loader') === FALSE) - { - // Found it - use a relative path for safety - $file = str_replace(array('Application', 'Core'), '', $call['file']); - $line = $call['line']; - break; - } - } - } - - Logger::logError($heading . " | " . implode(' | ', $message), null, $file, $line); - throw new DatabaseException($heading . ": " . implode(' ', $this->error()), 1); - - } - - // -------------------------------------------------------------------- - - /** - * Protect Identifiers - * - * This function is used extensively by the Query Builder class, and by - * a couple functions in this class. - * It takes a column or table name (optionally with an alias) and inserts - * the table prefix onto it. Some logic is necessary in order to deal with - * column names that include the path. Consider a query like this: - * - * SELECT hostname.database.table.column AS c FROM hostname.database.table - * - * Or a query with aliasing: - * - * SELECT m.member_id, m.member_name FROM members AS m - * - * Since the column name can include up to four segments (host, DB, table, column) - * or also have an alias prefix, we need to do a bit of work to figure this out and - * insert the table prefix (if it exists) in the proper position, and escape only - * the correct identifiers. - * - * @param string - * @param bool - * @param mixed - * @param bool - * @return string - */ - public function protect_identifiers($item, $prefix_single = FALSE, $protect_identifiers = NULL, $field_exists = TRUE) - { - if ( ! is_bool($protect_identifiers)) - { - $protect_identifiers = $this->_protect_identifiers; - } - - if (is_array($item)) - { - $escaped_array = array(); - foreach ($item as $k => $v) - { - $escaped_array[$this->protect_identifiers($k)] = $this->protect_identifiers($v, $prefix_single, $protect_identifiers, $field_exists); - } - - return $escaped_array; - } - - // This is basically a bug fix for queries that use MAX, MIN, etc. - // If a parenthesis is found we know that we do not need to - // escape the data or add a prefix. There's probably a more graceful - // way to deal with this, but I'm not thinking of it -- Rick - // - // Added exception for single quotes as well, we don't want to alter - // literal strings. -- Narf - if (strcspn($item, "()'") !== strlen($item)) - { - return $item; - } - - // Convert tabs or multiple spaces into single spaces - $item = preg_replace('/\s+/', ' ', trim($item)); - - // If the item has an alias declaration we remove it and set it aside. - // Note: strripos() is used in order to support spaces in table names - if ($offset = strripos($item, ' AS ')) - { - $alias = ($protect_identifiers) - ? substr($item, $offset, 4).$this->escape_identifiers(substr($item, $offset + 4)) - : substr($item, $offset); - $item = substr($item, 0, $offset); - } - elseif ($offset = strrpos($item, ' ')) - { - $alias = ($protect_identifiers) - ? ' '.$this->escape_identifiers(substr($item, $offset + 1)) - : substr($item, $offset); - $item = substr($item, 0, $offset); - } - else - { - $alias = ''; - } - - // Break the string apart if it contains periods, then insert the table prefix - // in the correct location, assuming the period doesn't indicate that we're dealing - // with an alias. While we're at it, we will escape the components - if (strpos($item, '.') !== FALSE) - { - $parts = explode('.', $item); - - // Does the first segment of the exploded item match - // one of the aliases previously identified? If so, - // we have nothing more to do other than escape the item - // - // NOTE: The ! empty() condition prevents this method - // from breaking when QB isn't enabled. - if ( ! empty($this->qb_aliased_tables) && in_array($parts[0], $this->qb_aliased_tables)) - { - if ($protect_identifiers === TRUE) - { - foreach ($parts as $key => $val) - { - if ( ! in_array($val, $this->_reserved_identifiers)) - { - $parts[$key] = $this->escape_identifiers($val); - } - } - - $item = implode('.', $parts); - } - - return $item.$alias; - } - - // Is there a table prefix defined in the config file? If not, no need to do anything - if ($this->dbprefix !== '') - { - // We now add the table prefix based on some logic. - // Do we have 4 segments (hostname.database.table.column)? - // If so, we add the table prefix to the column name in the 3rd segment. - if (isset($parts[3])) - { - $i = 2; - } - // Do we have 3 segments (database.table.column)? - // If so, we add the table prefix to the column name in 2nd position - elseif (isset($parts[2])) - { - $i = 1; - } - // Do we have 2 segments (table.column)? - // If so, we add the table prefix to the column name in 1st segment - else - { - $i = 0; - } - - // This flag is set when the supplied $item does not contain a field name. - // This can happen when this function is being called from a JOIN. - if ($field_exists === FALSE) - { - $i++; - } - - // Verify table prefix and replace if necessary - if ($this->swap_pre !== '' && strpos($parts[$i], $this->swap_pre) === 0) - { - $parts[$i] = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $parts[$i]); - } - // We only add the table prefix if it does not already exist - elseif (strpos($parts[$i], $this->dbprefix) !== 0) - { - $parts[$i] = $this->dbprefix.$parts[$i]; - } - - // Put the parts back together - $item = implode('.', $parts); - } - - if ($protect_identifiers === TRUE) - { - $item = $this->escape_identifiers($item); - } - - return $item.$alias; - } - - // Is there a table prefix? If not, no need to insert it - if ($this->dbprefix !== '') - { - // Verify table prefix and replace if necessary - if ($this->swap_pre !== '' && strpos($item, $this->swap_pre) === 0) - { - $item = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $item); - } - // Do we prefix an item with no segments? - elseif ($prefix_single === TRUE && strpos($item, $this->dbprefix) !== 0) - { - $item = $this->dbprefix.$item; - } - } - - if ($protect_identifiers === TRUE && ! in_array($item, $this->_reserved_identifiers)) - { - $item = $this->escape_identifiers($item); - } - - return $item.$alias; - } - - // -------------------------------------------------------------------- - - /** - * Dummy method that allows Query Builder class to be disabled - * and keep count_all() working. - * - * @return void - */ - protected function _reset_select() - { - } - -} diff --git a/src/Database/DB_forge.php b/src/Database/DB_forge.php deleted file mode 100644 index 0358871..0000000 --- a/src/Database/DB_forge.php +++ /dev/null @@ -1,1032 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -abstract class FW_DB_forge { - - /** - * Database object - * - * @var object - */ - protected $db; - - /** - * Fields data - * - * @var array - */ - public $fields = array(); - - /** - * Keys data - * - * @var array - */ - public $keys = array(); - - /** - * Primary Keys data - * - * @var array - */ - public $primary_keys = array(); - - /** - * Database character set - * - * @var string - */ - public $db_char_set = ''; - - // -------------------------------------------------------------------- - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE DATABASE %s'; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = 'DROP DATABASE %s'; - - /** - * CREATE TABLE statement - * - * @var string - */ - protected $_create_table = "%s %s (%s\n)"; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = FALSE; - - /** - * DROP TABLE IF EXISTS statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = 'ALTER TABLE %s RENAME TO %s;'; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = TRUE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = ''; - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = ' DEFAULT '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - $this->db =& $db; - Logger::log('Database Forge Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return bool - */ - public function create_database($db_name) - { - if ($this->_create_database === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - elseif ( ! $this->db->query(sprintf($this->_create_database, $db_name, $this->db->char_set, $this->db->dbcollat))) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - if ( ! empty($this->db->data_cache['db_names'])) - { - $this->db->data_cache['db_names'][] = $db_name; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name - * @return bool - */ - public function drop_database($db_name) - { - if ($this->_drop_database === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - elseif ( ! $this->db->query(sprintf($this->_drop_database, $db_name))) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - if ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($db_name), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Add Key - * - * @param string $key - * @param bool $primary - * @return FW_DB_forge - */ - public function add_key($key, $primary = FALSE) - { - // DO NOT change this! This condition is only applicable - // for PRIMARY keys because you can only have one such, - // and therefore all fields you add to it will be included - // in the same, composite PRIMARY KEY. - // - // It's not the same for regular indexes. - if ($primary === TRUE && is_array($key)) - { - foreach ($key as $one) - { - $this->add_key($one, $primary); - } - - return $this; - } - - if ($primary === TRUE) - { - $this->primary_keys[] = $key; - } - else - { - $this->keys[] = $key; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Add Field - * - * @param array $field - * @return FW_DB_forge - */ - public function add_field($field) - { - if (is_string($field)) - { - if ($field === 'id') - { - $this->add_field(array( - 'id' => array( - 'type' => 'INT', - 'constraint' => 9, - 'auto_increment' => TRUE - ) - )); - $this->add_key('id', TRUE); - } - else - { - if (strpos($field, ' ') === FALSE) - { - throw new DatabaseException('Field information is required for that operation.', 1); - } - - $this->fields[] = $field; - } - } - - if (is_array($field)) - { - $this->fields = array_merge($this->fields, $field); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Create Table - * - * @param string $table Table name - * @param bool $if_not_exists Whether to add IF NOT EXISTS condition - * @param array $attributes Associative array of table attributes - * @return bool - */ - public function create_table($table, $if_not_exists = FALSE, array $attributes = array()) - { - if ($table === '') - { - throw new DatabaseException('A table name is required for that operation.', 1); - } - else - { - $table = $this->db->dbprefix.$table; - } - - if (count($this->fields) === 0) - { - throw new DatabaseException('Field information is required.', 1); - } - - $sql = $this->_create_table($table, $if_not_exists, $attributes); - - if (is_bool($sql)) - { - $this->_reset(); - if ($sql === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - } - - if (($result = $this->db->query($sql)) !== FALSE) - { - empty($this->db->data_cache['table_names']) OR $this->db->data_cache['table_names'][] = $table; - - // Most databases don't support creating indexes from within the CREATE TABLE statement - if ( ! empty($this->keys)) - { - for ($i = 0, $sqls = $this->_process_indexes($table), $c = count($sqls); $i < $c; $i++) - { - $this->db->query($sqls[$i]); - } - } - } - - $this->_reset(); - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Create Table - * - * @param string $table Table name - * @param bool $if_not_exists Whether to add 'IF NOT EXISTS' condition - * @param array $attributes Associative array of table attributes - * @return mixed - */ - protected function _create_table($table, $if_not_exists, $attributes) - { - if ($if_not_exists === TRUE && $this->_create_table_if === FALSE) - { - if ($this->db->table_exists($table)) - { - return TRUE; - } - else - { - $if_not_exists = FALSE; - } - } - - $sql = ($if_not_exists) - ? sprintf($this->_create_table_if, $this->db->escape_identifiers($table)) - : 'CREATE TABLE'; - - $columns = $this->_process_fields(TRUE); - for ($i = 0, $c = count($columns); $i < $c; $i++) - { - $columns[$i] = ($columns[$i]['_literal'] !== FALSE) - ? "\n\t".$columns[$i]['_literal'] - : "\n\t".$this->_process_column($columns[$i]); - } - - $columns = implode(',', $columns) - .$this->_process_primary_keys($table); - - // Are indexes created from within the CREATE TABLE statement? (e.g. in MySQL) - if ($this->_create_table_keys === TRUE) - { - $columns .= $this->_process_indexes($table); - } - - // _create_table will usually have the following format: "%s %s (%s\n)" - $sql = sprintf($this->_create_table.'%s', - $sql, - $this->db->escape_identifiers($table), - $columns, - $this->_create_table_attr($attributes) - ); - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * CREATE TABLE attributes - * - * @param array $attributes Associative array of table attributes - * @return string - */ - protected function _create_table_attr($attributes) - { - $sql = ''; - - foreach (array_keys($attributes) as $key) - { - if (is_string($key)) - { - $sql .= ' '.strtoupper($key).' '.$attributes[$key]; - } - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Drop Table - * - * @param string $table_name Table name - * @param bool $if_exists Whether to add an IF EXISTS condition - * @return bool - */ - public function drop_table($table_name, $if_exists = FALSE) - { - if ($table_name === '') - { - return ($this->db->db_debug) ? $this->db->display_error('db_table_name_required') : FALSE; - } - - if (($query = $this->_drop_table($this->db->dbprefix.$table_name, $if_exists)) === TRUE) - { - return TRUE; - } - - $query = $this->db->query($query); - - // Update table list cache - if ($query && ! empty($this->db->data_cache['table_names'])) - { - $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['table_names'][$key]); - } - } - - return $query; - } - - // -------------------------------------------------------------------- - - /** - * Drop Table - * - * Generates a platform-specific DROP TABLE string - * - * @param string $table Table name - * @param bool $if_exists Whether to add an IF EXISTS condition - * @return string - */ - protected function _drop_table($table, $if_exists) - { - $sql = 'DROP TABLE'; - - if ($if_exists) - { - if ($this->_drop_table_if === FALSE) - { - if ( ! $this->db->table_exists($table)) - { - return TRUE; - } - } - else - { - $sql = sprintf($this->_drop_table_if, $this->db->escape_identifiers($table)); - } - } - - return $sql.' '.$this->db->escape_identifiers($table); - } - - // -------------------------------------------------------------------- - - /** - * Rename Table - * - * @param string $table_name Old table name - * @param string $new_table_name New table name - * @return bool - */ - public function rename_table($table_name, $new_table_name) - { - if ($table_name === '' OR $new_table_name === '') - { - throw new DatabaseException('A table name is required for that operation.', 1); - return FALSE; - } - elseif ($this->_rename_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $result = $this->db->query(sprintf($this->_rename_table, - $this->db->escape_identifiers($this->db->dbprefix.$table_name), - $this->db->escape_identifiers($this->db->dbprefix.$new_table_name)) - ); - - if ($result && ! empty($this->db->data_cache['table_names'])) - { - $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE); - if ($key !== FALSE) - { - $this->db->data_cache['table_names'][$key] = $this->db->dbprefix.$new_table_name; - } - } - - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Column Add - * - * @todo Remove deprecated $_after option in 3.1+ - * @param string $table Table name - * @param array $field Column definition - * @param string $_after Column for AFTER clause (deprecated) - * @return bool - */ - public function add_column($table, $field, $_after = NULL) - { - // Work-around for literal column definitions - is_array($field) OR $field = array($field); - - foreach (array_keys($field) as $k) - { - // Backwards-compatibility work-around for MySQL/CUBRID AFTER clause (remove in 3.1+) - if ($_after !== NULL && is_array($field[$k]) && ! isset($field[$k]['after'])) - { - $field[$k]['after'] = $_after; - } - - $this->add_field(array($k => $field[$k])); - } - - $sqls = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->_process_fields()); - $this->_reset(); - if ($sqls === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - for ($i = 0, $c = count($sqls); $i < $c; $i++) - { - if ($this->db->query($sqls[$i]) === FALSE) - { - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Column Drop - * - * @param string $table Table name - * @param string $column_name Column name - * @return bool - */ - public function drop_column($table, $column_name) - { - $sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name); - if ($sql === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - return $this->db->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Column Modify - * - * @param string $table Table name - * @param string $field Column definition - * @return bool - */ - public function modify_column($table, $field) - { - // Work-around for literal column definitions - is_array($field) OR $field = array($field); - - foreach (array_keys($field) as $k) - { - $this->add_field(array($k => $field[$k])); - } - - if (count($this->fields) === 0) - { - throw new DatabaseException('Field information is required.', 1); - } - - $sqls = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->_process_fields()); - $this->_reset(); - if ($sqls === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - for ($i = 0, $c = count($sqls); $i < $c; $i++) - { - if ($this->db->query($sqls[$i]) === FALSE) - { - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '; - - // DROP has everything it needs now. - if ($alter_type === 'DROP') - { - return $sql.'DROP COLUMN '.$this->db->escape_identifiers($field); - } - - $sql .= ($alter_type === 'ADD') - ? 'ADD ' - : $alter_type.' COLUMN '; - - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql - .($field[$i]['_literal'] !== FALSE ? $field[$i]['_literal'] : $this->_process_column($field[$i])); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process fields - * - * @param bool $create_table - * @return array - */ - protected function _process_fields($create_table = FALSE) - { - $fields = array(); - - foreach ($this->fields as $key => $attributes) - { - if (is_int($key) && ! is_array($attributes)) - { - $fields[] = array('_literal' => $attributes); - continue; - } - - $attributes = array_change_key_case($attributes, CASE_UPPER); - - if ($create_table === TRUE && empty($attributes['TYPE'])) - { - continue; - } - - isset($attributes['TYPE']) && $this->_attr_type($attributes); - - $field = array( - 'name' => $key, - 'new_name' => isset($attributes['NAME']) ? $attributes['NAME'] : NULL, - 'type' => isset($attributes['TYPE']) ? $attributes['TYPE'] : NULL, - 'length' => '', - 'unsigned' => '', - 'null' => '', - 'unique' => '', - 'default' => '', - 'auto_increment' => '', - '_literal' => FALSE - ); - - isset($attributes['TYPE']) && $this->_attr_unsigned($attributes, $field); - - if ($create_table === FALSE) - { - if (isset($attributes['AFTER'])) - { - $field['after'] = $attributes['AFTER']; - } - elseif (isset($attributes['FIRST'])) - { - $field['first'] = (bool) $attributes['FIRST']; - } - } - - $this->_attr_default($attributes, $field); - - if (isset($attributes['NULL'])) - { - if ($attributes['NULL'] === TRUE) - { - $field['null'] = empty($this->_null) ? '' : ' '.$this->_null; - } - else - { - $field['null'] = ' NOT NULL'; - } - } - elseif ($create_table === TRUE) - { - $field['null'] = ' NOT NULL'; - } - - $this->_attr_auto_increment($attributes, $field); - $this->_attr_unique($attributes, $field); - - if (isset($attributes['COMMENT'])) - { - $field['comment'] = $this->db->escape($attributes['COMMENT']); - } - - if (isset($attributes['TYPE']) && ! empty($attributes['CONSTRAINT'])) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['CONSTRAINT'] = $this->db->escape($attributes['CONSTRAINT']); - default: - $field['length'] = is_array($attributes['CONSTRAINT']) - ? '('.implode(',', $attributes['CONSTRAINT']).')' - : '('.$attributes['CONSTRAINT'].')'; - break; - } - } - - $fields[] = $field; - } - - return $fields; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['default'] - .$field['null'] - .$field['auto_increment'] - .$field['unique']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - // Usually overridden by drivers - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNSIGNED - * - * Depending on the _unsigned property value: - * - * - TRUE will always set $field['unsigned'] to 'UNSIGNED' - * - FALSE will always set $field['unsigned'] to '' - * - array(TYPE) will set $field['unsigned'] to 'UNSIGNED', - * if $attributes['TYPE'] is found in the array - * - array(TYPE => UTYPE) will change $field['type'], - * from TYPE to UTYPE in case of a match - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unsigned(&$attributes, &$field) - { - if (empty($attributes['UNSIGNED']) OR $attributes['UNSIGNED'] !== TRUE) - { - return; - } - - // Reset the attribute in order to avoid issues if we do type conversion - $attributes['UNSIGNED'] = FALSE; - - if (is_array($this->_unsigned)) - { - foreach (array_keys($this->_unsigned) as $key) - { - if (is_int($key) && strcasecmp($attributes['TYPE'], $this->_unsigned[$key]) === 0) - { - $field['unsigned'] = ' UNSIGNED'; - return; - } - elseif (is_string($key) && strcasecmp($attributes['TYPE'], $key) === 0) - { - $field['type'] = $key; - return; - } - } - - return; - } - - $field['unsigned'] = ($this->_unsigned === TRUE) ? ' UNSIGNED' : ''; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute DEFAULT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_default(&$attributes, &$field) - { - if ($this->_default === FALSE) - { - return; - } - - if (array_key_exists('DEFAULT', $attributes)) - { - if ($attributes['DEFAULT'] === NULL) - { - $field['default'] = empty($this->_null) ? '' : $this->_default.$this->_null; - - // Override the NULL attribute if that's our default - $attributes['NULL'] = TRUE; - $field['null'] = empty($this->_null) ? '' : ' '.$this->_null; - } - else - { - $field['default'] = $this->_default.$this->db->escape($attributes['DEFAULT']); - } - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE'; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' AUTO_INCREMENT'; - } - } - - // -------------------------------------------------------------------- - - /** - * Process primary keys - * - * @param string $table Table name - * @return string - */ - protected function _process_primary_keys($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->primary_keys); $i < $c; $i++) - { - if ( ! isset($this->fields[$this->primary_keys[$i]])) - { - unset($this->primary_keys[$i]); - } - } - - if (count($this->primary_keys) > 0) - { - $sql .= ",\n\tCONSTRAINT ".$this->db->escape_identifiers('pk_'.$table) - .' PRIMARY KEY('.implode(', ', $this->db->escape_identifiers($this->primary_keys)).')'; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table - * @return string - */ - protected function _process_indexes($table) - { - $sqls = array(); - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sqls[] = 'CREATE INDEX '.$this->db->escape_identifiers($table.'_'.implode('_', $this->keys[$i])) - .' ON '.$this->db->escape_identifiers($table) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).');'; - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Reset - * - * Resets table creation vars - * - * @return void - */ - protected function _reset() - { - $this->fields = $this->keys = $this->primary_keys = array(); - } - -} diff --git a/src/Database/DB_query_builder.php b/src/Database/DB_query_builder.php deleted file mode 100644 index 5ba5f10..0000000 --- a/src/Database/DB_query_builder.php +++ /dev/null @@ -1,2781 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * Query Builder Class - * - * This is the platform-independent base Query Builder implementation class. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ - -abstract class FW_DB_query_builder extends FW_DB_driver { - - /** - * Return DELETE SQL flag - * - * @var bool - */ - protected $return_delete_sql = FALSE; - - /** - * Reset DELETE data flag - * - * @var bool - */ - protected $reset_delete_data = FALSE; - - /** - * QB SELECT data - * - * @var array - */ - protected $qb_select = array(); - - /** - * QB DISTINCT flag - * - * @var bool - */ - protected $qb_distinct = FALSE; - - /** - * QB FROM data - * - * @var array - */ - protected $qb_from = array(); - - /** - * QB JOIN data - * - * @var array - */ - protected $qb_join = array(); - - /** - * QB WHERE data - * - * @var array - */ - protected $qb_where = array(); - - /** - * QB GROUP BY data - * - * @var array - */ - protected $qb_groupby = array(); - - /** - * QB HAVING data - * - * @var array - */ - protected $qb_having = array(); - - /** - * QB keys - * - * @var array - */ - protected $qb_keys = array(); - - /** - * QB LIMIT data - * - * @var int - */ - protected $qb_limit = FALSE; - - /** - * QB OFFSET data - * - * @var int - */ - protected $qb_offset = FALSE; - - /** - * QB ORDER BY data - * - * @var array - */ - protected $qb_orderby = array(); - - /** - * QB data sets - * - * @var array - */ - protected $qb_set = array(); - - /** - * QB aliased tables list - * - * @var array - */ - protected $qb_aliased_tables = array(); - - /** - * QB WHERE group started flag - * - * @var bool - */ - protected $qb_where_group_started = FALSE; - - /** - * QB WHERE group count - * - * @var int - */ - protected $qb_where_group_count = 0; - - // Query Builder Caching variables - - /** - * QB Caching flag - * - * @var bool - */ - protected $qb_caching = FALSE; - - /** - * QB Cache exists list - * - * @var array - */ - protected $qb_cache_exists = array(); - - /** - * QB Cache SELECT data - * - * @var array - */ - protected $qb_cache_select = array(); - - /** - * QB Cache FROM data - * - * @var array - */ - protected $qb_cache_from = array(); - - /** - * QB Cache JOIN data - * - * @var array - */ - protected $qb_cache_join = array(); - - /** - * QB Cache WHERE data - * - * @var array - */ - protected $qb_cache_where = array(); - - /** - * QB Cache GROUP BY data - * - * @var array - */ - protected $qb_cache_groupby = array(); - - /** - * QB Cache HAVING data - * - * @var array - */ - protected $qb_cache_having = array(); - - /** - * QB Cache ORDER BY data - * - * @var array - */ - protected $qb_cache_orderby = array(); - - /** - * QB Cache data sets - * - * @var array - */ - protected $qb_cache_set = array(); - - /** - * QB No Escape data - * - * @var array - */ - protected $qb_no_escape = array(); - - /** - * QB Cache No Escape data - * - * @var array - */ - protected $qb_cache_no_escape = array(); - - // -------------------------------------------------------------------- - - /** - * Select - * - * Generates the SELECT portion of the query - * - * @param string - * @param mixed - * @return FW_DB_query_builder - */ - public function select($select = '*', $escape = NULL) - { - if (is_string($select)) - { - $select = explode(',', $select); - } - - // If the escape value was not set, we will base it on the global setting - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($select as $val) - { - $val = trim($val); - - if ($val !== '') - { - $this->qb_select[] = $val; - $this->qb_no_escape[] = $escape; - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_select[] = $val; - $this->qb_cache_exists[] = 'select'; - $this->qb_cache_no_escape[] = $escape; - } - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Select Max - * - * Generates a SELECT MAX(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_max($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'MAX'); - } - - // -------------------------------------------------------------------- - - /** - * Select Min - * - * Generates a SELECT MIN(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_min($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'MIN'); - } - - // -------------------------------------------------------------------- - - /** - * Select Average - * - * Generates a SELECT AVG(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_avg($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'AVG'); - } - - // -------------------------------------------------------------------- - - /** - * Select Sum - * - * Generates a SELECT SUM(field) portion of a query - * - * @param string the field - * @param string an alias - * @return FW_DB_query_builder - */ - public function select_sum($select = '', $alias = '') - { - return $this->_max_min_avg_sum($select, $alias, 'SUM'); - } - - // -------------------------------------------------------------------- - - /** - * SELECT [MAX|MIN|AVG|SUM]() - * - * @used-by select_max() - * @used-by select_min() - * @used-by select_avg() - * @used-by select_sum() - * - * @param string $select Field name - * @param string $alias - * @param string $type - * @return FW_DB_query_builder - */ - protected function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX') - { - if ( ! is_string($select) OR $select === '') - { - $this->display_error('db_invalid_query'); - } - - $type = strtoupper($type); - - if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM'))) - { - throw new DatabaseException('Invalid function type: '.$type, 1); - } - - if ($alias === '') - { - $alias = $this->_create_alias_from_table(trim($select)); - } - - $sql = $type.'('.$this->protect_identifiers(trim($select)).') AS '.$this->escape_identifiers(trim($alias)); - - $this->qb_select[] = $sql; - $this->qb_no_escape[] = NULL; - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_select[] = $sql; - $this->qb_cache_exists[] = 'select'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Determines the alias name based on the table - * - * @param string $item - * @return string - */ - protected function _create_alias_from_table($item) - { - if (strpos($item, '.') !== FALSE) - { - $item = explode('.', $item); - return end($item); - } - - return $item; - } - - // -------------------------------------------------------------------- - - /** - * DISTINCT - * - * Sets a flag which tells the query string compiler to add DISTINCT - * - * @param bool $val - * @return FW_DB_query_builder - */ - public function distinct($val = TRUE) - { - $this->qb_distinct = is_bool($val) ? $val : TRUE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * From - * - * Generates the FROM portion of the query - * - * @param mixed $from can be a string or array - * @return FW_DB_query_builder - */ - public function from($from) - { - foreach ((array) $from as $val) - { - if (strpos($val, ',') !== FALSE) - { - foreach (explode(',', $val) as $v) - { - $v = trim($v); - $this->_track_aliases($v); - - $this->qb_from[] = $v = $this->protect_identifiers($v, TRUE, NULL, FALSE); - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_from[] = $v; - $this->qb_cache_exists[] = 'from'; - } - } - } - else - { - $val = trim($val); - - // Extract any aliases that might exist. We use this information - // in the protect_identifiers to know whether to add a table prefix - $this->_track_aliases($val); - - $this->qb_from[] = $val = $this->protect_identifiers($val, TRUE, NULL, FALSE); - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_from[] = $val; - $this->qb_cache_exists[] = 'from'; - } - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * JOIN - * - * Generates the JOIN portion of the query - * - * @param string - * @param string the join condition - * @param string the type of join - * @param string whether not to try to escape identifiers - * @return FW_DB_query_builder - */ - public function join($table, $cond, $type = '', $escape = NULL) - { - if ($type !== '') - { - $type = strtoupper(trim($type)); - - if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE)) - { - $type = ''; - } - else - { - $type .= ' '; - } - } - - // Extract any aliases that might exist. We use this information - // in the protect_identifiers to know whether to add a table prefix - $this->_track_aliases($table); - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - if ( ! $this->_has_operator($cond)) - { - $cond = ' USING ('.($escape ? $this->escape_identifiers($cond) : $cond).')'; - } - elseif ($escape === FALSE) - { - $cond = ' ON '.$cond; - } - else - { - // Split multiple conditions - if (preg_match_all('/\sAND\s|\sOR\s/i', $cond, $joints, PREG_OFFSET_CAPTURE)) - { - $conditions = array(); - $joints = $joints[0]; - array_unshift($joints, array('', 0)); - - for ($i = count($joints) - 1, $pos = strlen($cond); $i >= 0; $i--) - { - $joints[$i][1] += strlen($joints[$i][0]); // offset - $conditions[$i] = substr($cond, $joints[$i][1], $pos - $joints[$i][1]); - $pos = $joints[$i][1] - strlen($joints[$i][0]); - $joints[$i] = $joints[$i][0]; - } - } - else - { - $conditions = array($cond); - $joints = array(''); - } - - $cond = ' ON '; - for ($i = 0, $c = count($conditions); $i < $c; $i++) - { - $operator = $this->_get_operator($conditions[$i]); - $cond .= $joints[$i]; - $cond .= preg_match("/(\(*)?([\[\]\w\.'-]+)".preg_quote($operator)."(.*)/i", $conditions[$i], $match) - ? $match[1].$this->protect_identifiers($match[2]).$operator.$this->protect_identifiers($match[3]) - : $conditions[$i]; - } - } - - // Do we want to escape the table name? - if ($escape === TRUE) - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // Assemble the JOIN statement - $this->qb_join[] = $join = $type.'JOIN '.$table.$cond; - - if ($this->qb_caching === TRUE) - { - $this->qb_cache_join[] = $join; - $this->qb_cache_exists[] = 'join'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * WHERE - * - * Generates the WHERE portion of the query. - * Separates multiple calls with 'AND'. - * - * @param mixed - * @param mixed - * @param bool - * @return FW_DB_query_builder - */ - public function where($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_where', $key, $value, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR WHERE - * - * Generates the WHERE portion of the query. - * Separates multiple calls with 'OR'. - * - * @param mixed - * @param mixed - * @param bool - * @return FW_DB_query_builder - */ - public function or_where($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_where', $key, $value, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * WHERE, HAVING - * - * @used-by where() - * @used-by or_where() - * @used-by having() - * @used-by or_having() - * - * @param string $qb_key 'qb_where' or 'qb_having' - * @param mixed $key - * @param mixed $value - * @param string $type - * @param bool $escape - * @return FW_DB_query_builder - */ - protected function _wh($qb_key, $key, $value = NULL, $type = 'AND ', $escape = NULL) - { - $qb_cache_key = ($qb_key === 'qb_having') ? 'qb_cache_having' : 'qb_cache_where'; - - if ( ! is_array($key)) - { - $key = array($key => $value); - } - - // If the escape value was not set will base it on the global setting - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($key as $k => $v) - { - $prefix = (count($this->$qb_key) === 0 && count($this->$qb_cache_key) === 0) - ? $this->_group_get_type('') - : $this->_group_get_type($type); - - if ($v !== NULL) - { - if ($escape === TRUE) - { - $v = ' '.$this->escape($v); - } - - if ( ! $this->_has_operator($k)) - { - $k .= ' = '; - } - } - elseif ( ! $this->_has_operator($k)) - { - // value appears not to have been set, assign the test to IS NULL - $k .= ' IS NULL'; - } - elseif (preg_match('/\s*(!?=|<>|IS(?:\s+NOT)?)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) - { - $k = substr($k, 0, $match[0][1]).($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL'); - } - - $this->{$qb_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape); - if ($this->qb_caching === TRUE) - { - $this->{$qb_cache_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape); - $this->qb_cache_exists[] = substr($qb_key, 3); - } - - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * WHERE IN - * - * Generates a WHERE field IN('item', 'item') SQL query, - * joined with 'AND' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function where_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, FALSE, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR WHERE IN - * - * Generates a WHERE field IN('item', 'item') SQL query, - * joined with 'OR' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_where_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, FALSE, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * WHERE NOT IN - * - * Generates a WHERE field NOT IN('item', 'item') SQL query, - * joined with 'AND' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function where_not_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, TRUE, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR WHERE NOT IN - * - * Generates a WHERE field NOT IN('item', 'item') SQL query, - * joined with 'OR' if appropriate. - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_where_not_in($key = NULL, $values = NULL, $escape = NULL) - { - return $this->_where_in($key, $values, TRUE, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * Internal WHERE IN - * - * @used-by where_in() - * @used-by or_where_in() - * @used-by where_not_in() - * @used-by or_where_not_in() - * - * @param string $key The field to search - * @param array $values The values searched on - * @param bool $not If the statement would be IN or NOT IN - * @param string $type - * @param bool $escape - * @return FW_DB_query_builder - */ - protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ', $escape = NULL) - { - if ($key === NULL OR $values === NULL) - { - return $this; - } - - if ( ! is_array($values)) - { - $values = array($values); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - $not = ($not) ? ' NOT' : ''; - - if ($escape === TRUE) - { - $where_in = array(); - foreach ($values as $value) - { - $where_in[] = $this->escape($value); - } - } - else - { - $where_in = array_values($values); - } - - $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) - ? $this->_group_get_type('') - : $this->_group_get_type($type); - - $where_in = array( - 'condition' => $prefix.$key.$not.' IN('.implode(', ', $where_in).')', - 'escape' => $escape - ); - - $this->qb_where[] = $where_in; - if ($this->qb_caching === TRUE) - { - $this->qb_cache_where[] = $where_in; - $this->qb_cache_exists[] = 'where'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * LIKE - * - * Generates a %LIKE% portion of the query. - * Separates multiple calls with 'AND'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'AND ', $side, '', $escape); - } - - // -------------------------------------------------------------------- - - /** - * NOT LIKE - * - * Generates a NOT LIKE portion of the query. - * Separates multiple calls with 'AND'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function not_like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'AND ', $side, 'NOT', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR LIKE - * - * Generates a %LIKE% portion of the query. - * Separates multiple calls with 'OR'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'OR ', $side, '', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR NOT LIKE - * - * Generates a NOT LIKE portion of the query. - * Separates multiple calls with 'OR'. - * - * @param mixed $field - * @param string $match - * @param string $side - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_not_like($field, $match = '', $side = 'both', $escape = NULL) - { - return $this->_like($field, $match, 'OR ', $side, 'NOT', $escape); - } - - // -------------------------------------------------------------------- - - /** - * Internal LIKE - * - * @used-by like() - * @used-by or_like() - * @used-by not_like() - * @used-by or_not_like() - * - * @param mixed $field - * @param string $match - * @param string $type - * @param string $side - * @param string $not - * @param bool $escape - * @return FW_DB_query_builder - */ - protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '', $escape = NULL) - { - if ( ! is_array($field)) - { - $field = array($field => $match); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - // lowercase $side in case somebody writes e.g. 'BEFORE' instead of 'before' (doh) - $side = strtolower($side); - - foreach ($field as $k => $v) - { - $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) - ? $this->_group_get_type('') : $this->_group_get_type($type); - - if ($escape === TRUE) - { - $v = $this->escape_like_str($v); - } - - if ($side === 'none') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}'"; - } - elseif ($side === 'before') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}'"; - } - elseif ($side === 'after') - { - $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}%'"; - } - else - { - $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}%'"; - } - - // some platforms require an escape sequence definition for LIKE wildcards - if ($escape === TRUE && $this->_like_escape_str !== '') - { - $like_statement .= sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - $this->qb_where[] = array('condition' => $like_statement, 'escape' => $escape); - if ($this->qb_caching === TRUE) - { - $this->qb_cache_where[] = array('condition' => $like_statement, 'escape' => $escape); - $this->qb_cache_exists[] = 'where'; - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group. - * - * @param string $not (Internal use only) - * @param string $type (Internal use only) - * @return FW_DB_query_builder - */ - public function group_start($not = '', $type = 'AND ') - { - $type = $this->_group_get_type($type); - - $this->qb_where_group_started = TRUE; - $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type; - $where = array( - 'condition' => $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (', - 'escape' => FALSE - ); - - $this->qb_where[] = $where; - if ($this->qb_caching) - { - $this->qb_cache_where[] = $where; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group, but ORs the group - * - * @return FW_DB_query_builder - */ - public function or_group_start() - { - return $this->group_start('', 'OR '); - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group, but NOTs the group - * - * @return FW_DB_query_builder - */ - public function not_group_start() - { - return $this->group_start('NOT ', 'AND '); - } - - // -------------------------------------------------------------------- - - /** - * Starts a query group, but OR NOTs the group - * - * @return FW_DB_query_builder - */ - public function or_not_group_start() - { - return $this->group_start('NOT ', 'OR '); - } - - // -------------------------------------------------------------------- - - /** - * Ends a query group - * - * @return FW_DB_query_builder - */ - public function group_end() - { - $this->qb_where_group_started = FALSE; - $where = array( - 'condition' => str_repeat(' ', $this->qb_where_group_count--).')', - 'escape' => FALSE - ); - - $this->qb_where[] = $where; - if ($this->qb_caching) - { - $this->qb_cache_where[] = $where; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Group_get_type - * - * @used-by group_start() - * @used-by _like() - * @used-by _wh() - * @used-by _where_in() - * - * @param string $type - * @return string - */ - protected function _group_get_type($type) - { - if ($this->qb_where_group_started) - { - $type = ''; - $this->qb_where_group_started = FALSE; - } - - return $type; - } - - // -------------------------------------------------------------------- - - /** - * GROUP BY - * - * @param string $by - * @param bool $escape - * @return FW_DB_query_builder - */ - public function group_by($by, $escape = NULL) - { - is_bool($escape) OR $escape = $this->_protect_identifiers; - - if (is_string($by)) - { - $by = ($escape === TRUE) - ? explode(',', $by) - : array($by); - } - - foreach ($by as $val) - { - $val = trim($val); - - if ($val !== '') - { - $val = array('field' => $val, 'escape' => $escape); - - $this->qb_groupby[] = $val; - if ($this->qb_caching === TRUE) - { - $this->qb_cache_groupby[] = $val; - $this->qb_cache_exists[] = 'groupby'; - } - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * HAVING - * - * Separates multiple calls with 'AND'. - * - * @param string $key - * @param string $value - * @param bool $escape - * @return FW_DB_query_builder - */ - public function having($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_having', $key, $value, 'AND ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * OR HAVING - * - * Separates multiple calls with 'OR'. - * - * @param string $key - * @param string $value - * @param bool $escape - * @return FW_DB_query_builder - */ - public function or_having($key, $value = NULL, $escape = NULL) - { - return $this->_wh('qb_having', $key, $value, 'OR ', $escape); - } - - // -------------------------------------------------------------------- - - /** - * ORDER BY - * - * @param string $orderby - * @param string $direction ASC, DESC or RANDOM - * @param bool $escape - * @return FW_DB_query_builder - */ - public function order_by($orderby, $direction = '', $escape = NULL) - { - $direction = strtoupper(trim($direction)); - - if ($direction === 'RANDOM') - { - $direction = ''; - - // Do we have a seed value? - $orderby = ctype_digit((string) $orderby) - ? sprintf($this->_random_keyword[1], $orderby) - : $this->_random_keyword[0]; - } - elseif (empty($orderby)) - { - return $this; - } - elseif ($direction !== '') - { - $direction = in_array($direction, array('ASC', 'DESC'), TRUE) ? ' '.$direction : ''; - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - if ($escape === FALSE) - { - $qb_orderby[] = array('field' => $orderby, 'direction' => $direction, 'escape' => FALSE); - } - else - { - $qb_orderby = array(); - foreach (explode(',', $orderby) as $field) - { - $qb_orderby[] = ($direction === '' && preg_match('/\s+(ASC|DESC)$/i', rtrim($field), $match, PREG_OFFSET_CAPTURE)) - ? array('field' => ltrim(substr($field, 0, $match[0][1])), 'direction' => ' '.$match[1][0], 'escape' => TRUE) - : array('field' => trim($field), 'direction' => $direction, 'escape' => TRUE); - } - } - - $this->qb_orderby = array_merge($this->qb_orderby, $qb_orderby); - if ($this->qb_caching === TRUE) - { - $this->qb_cache_orderby = array_merge($this->qb_cache_orderby, $qb_orderby); - $this->qb_cache_exists[] = 'orderby'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * @param int $value LIMIT value - * @param int $offset OFFSET value - * @return FW_DB_query_builder - */ - public function limit($value, $offset = 0) - { - is_null($value) OR $this->qb_limit = (int) $value; - empty($offset) OR $this->qb_offset = (int) $offset; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Sets the OFFSET value - * - * @param int $offset OFFSET value - * @return FW_DB_query_builder - */ - public function offset($offset) - { - empty($offset) OR $this->qb_offset = (int) $offset; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * LIMIT string - * - * Generates a platform-specific LIMIT clause. - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.($this->qb_offset ? $this->qb_offset.', ' : '').$this->qb_limit; - } - - // -------------------------------------------------------------------- - - /** - * The "set" function. - * - * Allows key/value pairs to be set for inserting or updating - * - * @param mixed - * @param string - * @param bool - * @return FW_DB_query_builder - */ - public function set($key, $value = '', $escape = NULL) - { - $key = $this->_object_to_array($key); - - if ( ! is_array($key)) - { - $key = array($key => $value); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($key as $k => $v) - { - $this->qb_set[$this->protect_identifiers($k, FALSE, $escape)] = ($escape) - ? $this->escape($v) : $v; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get SELECT query string - * - * Compiles a SELECT query string and returns the sql. - * - * @param string the table name to select from (optional) - * @param bool TRUE: resets QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_select($table = '', $reset = TRUE) - { - if ($table !== '') - { - $this->_track_aliases($table); - $this->from($table); - } - - $select = $this->_compile_select(); - - if ($reset === TRUE) - { - $this->_reset_select(); - } - - return $select; - } - - // -------------------------------------------------------------------- - - /** - * Get - * - * Compiles the select statement based on the other functions called - * and runs the query - * - * @param string the table - * @param string the limit clause - * @param string the offset clause - * @return FW_DB_result - */ - public function get($table = '', $limit = NULL, $offset = NULL) - { - if ($table !== '') - { - $this->_track_aliases($table); - $this->from($table); - } - - if ( ! empty($limit)) - { - $this->limit($limit, $offset); - } - - $result = $this->query($this->_compile_select()); - $this->_reset_select(); - return $result; - } - - // -------------------------------------------------------------------- - - /** - * "Count All Results" query - * - * Generates a platform-specific query string that counts all records - * returned by an Query Builder query. - * - * @param string - * @param bool the reset clause - * @return int - */ - public function count_all_results($table = '', $reset = TRUE) - { - if ($table !== '') - { - $this->_track_aliases($table); - $this->from($table); - } - - // ORDER BY usage is often problematic here (most notably - // on Microsoft SQL Server) and ultimately unnecessary - // for selecting COUNT(*) ... - if ( ! empty($this->qb_orderby)) - { - $orderby = $this->qb_orderby; - $this->qb_orderby = NULL; - } - - $result = ($this->qb_distinct === TRUE) - ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) FW_count_all_results") - : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows'))); - - if ($reset === TRUE) - { - $this->_reset_select(); - } - // If we've previously reset the qb_orderby values, get them back - elseif ( ! isset($this->qb_orderby)) - { - $this->qb_orderby = $orderby; - } - - if ($result->num_rows() === 0) - { - return 0; - } - - $row = $result->row(); - return (int) $row->numrows; - } - - // -------------------------------------------------------------------- - - /** - * Get_Where - * - * Allows the where clause, limit and offset to be added directly - * - * @param string $table - * @param string $where - * @param int $limit - * @param int $offset - * @return FW_DB_result - */ - public function get_where($table = '', $where = NULL, $limit = NULL, $offset = NULL) - { - if ($table !== '') - { - $this->from($table); - } - - if ($where !== NULL) - { - $this->where($where); - } - - if ( ! empty($limit)) - { - $this->limit($limit, $offset); - } - - $result = $this->query($this->_compile_select()); - $this->_reset_select(); - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Insert_Batch - * - * Compiles batch insert strings and runs the queries - * - * @param string $table Table to insert into - * @param array $set An associative array of insert values - * @param bool $escape Whether to escape values and identifiers - * @return int Number of rows inserted or FALSE on failure - */ - public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size = 100) - { - if ($set === NULL) - { - if (empty($this->qb_set)) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - } - else - { - if (empty($set)) - { - return ($this->db_debug) ? $this->display_error('insert_batch() called with no data') : FALSE; - } - - $this->set_insert_batch($set, '', $escape); - } - - if (strlen($table) === 0) - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - - // Batch this baby - $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) - { - $this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size))); - $affected_rows += $this->affected_rows(); - } - - $this->_reset_write(); - return $affected_rows; - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _insert_batch($table, $keys, $values) - { - return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values); - } - - // -------------------------------------------------------------------- - - /** - * The "set_insert_batch" function. Allows key/value pairs to be set for batch inserts - * - * @param mixed - * @param string - * @param bool - * @return FW_DB_query_builder - */ - public function set_insert_batch($key, $value = '', $escape = NULL) - { - $key = $this->_object_to_array_batch($key); - - if ( ! is_array($key)) - { - $key = array($key => $value); - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - $keys = array_keys($this->_object_to_array(current($key))); - sort($keys); - - foreach ($key as $row) - { - $row = $this->_object_to_array($row); - if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0) - { - // batch function above returns an error on an empty array - $this->qb_set[] = array(); - return; - } - - ksort($row); // puts $row in the same order as our keys - - if ($escape !== FALSE) - { - $clean = array(); - foreach ($row as $value) - { - $clean[] = $this->escape($value); - } - - $row = $clean; - } - - $this->qb_set[] = '('.implode(',', $row).')'; - } - - foreach ($keys as $k) - { - $this->qb_keys[] = $this->protect_identifiers($k, FALSE, $escape); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get INSERT query string - * - * Compiles an insert query and returns the sql - * - * @param string the table to insert into - * @param bool TRUE: reset QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_insert($table = '', $reset = TRUE) - { - if ($this->_validate_insert($table) === FALSE) - { - return FALSE; - } - - $sql = $this->_insert( - $this->protect_identifiers( - $this->qb_from[0], TRUE, NULL, FALSE - ), - array_keys($this->qb_set), - array_values($this->qb_set) - ); - - if ($reset === TRUE) - { - $this->_reset_write(); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Insert - * - * Compiles an insert string and runs the query - * - * @param string the table to insert data into - * @param array an associative array of insert values - * @param bool $escape Whether to escape values and identifiers - * @return bool TRUE on success, FALSE on failure - */ - public function insert($table = '', $set = NULL, $escape = NULL) - { - if ($set !== NULL) - { - $this->set($set, '', $escape); - } - - if ($this->_validate_insert($table) === FALSE) - { - return FALSE; - } - - $sql = $this->_insert( - $this->protect_identifiers( - $this->qb_from[0], TRUE, $escape, FALSE - ), - array_keys($this->qb_set), - array_values($this->qb_set) - ); - - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Validate Insert - * - * This method is used by both insert() and get_compiled_insert() to - * validate that the there data is actually being set and that table - * has been chosen to be inserted into. - * - * @param string the table to insert data into - * @return string - */ - protected function _validate_insert($table = '') - { - if (count($this->qb_set) === 0) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - - if ($table !== '') - { - $this->qb_from[0] = $table; - } - elseif ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Replace - * - * Compiles an replace into string and runs the query - * - * @param string the table to replace data into - * @param array an associative array of insert values - * @return bool TRUE on success, FALSE on failure - */ - public function replace($table = '', $set = NULL) - { - if ($set !== NULL) - { - $this->set($set); - } - - if (count($this->qb_set) === 0) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - - $sql = $this->_replace($this->protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->qb_set), array_values($this->qb_set)); - - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * Generates a platform-specific replace string from the supplied data - * - * @param string the table name - * @param array the insert keys - * @param array the insert values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * Note: This is only used (and overridden) by MySQL and CUBRID. - * - * @return string - */ - protected function _from_tables() - { - return implode(', ', $this->qb_from); - } - - // -------------------------------------------------------------------- - - /** - * Get UPDATE query string - * - * Compiles an update query and returns the sql - * - * @param string the table to update - * @param bool TRUE: reset QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_update($table = '', $reset = TRUE) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($this->_validate_update($table) === FALSE) - { - return FALSE; - } - - $sql = $this->_update($this->qb_from[0], $this->qb_set); - - if ($reset === TRUE) - { - $this->_reset_write(); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * UPDATE - * - * Compiles an update string and runs the query. - * - * @param string $table - * @param array $set An associative array of update values - * @param mixed $where - * @param int $limit - * @return bool TRUE on success, FALSE on failure - */ - public function update($table = '', $set = NULL, $where = NULL, $limit = NULL) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($set !== NULL) - { - $this->set($set); - } - - if ($this->_validate_update($table) === FALSE) - { - return FALSE; - } - - if ($where !== NULL) - { - $this->where($where); - } - - if ( ! empty($limit)) - { - $this->limit($limit); - } - - $sql = $this->_update($this->qb_from[0], $this->qb_set); - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Validate Update - * - * This method is used by both update() and get_compiled_update() to - * validate that data is actually being set and that a table has been - * chosen to be update. - * - * @param string the table to update data on - * @return bool - */ - protected function _validate_update($table) - { - if (count($this->qb_set) === 0) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - - if ($table !== '') - { - $this->qb_from = array($this->protect_identifiers($table, TRUE, NULL, FALSE)); - } - elseif ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch - * - * Compiles an update string and runs the query - * - * @param string the table to retrieve the results from - * @param array an associative array of update values - * @param string the where key - * @return int number of rows affected or FALSE on failure - */ - public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 100) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($index === NULL) - { - return ($this->db_debug) ? $this->display_error('db_must_use_index') : FALSE; - } - - if ($set === NULL) - { - if (empty($this->qb_set)) - { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; - } - } - else - { - if (empty($set)) - { - return ($this->db_debug) ? $this->display_error('update_batch() called with no data') : FALSE; - } - - $this->set_update_batch($set, $index); - } - - if (strlen($table) === 0) - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - - // Batch this baby - $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) - { - $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, $batch_size), $this->protect_identifiers($index))); - $affected_rows += $this->affected_rows(); - $this->qb_where = array(); - } - - $this->_reset_write(); - return $affected_rows; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k." = CASE \n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END, '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * The "set_update_batch" function. Allows key/value pairs to be set for batch updating - * - * @param array - * @param string - * @param bool - * @return FW_DB_query_builder - */ - public function set_update_batch($key, $index = '', $escape = NULL) - { - $key = $this->_object_to_array_batch($key); - - if ( ! is_array($key)) - { - // @todo error - } - - is_bool($escape) OR $escape = $this->_protect_identifiers; - - foreach ($key as $k => $v) - { - $index_set = FALSE; - $clean = array(); - foreach ($v as $k2 => $v2) - { - if ($k2 === $index) - { - $index_set = TRUE; - } - - $clean[$this->protect_identifiers($k2, FALSE, $escape)] = ($escape === FALSE) ? $v2 : $this->escape($v2); - } - - if ($index_set === FALSE) - { - return $this->display_error('db_batch_missing_index'); - } - - $this->qb_set[] = $clean; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Empty Table - * - * Compiles a delete string and runs "DELETE FROM table" - * - * @param string the table to empty - * @return bool TRUE on success, FALSE on failure - */ - public function empty_table($table = '') - { - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - else - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - $sql = $this->_delete($table); - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Truncate - * - * Compiles a truncate string and runs the query - * If the database does not support the truncate() command - * This function maps to "DELETE FROM table" - * - * @param string the table to truncate - * @return bool TRUE on success, FALSE on failure - */ - public function truncate($table = '') - { - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - else - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - $sql = $this->_truncate($table); - $this->_reset_write(); - return $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the truncate() command, - * then this method maps to 'DELETE FROM table' - * - * @param string the table name - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Get DELETE query string - * - * Compiles a delete query string and returns the sql - * - * @param string the table to delete from - * @param bool TRUE: reset QB values; FALSE: leave QB values alone - * @return string - */ - public function get_compiled_delete($table = '', $reset = TRUE) - { - $this->return_delete_sql = TRUE; - $sql = $this->delete($table, '', NULL, $reset); - $this->return_delete_sql = FALSE; - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Delete - * - * Compiles a delete string and runs the query - * - * @param mixed the table(s) to delete from. String or array - * @param mixed the where clause - * @param mixed the limit clause - * @param bool - * @return mixed - */ - public function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - if ($table === '') - { - if ( ! isset($this->qb_from[0])) - { - return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE; - } - - $table = $this->qb_from[0]; - } - elseif (is_array($table)) - { - empty($where) && $reset_data = FALSE; - - foreach ($table as $single_table) - { - $this->delete($single_table, $where, $limit, $reset_data); - } - - return; - } - else - { - $table = $this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - if ($where !== '') - { - $this->where($where); - } - - if ( ! empty($limit)) - { - $this->limit($limit); - } - - if (count($this->qb_where) === 0) - { - return ($this->db_debug) ? $this->display_error('db_del_must_use_where') : FALSE; - } - - $sql = $this->_delete($table); - if ($reset_data) - { - $this->_reset_write(); - } - - return ($this->return_delete_sql === TRUE) ? $sql : $this->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string the table name - * @return string - */ - protected function _delete($table) - { - return 'DELETE FROM '.$table.$this->_compile_wh('qb_where') - .($this->qb_limit ? ' LIMIT '.$this->qb_limit : ''); - } - - // -------------------------------------------------------------------- - - /** - * DB Prefix - * - * Prepends a database prefix if one exists in configuration - * - * @param string the table - * @return string - */ - public function dbprefix($table = '') - { - if ($table === '') - { - $this->display_error('db_table_name_required'); - } - - return $this->dbprefix.$table; - } - - // -------------------------------------------------------------------- - - /** - * Set DB Prefix - * - * Set's the DB Prefix to something new without needing to reconnect - * - * @param string the prefix - * @return string - */ - public function set_dbprefix($prefix = '') - { - return $this->dbprefix = $prefix; - } - - // -------------------------------------------------------------------- - - /** - * Track Aliases - * - * Used to track SQL statements written with aliased tables. - * - * @param string The table to inspect - * @return string - */ - protected function _track_aliases($table) - { - if (is_array($table)) - { - foreach ($table as $t) - { - $this->_track_aliases($t); - } - return; - } - - // Does the string contain a comma? If so, we need to separate - // the string into discreet statements - if (strpos($table, ',') !== FALSE) - { - return $this->_track_aliases(explode(',', $table)); - } - - // if a table alias is used we can recognize it by a space - if (strpos($table, ' ') !== FALSE) - { - // if the alias is written with the AS keyword, remove it - $table = preg_replace('/\s+AS\s+/i', ' ', $table); - - // Grab the alias - $table = trim(strrchr($table, ' ')); - - // Store the alias, if it doesn't already exist - if ( ! in_array($table, $this->qb_aliased_tables)) - { - $this->qb_aliased_tables[] = $table; - } - } - } - - // -------------------------------------------------------------------- - - /** - * Compile the SELECT statement - * - * Generates a query string based on which functions were used. - * Should not be called directly. - * - * @param bool $select_override - * @return string - */ - protected function _compile_select($select_override = FALSE) - { - // Combine any cached components with the current statements - $this->_merge_cache(); - - // Write the "select" portion of the query - if ($select_override !== FALSE) - { - $sql = $select_override; - } - else - { - $sql = ( ! $this->qb_distinct) ? 'SELECT ' : 'SELECT DISTINCT '; - - if (count($this->qb_select) === 0) - { - $sql .= '*'; - } - else - { - // Cycle through the "select" portion of the query and prep each column name. - // The reason we protect identifiers here rather than in the select() function - // is because until the user calls the from() function we don't know if there are aliases - foreach ($this->qb_select as $key => $val) - { - $no_escape = isset($this->qb_no_escape[$key]) ? $this->qb_no_escape[$key] : NULL; - $this->qb_select[$key] = $this->protect_identifiers($val, FALSE, $no_escape); - } - - $sql .= implode(', ', $this->qb_select); - } - } - - // Write the "FROM" portion of the query - if (count($this->qb_from) > 0) - { - $sql .= "\nFROM ".$this->_from_tables(); - } - - // Write the "JOIN" portion of the query - if (count($this->qb_join) > 0) - { - $sql .= "\n".implode("\n", $this->qb_join); - } - - $sql .= $this->_compile_wh('qb_where') - .$this->_compile_group_by() - .$this->_compile_wh('qb_having') - .$this->_compile_order_by(); // ORDER BY - - // LIMIT - if ($this->qb_limit) - { - return $this->_limit($sql."\n"); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Compile WHERE, HAVING statements - * - * Escapes identifiers in WHERE and HAVING statements at execution time. - * - * Required so that aliases are tracked properly, regardless of whether - * where(), or_where(), having(), or_having are called prior to from(), - * join() and dbprefix is added only if needed. - * - * @param string $qb_key 'qb_where' or 'qb_having' - * @return string SQL statement - */ - protected function _compile_wh($qb_key) - { - if (count($this->$qb_key) > 0) - { - for ($i = 0, $c = count($this->$qb_key); $i < $c; $i++) - { - // Is this condition already compiled? - if (is_string($this->{$qb_key}[$i])) - { - continue; - } - elseif ($this->{$qb_key}[$i]['escape'] === FALSE) - { - $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition']; - continue; - } - - // Split multiple conditions - $conditions = preg_split( - '/((?:^|\s+)AND\s+|(?:^|\s+)OR\s+)/i', - $this->{$qb_key}[$i]['condition'], - -1, - PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY - ); - - for ($ci = 0, $cc = count($conditions); $ci < $cc; $ci++) - { - if (($op = $this->_get_operator($conditions[$ci])) === FALSE - OR ! preg_match('/^(\(?)(.*)('.preg_quote($op, '/').')\s*(.*(? '(test <= foo)', /* the whole thing */ - // 1 => '(', /* optional */ - // 2 => 'test', /* the field name */ - // 3 => ' <= ', /* $op */ - // 4 => 'foo', /* optional, if $op is e.g. 'IS NULL' */ - // 5 => ')' /* optional */ - // ); - - if ( ! empty($matches[4])) - { - $this->_is_literal($matches[4]) OR $matches[4] = $this->protect_identifiers(trim($matches[4])); - $matches[4] = ' '.$matches[4]; - } - - $conditions[$ci] = $matches[1].$this->protect_identifiers(trim($matches[2])) - .' '.trim($matches[3]).$matches[4].$matches[5]; - } - - $this->{$qb_key}[$i] = implode('', $conditions); - } - - return ($qb_key === 'qb_having' ? "\nHAVING " : "\nWHERE ") - .implode("\n", $this->$qb_key); - } - - return ''; - } - - // -------------------------------------------------------------------- - - /** - * Compile GROUP BY - * - * Escapes identifiers in GROUP BY statements at execution time. - * - * Required so that aliases are tracked properly, regardless of wether - * group_by() is called prior to from(), join() and dbprefix is added - * only if needed. - * - * @return string SQL statement - */ - protected function _compile_group_by() - { - if (count($this->qb_groupby) > 0) - { - for ($i = 0, $c = count($this->qb_groupby); $i < $c; $i++) - { - // Is it already compiled? - if (is_string($this->qb_groupby[$i])) - { - continue; - } - - $this->qb_groupby[$i] = ($this->qb_groupby[$i]['escape'] === FALSE OR $this->_is_literal($this->qb_groupby[$i]['field'])) - ? $this->qb_groupby[$i]['field'] - : $this->protect_identifiers($this->qb_groupby[$i]['field']); - } - - return "\nGROUP BY ".implode(', ', $this->qb_groupby); - } - - return ''; - } - - // -------------------------------------------------------------------- - - /** - * Compile ORDER BY - * - * Escapes identifiers in ORDER BY statements at execution time. - * - * Required so that aliases are tracked properly, regardless of wether - * order_by() is called prior to from(), join() and dbprefix is added - * only if needed. - * - * @return string SQL statement - */ - protected function _compile_order_by() - { - if (is_array($this->qb_orderby) && count($this->qb_orderby) > 0) - { - for ($i = 0, $c = count($this->qb_orderby); $i < $c; $i++) - { - if ($this->qb_orderby[$i]['escape'] !== FALSE && ! $this->_is_literal($this->qb_orderby[$i]['field'])) - { - $this->qb_orderby[$i]['field'] = $this->protect_identifiers($this->qb_orderby[$i]['field']); - } - - $this->qb_orderby[$i] = $this->qb_orderby[$i]['field'].$this->qb_orderby[$i]['direction']; - } - - return $this->qb_orderby = "\nORDER BY ".implode(', ', $this->qb_orderby); - } - elseif (is_string($this->qb_orderby)) - { - return $this->qb_orderby; - } - - return ''; - } - - // -------------------------------------------------------------------- - - /** - * Object to Array - * - * Takes an object as input and converts the class variables to array key/vals - * - * @param object - * @return array - */ - protected function _object_to_array($object) - { - if ( ! is_object($object)) - { - return $object; - } - - $array = array(); - foreach (get_object_vars($object) as $key => $val) - { - // There are some built in keys we need to ignore for this conversion - if ( ! is_object($val) && ! is_array($val) && $key !== '_parent_name') - { - $array[$key] = $val; - } - } - - return $array; - } - - // -------------------------------------------------------------------- - - /** - * Object to Array - * - * Takes an object as input and converts the class variables to array key/vals - * - * @param object - * @return array - */ - protected function _object_to_array_batch($object) - { - if ( ! is_object($object)) - { - return $object; - } - - $array = array(); - $out = get_object_vars($object); - $fields = array_keys($out); - - foreach ($fields as $val) - { - // There are some built in keys we need to ignore for this conversion - if ($val !== '_parent_name') - { - $i = 0; - foreach ($out[$val] as $data) - { - $array[$i++][$val] = $data; - } - } - } - - return $array; - } - - // -------------------------------------------------------------------- - - /** - * Start Cache - * - * Starts QB caching - * - * @return FW_DB_query_builder - */ - public function start_cache() - { - $this->qb_caching = TRUE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Stop Cache - * - * Stops QB caching - * - * @return FW_DB_query_builder - */ - public function stop_cache() - { - $this->qb_caching = FALSE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Flush Cache - * - * Empties the QB cache - * - * @return FW_DB_query_builder - */ - public function flush_cache() - { - $this->_reset_run(array( - 'qb_cache_select' => array(), - 'qb_cache_from' => array(), - 'qb_cache_join' => array(), - 'qb_cache_where' => array(), - 'qb_cache_groupby' => array(), - 'qb_cache_having' => array(), - 'qb_cache_orderby' => array(), - 'qb_cache_set' => array(), - 'qb_cache_exists' => array(), - 'qb_cache_no_escape' => array() - )); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Merge Cache - * - * When called, this function merges any cached QB arrays with - * locally called ones. - * - * @return void - */ - protected function _merge_cache() - { - if (count($this->qb_cache_exists) === 0) - { - return; - } - elseif (in_array('select', $this->qb_cache_exists, TRUE)) - { - $qb_no_escape = $this->qb_cache_no_escape; - } - - foreach (array_unique($this->qb_cache_exists) as $val) // select, from, etc. - { - $qb_variable = 'qb_'.$val; - $qb_cache_var = 'qb_cache_'.$val; - $qb_new = $this->$qb_cache_var; - - for ($i = 0, $c = count($this->$qb_variable); $i < $c; $i++) - { - if ( ! in_array($this->{$qb_variable}[$i], $qb_new, TRUE)) - { - $qb_new[] = $this->{$qb_variable}[$i]; - if ($val === 'select') - { - $qb_no_escape[] = $this->qb_no_escape[$i]; - } - } - } - - $this->$qb_variable = $qb_new; - if ($val === 'select') - { - $this->qb_no_escape = $qb_no_escape; - } - } - - // If we are "protecting identifiers" we need to examine the "from" - // portion of the query to determine if there are any aliases - if ($this->_protect_identifiers === TRUE && count($this->qb_cache_from) > 0) - { - $this->_track_aliases($this->qb_from); - } - } - - // -------------------------------------------------------------------- - - /** - * Is literal - * - * Determines if a string represents a literal value or a field name - * - * @param string $str - * @return bool - */ - protected function _is_literal($str) - { - $str = trim($str); - - if (empty($str) OR ctype_digit($str) OR (string) (float) $str === $str OR in_array(strtoupper($str), array('TRUE', 'FALSE'), TRUE)) - { - return TRUE; - } - - static $_str; - - if (empty($_str)) - { - $_str = ($this->_escape_char !== '"') - ? array('"', "'") : array("'"); - } - - return in_array($str[0], $_str, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Reset Query Builder values. - * - * Publicly-visible method to reset the QB values. - * - * @return FW_DB_query_builder - */ - public function reset_query() - { - $this->_reset_select(); - $this->_reset_write(); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Resets the query builder values. Called by the get() function - * - * @param array An array of fields to reset - * @return void - */ - protected function _reset_run($qb_reset_items) - { - foreach ($qb_reset_items as $item => $default_value) - { - $this->$item = $default_value; - } - } - - // -------------------------------------------------------------------- - - /** - * Resets the query builder values. Called by the get() function - * - * @return void - */ - protected function _reset_select() - { - $this->_reset_run(array( - 'qb_select' => array(), - 'qb_from' => array(), - 'qb_join' => array(), - 'qb_where' => array(), - 'qb_groupby' => array(), - 'qb_having' => array(), - 'qb_orderby' => array(), - 'qb_aliased_tables' => array(), - 'qb_no_escape' => array(), - 'qb_distinct' => FALSE, - 'qb_limit' => FALSE, - 'qb_offset' => FALSE - )); - } - - // -------------------------------------------------------------------- - - /** - * Resets the query builder "write" values. - * - * Called by the insert() update() insert_batch() update_batch() and delete() functions - * - * @return void - */ - protected function _reset_write() - { - $this->_reset_run(array( - 'qb_set' => array(), - 'qb_from' => array(), - 'qb_join' => array(), - 'qb_where' => array(), - 'qb_orderby' => array(), - 'qb_keys' => array(), - 'qb_limit' => FALSE - )); - } - -} diff --git a/src/Database/DB_result.php b/src/Database/DB_result.php deleted file mode 100644 index 7882a2e..0000000 --- a/src/Database/DB_result.php +++ /dev/null @@ -1,666 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Result Class - * - * This is the platform-independent result class. - * This class will not be called directly. Rather, the adapter - * class for the specific database will extend and instantiate it. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_result { - - /** - * Connection ID - * - * @var resource|object - */ - public $conn_id; - - /** - * Result ID - * - * @var resource|object - */ - public $result_id; - - /** - * Result Array - * - * @var array[] - */ - public $result_array = array(); - - /** - * Result Object - * - * @var object[] - */ - public $result_object = array(); - - /** - * Custom Result Object - * - * @var object[] - */ - public $custom_result_object = array(); - - /** - * Current Row index - * - * @var int - */ - public $current_row = 0; - - /** - * Number of rows - * - * @var int - */ - public $num_rows; - - /** - * Row data - * - * @var array - */ - public $row_data; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param object $driver_object - * @return void - */ - public function __construct(&$driver_object) - { - $this->conn_id = $driver_object->conn_id; - $this->result_id = $driver_object->result_id; - } - - // -------------------------------------------------------------------- - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - if (is_int($this->num_rows)) - { - return $this->num_rows; - } - elseif (count($this->result_array) > 0) - { - return $this->num_rows = count($this->result_array); - } - elseif (count($this->result_object) > 0) - { - return $this->num_rows = count($this->result_object); - } - - return $this->num_rows = count($this->result_array()); - } - - // -------------------------------------------------------------------- - - /** - * Query result. Acts as a wrapper function for the following functions. - * - * @param string $type 'object', 'array' or a custom class name - * @return array - */ - public function result($type = 'object') - { - if ($type === 'array') - { - return $this->result_array(); - } - elseif ($type === 'object') - { - return $this->result_object(); - } - else - { - return $this->custom_result_object($type); - } - } - - // -------------------------------------------------------------------- - - /** - * Custom query result. - * - * @param string $class_name - * @return array - */ - public function custom_result_object($class_name) - { - if (isset($this->custom_result_object[$class_name])) - { - return $this->custom_result_object[$class_name]; - } - elseif ( ! $this->result_id OR $this->num_rows === 0) - { - return array(); - } - - // Don't fetch the result set again if we already have it - $_data = NULL; - if (($c = count($this->result_array)) > 0) - { - $_data = 'result_array'; - } - elseif (($c = count($this->result_object)) > 0) - { - $_data = 'result_object'; - } - - if ($_data !== NULL) - { - for ($i = 0; $i < $c; $i++) - { - $this->custom_result_object[$class_name][$i] = new $class_name(); - - foreach ($this->{$_data}[$i] as $key => $value) - { - $this->custom_result_object[$class_name][$i]->$key = $value; - } - } - - return $this->custom_result_object[$class_name]; - } - - is_null($this->row_data) OR $this->data_seek(0); - $this->custom_result_object[$class_name] = array(); - - while ($row = $this->_fetch_object($class_name)) - { - $this->custom_result_object[$class_name][] = $row; - } - - return $this->custom_result_object[$class_name]; - } - - // -------------------------------------------------------------------- - - /** - * Query result. "object" version. - * - * @return array - */ - public function result_object() - { - if (count($this->result_object) > 0) - { - return $this->result_object; - } - - // In the event that query caching is on, the result_id variable - // will not be a valid resource so we'll simply return an empty - // array. - if ( ! $this->result_id OR $this->num_rows === 0) - { - return array(); - } - - if (($c = count($this->result_array)) > 0) - { - for ($i = 0; $i < $c; $i++) - { - $this->result_object[$i] = (object) $this->result_array[$i]; - } - - return $this->result_object; - } - - is_null($this->row_data) OR $this->data_seek(0); - while ($row = $this->_fetch_object()) - { - $this->result_object[] = $row; - } - - return $this->result_object; - } - - // -------------------------------------------------------------------- - - /** - * Query result. "array" version. - * - * @return array - */ - public function result_array() - { - if (count($this->result_array) > 0) - { - return $this->result_array; - } - - // In the event that query caching is on, the result_id variable - // will not be a valid resource so we'll simply return an empty - // array. - if ( ! $this->result_id OR $this->num_rows === 0) - { - return array(); - } - - if (($c = count($this->result_object)) > 0) - { - for ($i = 0; $i < $c; $i++) - { - $this->result_array[$i] = (array) $this->result_object[$i]; - } - - return $this->result_array; - } - - is_null($this->row_data) OR $this->data_seek(0); - while ($row = $this->_fetch_assoc()) - { - $this->result_array[] = $row; - } - - return $this->result_array; - } - - // -------------------------------------------------------------------- - - /** - * Row - * - * A wrapper method. - * - * @param mixed $n - * @param string $type 'object' or 'array' - * @return mixed - */ - public function row($n = 0, $type = 'object') - { - if ( ! is_numeric($n)) - { - // We cache the row data for subsequent uses - is_array($this->row_data) OR $this->row_data = $this->row_array(0); - - // array_key_exists() instead of isset() to allow for NULL values - if (empty($this->row_data) OR ! array_key_exists($n, $this->row_data)) - { - return NULL; - } - - return $this->row_data[$n]; - } - - if ($type === 'object') return $this->row_object($n); - elseif ($type === 'array') return $this->row_array($n); - else return $this->custom_row_object($n, $type); - } - - // -------------------------------------------------------------------- - - /** - * Assigns an item into a particular column slot - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function set_row($key, $value = NULL) - { - // We cache the row data for subsequent uses - if ( ! is_array($this->row_data)) - { - $this->row_data = $this->row_array(0); - } - - if (is_array($key)) - { - foreach ($key as $k => $v) - { - $this->row_data[$k] = $v; - } - return; - } - - if ($key !== '' && $value !== NULL) - { - $this->row_data[$key] = $value; - } - } - - // -------------------------------------------------------------------- - - /** - * Returns a single result row - custom object version - * - * @param int $n - * @param string $type - * @return object - */ - public function custom_row_object($n, $type) - { - isset($this->custom_result_object[$type]) OR $this->custom_result_object($type); - - if (count($this->custom_result_object[$type]) === 0) - { - return NULL; - } - - if ($n !== $this->current_row && isset($this->custom_result_object[$type][$n])) - { - $this->current_row = $n; - } - - return $this->custom_result_object[$type][$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns a single result row - object version - * - * @param int $n - * @return object - */ - public function row_object($n = 0) - { - $result = $this->result_object(); - if (count($result) === 0) - { - return NULL; - } - - if ($n !== $this->current_row && isset($result[$n])) - { - $this->current_row = $n; - } - - return $result[$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns a single result row - array version - * - * @param int $n - * @return array - */ - public function row_array($n = 0) - { - $result = $this->result_array(); - if (count($result) === 0) - { - return NULL; - } - - if ($n !== $this->current_row && isset($result[$n])) - { - $this->current_row = $n; - } - - return $result[$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "first" row - * - * @param string $type - * @return mixed - */ - public function first_row($type = 'object') - { - $result = $this->result($type); - return (count($result) === 0) ? NULL : $result[0]; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "last" row - * - * @param string $type - * @return mixed - */ - public function last_row($type = 'object') - { - $result = $this->result($type); - return (count($result) === 0) ? NULL : $result[count($result) - 1]; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "next" row - * - * @param string $type - * @return mixed - */ - public function next_row($type = 'object') - { - $result = $this->result($type); - if (count($result) === 0) - { - return NULL; - } - - return isset($result[$this->current_row + 1]) - ? $result[++$this->current_row] - : NULL; - } - - // -------------------------------------------------------------------- - - /** - * Returns the "previous" row - * - * @param string $type - * @return mixed - */ - public function previous_row($type = 'object') - { - $result = $this->result($type); - if (count($result) === 0) - { - return NULL; - } - - if (isset($result[$this->current_row - 1])) - { - --$this->current_row; - } - return $result[$this->current_row]; - } - - // -------------------------------------------------------------------- - - /** - * Returns an unbuffered row and move pointer to next row - * - * @param string $type 'array', 'object' or a custom class name - * @return mixed - */ - public function unbuffered_row($type = 'object') - { - if ($type === 'array') - { - return $this->_fetch_assoc(); - } - elseif ($type === 'object') - { - return $this->_fetch_object(); - } - - return $this->_fetch_object($type); - } - - // -------------------------------------------------------------------- - - /** - * The following methods are normally overloaded by the identically named - * methods in the platform-specific driver -- except when query caching - * is used. When caching is enabled we do not load the other driver. - * These functions are primarily here to prevent undefined function errors - * when a cached result object is in use. They are not otherwise fully - * operational due to the unavailability of the database resource IDs with - * cached results. - */ - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * Overridden by driver result classes. - * - * @return int - */ - public function num_fields() - { - return 0; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names. - * - * Overridden by driver result classes. - * - * @return array - */ - public function list_fields() - { - return array(); - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data. - * - * Overridden by driver result classes. - * - * @return array - */ - public function field_data() - { - return array(); - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * Overridden by driver result classes. - * - * @return void - */ - public function free_result() - { - $this->result_id = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * Overridden by driver result classes. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array. - * - * Overridden by driver result classes. - * - * @return array - */ - protected function _fetch_assoc() - { - return array(); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object. - * - * Overridden by driver result classes. - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return array(); - } - -} diff --git a/src/Database/DB_utility.php b/src/Database/DB_utility.php deleted file mode 100644 index 321c83a..0000000 --- a/src/Database/DB_utility.php +++ /dev/null @@ -1,434 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Helpers; -use FuzeWorks\Libraries; -use Fuzeworks\Factory; -use FuzeWorks\Exception\DatabaseException; - -/** - * Database Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -abstract class FW_DB_utility { - - /** - * Database object - * - * @var object - */ - protected $db; - - // -------------------------------------------------------------------- - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = FALSE; - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = FALSE; - - /** - * REPAIR TABLE statement - * - * @var string - */ - protected $_repair_table = FALSE; - - /** - * The FuzeWorks factory class - * - * @var Fuzeworks\Factory; - */ - private $factory; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - $this->db =& $db; - $this->factory = Factory::getInstance(); - Logger::log('Database Utility Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * List databases - * - * @return array - */ - public function list_databases() - { - // Is there a cached result? - if (isset($this->db->data_cache['db_names'])) - { - return $this->db->data_cache['db_names']; - } - elseif ($this->_list_databases === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $this->db->data_cache['db_names'] = array(); - - $query = $this->db->query($this->_list_databases); - if ($query === FALSE) - { - return $this->db->data_cache['db_names']; - } - - for ($i = 0, $query = $query->result_array(), $c = count($query); $i < $c; $i++) - { - $this->db->data_cache['db_names'][] = current($query[$i]); - } - - return $this->db->data_cache['db_names']; - } - - // -------------------------------------------------------------------- - - /** - * Determine if a particular database exists - * - * @param string $database_name - * @return bool - */ - public function database_exists($database_name) - { - return in_array($database_name, $this->list_databases()); - } - - // -------------------------------------------------------------------- - - /** - * Optimize Table - * - * @param string $table_name - * @return mixed - */ - public function optimize_table($table_name) - { - if ($this->_optimize_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name))); - if ($query !== FALSE) - { - $query = $query->result_array(); - return current($query); - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Optimize Database - * - * @return mixed - */ - public function optimize_database() - { - if ($this->_optimize_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $result = array(); - foreach ($this->db->list_tables() as $table_name) - { - $res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name))); - if (is_bool($res)) - { - return $res; - } - - // Build the result array... - $res = $res->result_array(); - $res = current($res); - $key = str_replace($this->db->database.'.', '', current($res)); - $keys = array_keys($res); - unset($res[$keys[0]]); - - $result[$key] = $res; - } - - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Repair Table - * - * @param string $table_name - * @return mixed - */ - public function repair_table($table_name) - { - if ($this->_repair_table === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - $query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name))); - if (is_bool($query)) - { - return $query; - } - - $query = $query->result_array(); - return current($query); - } - - // -------------------------------------------------------------------- - - /** - * Generate CSV from a query result object - * - * @param object $query Query result object - * @param string $delim Delimiter (default: ,) - * @param string $newline Newline character (default: \n) - * @param string $enclosure Enclosure (default: ") - * @return string - */ - public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"') - { - if ( ! is_object($query) OR ! method_exists($query, 'list_fields')) - { - throw new DatabaseException('You must submit a valid result object', 1); - } - - $out = ''; - // First generate the headings from the table column names - foreach ($query->list_fields() as $name) - { - $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim; - } - - $out = substr($out, 0, -strlen($delim)).$newline; - - // Next blast through the result array and build out the rows - while ($row = $query->unbuffered_row('array')) - { - $line = array(); - foreach ($row as $item) - { - $line[] = $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure; - } - $out .= implode($delim, $line).$newline; - } - - return $out; - } - - // -------------------------------------------------------------------- - - /** - * Generate XML data from a query result object - * - * @param object $query Query result object - * @param array $params Any preferences - * @return string - */ - public function xml_from_result($query, $params = array()) - { - if ( ! is_object($query) OR ! method_exists($query, 'list_fields')) - { - throw new DatabaseException('You must submit a valid result object', 1); - } - - // Set our default values - foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val) - { - if ( ! isset($params[$key])) - { - $params[$key] = $val; - } - } - - // Create variables for convenience - extract($params); - - // Load the xml helper - $this->factory->helpers->load('xml'); - - // Generate the result - $xml = '<'.$root.'>'.$newline; - while ($row = $query->unbuffered_row()) - { - $xml .= $tab.'<'.$element.'>'.$newline; - foreach ($row as $key => $val) - { - $xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).''.$newline; - } - $xml .= $tab.''.$newline; - } - - return $xml.''.$newline; - } - - // -------------------------------------------------------------------- - - /** - * Database Backup - * - * @param array $params - * @return string - */ - public function backup($params = array()) - { - // If the parameters have not been submitted as an - // array then we know that it is simply the table - // name, which is a valid short cut. - if (is_string($params)) - { - $params = array('tables' => $params); - } - - // Set up our default preferences - $prefs = array( - 'tables' => array(), - 'ignore' => array(), - 'filename' => '', - 'format' => 'gzip', // gzip, zip, txt - 'add_drop' => TRUE, - 'add_insert' => TRUE, - 'newline' => "\n", - 'foreign_key_checks' => TRUE - ); - - // Did the user submit any preferences? If so set them.... - if (count($params) > 0) - { - foreach ($prefs as $key => $val) - { - if (isset($params[$key])) - { - $prefs[$key] = $params[$key]; - } - } - } - - // Are we backing up a complete database or individual tables? - // If no table names were submitted we'll fetch the entire table list - if (count($prefs['tables']) === 0) - { - $prefs['tables'] = $this->db->list_tables(); - } - - // Validate the format - if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE)) - { - $prefs['format'] = 'txt'; - } - - // Is the encoder supported? If not, we'll either issue an - // error or use plain text depending on the debug settings - if (($prefs['format'] === 'gzip' && ! function_exists('gzencode')) - OR ($prefs['format'] === 'zip' && ! function_exists('gzcompress'))) - { - if ($this->db->db_debug) - { - return $this->db->display_error('db_unsupported_compression'); - } - - $prefs['format'] = 'txt'; - } - - // Was a Zip file requested? - if ($prefs['format'] === 'zip') - { - // Set the filename if not provided (only needed with Zip files) - if ($prefs['filename'] === '') - { - $prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database) - .date('Y-m-d_H-i', time()).'.sql'; - } - else - { - // If they included the .zip file extension we'll remove it - if (preg_match('|.+?\.zip$|', $prefs['filename'])) - { - $prefs['filename'] = str_replace('.zip', '', $prefs['filename']); - } - - // Tack on the ".sql" file extension if needed - if ( ! preg_match('|.+?\.sql$|', $prefs['filename'])) - { - $prefs['filename'] .= '.sql'; - } - } - - // Load the Zip class and output it - $zip = Libraries::get('zip'); - $zip->add_data($prefs['filename'], $this->_backup($prefs)); - return $zip->get_zip(); - } - elseif ($prefs['format'] === 'txt') // Was a text file requested? - { - return $this->_backup($prefs); - } - elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested? - { - return gzencode($this->_backup($prefs)); - } - - return; - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_driver.php b/src/Database/drivers/cubrid/cubrid_driver.php deleted file mode 100644 index ac3c141..0000000 --- a/src/Database/drivers/cubrid/cubrid_driver.php +++ /dev/null @@ -1,401 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'cubrid'; - - /** - * Auto-commit flag - * - * @var bool - */ - public $auto_commit = TRUE; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:[^:]*:[^:]*:(\?.+)?$/', $this->dsn, $matches)) - { - if (stripos($matches[2], 'autocommit=off') !== FALSE) - { - $this->auto_commit = FALSE; - } - } - else - { - // If no port is defined by the user, use the default value - empty($this->port) OR $this->port = 33000; - } - } - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:([^:]*):([^:]*):(\?.+)?$/', $this->dsn, $matches)) - { - $func = ($persistent !== TRUE) ? 'cubrid_connect_with_url' : 'cubrid_pconnect_with_url'; - return ($matches[2] === '' && $matches[3] === '' && $this->username !== '' && $this->password !== '') - ? $func($this->dsn, $this->username, $this->password) - : $func($this->dsn); - } - - $func = ($persistent !== TRUE) ? 'cubrid_connect' : 'cubrid_pconnect'; - return ($this->username !== '') - ? $func($this->hostname, $this->port, $this->database, $this->username, $this->password) - : $func($this->hostname, $this->port, $this->database); - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout - * - * @return void - */ - public function reconnect() - { - if (cubrid_ping($this->conn_id) === FALSE) - { - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - return ( ! $this->conn_id OR ($version = cubrid_get_server_info($this->conn_id)) === FALSE) - ? FALSE - : $this->data_cache['version'] = $version; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return cubrid_query($sql, $this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - if (($autocommit = cubrid_get_autocommit($this->conn_id)) === NULL) - { - return FALSE; - } - elseif ($autocommit === TRUE) - { - return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE); - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if ( ! cubrid_commit($this->conn_id)) - { - return FALSE; - } - - if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id)) - { - return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE); - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if ( ! cubrid_rollback($this->conn_id)) - { - return FALSE; - } - - if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id)) - { - cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE); - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return cubrid_real_escape_string($str, $this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return cubrid_affected_rows(); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return cubrid_insert_id($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES'; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => cubrid_errno($this->conn_id), 'message' => cubrid_error($this->conn_id)); - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - cubrid_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_forge.php b/src/Database/drivers/cubrid/cubrid_forge.php deleted file mode 100644 index 0063235..0000000 --- a/src/Database/drivers/cubrid/cubrid_forge.php +++ /dev/null @@ -1,224 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_forge extends FW_DB_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SHORT' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'BIGINT' => 'NUMERIC', - 'FLOAT' => 'DOUBLE', - 'REAL' => 'DOUBLE' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $sqls[] = $sql.' CHANGE '.$field[$i]['_literal']; - } - else - { - $alter_type = empty($field[$i]['new_name']) ? ' MODIFY ' : ' CHANGE '; - $sqls[] = $sql.$alter_type.$this->_process_column($field[$i]); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_result.php b/src/Database/drivers/cubrid/cubrid_result.php deleted file mode 100644 index ceff132..0000000 --- a/src/Database/drivers/cubrid/cubrid_result.php +++ /dev/null @@ -1,174 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = cubrid_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return cubrid_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - return cubrid_column_names($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = cubrid_field_name($this->result_id, $i); - $retval[$i]->type = cubrid_field_type($this->result_id, $i); - $retval[$i]->max_length = cubrid_field_len($this->result_id, $i); - $retval[$i]->primary_key = (int) (strpos(cubrid_field_flags($this->result_id, $i), 'primary_key') !== FALSE); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id) OR - (get_resource_type($this->result_id) === 'Unknown' && preg_match('/Resource id #/', strval($this->result_id)))) - { - cubrid_close_request($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return cubrid_data_seek($this->result_id, $n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return cubrid_fetch_assoc($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return cubrid_fetch_object($this->result_id, $class_name); - } - -} diff --git a/src/Database/drivers/cubrid/cubrid_utility.php b/src/Database/drivers/cubrid/cubrid_utility.php deleted file mode 100644 index a0bc94b..0000000 --- a/src/Database/drivers/cubrid/cubrid_utility.php +++ /dev/null @@ -1,76 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * CUBRID Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_cubrid_utility extends FW_DB_utility { - - /** - * List databases - * - * @return array - */ - public function list_databases() - { - if (isset($this->db->data_cache['db_names'])) - { - return $this->db->data_cache['db_names']; - } - - return $this->db->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * CUBRID Export - * - * @param array Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // No SQL based support in CUBRID as of version 8.4.0. Database or - // table backup can be performed using CUBRID Manager - // database administration tool. - return $this->db->display_error('db_unsupported_feature'); - } -} diff --git a/src/Database/drivers/ibase/ibase_driver.php b/src/Database/drivers/ibase/ibase_driver.php deleted file mode 100644 index 099c92d..0000000 --- a/src/Database/drivers/ibase/ibase_driver.php +++ /dev/null @@ -1,392 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Firebird/Interbase Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'ibase'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RAND()', 'RAND()'); - - /** - * IBase Transaction status flag - * - * @var resource - */ - protected $_ibase_trans; - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - return ($persistent === TRUE) - ? ibase_pconnect($this->hostname.':'.$this->database, $this->username, $this->password, $this->char_set) - : ibase_connect($this->hostname.':'.$this->database, $this->username, $this->password, $this->char_set); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if (($service = ibase_service_attach($this->hostname, $this->username, $this->password))) - { - $this->data_cache['version'] = ibase_server_info($service, IBASE_SVC_SERVER_VERSION); - - // Don't keep the service open - ibase_service_detach($service); - return $this->data_cache['version']; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return ibase_query(isset($this->_ibase_trans) ? $this->_ibase_trans : $this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - if (($trans_handle = ibase_trans($this->conn_id)) === FALSE) - { - return FALSE; - } - - $this->_ibase_trans = $trans_handle; - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if (ibase_commit($this->_ibase_trans)) - { - $this->_ibase_trans = NULL; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if (ibase_rollback($this->_ibase_trans)) - { - $this->_ibase_trans = NULL; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return ibase_affected_rows($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @param string $generator_name - * @param int $inc_by - * @return int - */ - public function insert_id($generator_name, $inc_by = 0) - { - //If a generator hasn't been used before it will return 0 - return ibase_gen_id('"'.$generator_name.'"', $inc_by); - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT TRIM("RDB$RELATION_NAME") AS TABLE_NAME FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\''; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql.' AND TRIM("RDB$RELATION_NAME") AS TABLE_NAME LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT TRIM("RDB$FIELD_NAME") AS COLUMN_NAME FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "rfields"."RDB$FIELD_NAME" AS "name", - CASE "fields"."RDB$FIELD_TYPE" - WHEN 7 THEN \'SMALLINT\' - WHEN 8 THEN \'INTEGER\' - WHEN 9 THEN \'QUAD\' - WHEN 10 THEN \'FLOAT\' - WHEN 11 THEN \'DFLOAT\' - WHEN 12 THEN \'DATE\' - WHEN 13 THEN \'TIME\' - WHEN 14 THEN \'CHAR\' - WHEN 16 THEN \'INT64\' - WHEN 27 THEN \'DOUBLE\' - WHEN 35 THEN \'TIMESTAMP\' - WHEN 37 THEN \'VARCHAR\' - WHEN 40 THEN \'CSTRING\' - WHEN 261 THEN \'BLOB\' - ELSE NULL - END AS "type", - "fields"."RDB$FIELD_LENGTH" AS "max_length", - "rfields"."RDB$DEFAULT_VALUE" AS "default" - FROM "RDB$RELATION_FIELDS" "rfields" - JOIN "RDB$FIELDS" "fields" ON "rfields"."RDB$FIELD_SOURCE" = "fields"."RDB$FIELD_NAME" - WHERE "rfields"."RDB$RELATION_NAME" = '.$this->escape($table).' - ORDER BY "rfields"."RDB$FIELD_POSITION"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => ibase_errcode(), 'message' => ibase_errmsg()); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // Limit clause depends on if Interbase or Firebird - if (stripos($this->version(), 'firebird') !== FALSE) - { - $select = 'FIRST '.$this->qb_limit - .($this->qb_offset ? ' SKIP '.$this->qb_offset : ''); - } - else - { - $select = 'ROWS ' - .($this->qb_offset ? $this->qb_offset.' TO '.($this->qb_limit + $this->qb_offset) : $this->qb_limit); - } - - return preg_replace('`SELECT`i', 'SELECT '.$select, $sql, 1); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - ibase_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/ibase/ibase_forge.php b/src/Database/drivers/ibase/ibase_forge.php deleted file mode 100644 index 1cc3b5b..0000000 --- a/src/Database/drivers/ibase/ibase_forge.php +++ /dev/null @@ -1,248 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Interbase/Firebird Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INTEGER' => 'INT64', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return string - */ - public function create_database($db_name) - { - // Firebird databases are flat files, so a path is required - - // Hostname is needed for remote access - empty($this->db->hostname) OR $db_name = $this->hostname.':'.$db_name; - - return parent::create_database('"'.$db_name.'"'); - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - if ( ! ibase_drop_db($this->conn_id)) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identififers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = 'UPDATE "RDB$RELATION_FIELDS" SET "RDB$NULL_FLAG" = ' - .($field[$i]['null'] === TRUE ? 'NULL' : '1') - .' WHERE "RDB$FIELD_NAME" = '.$this->db->escape($field[$i]['name']) - .' AND "RDB$RELATION_NAME" = '.$this->db->escape($table); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INT': - $attributes['TYPE'] = 'INTEGER'; - return; - case 'BIGINT': - $attributes['TYPE'] = 'INT64'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/ibase/ibase_result.php b/src/Database/drivers/ibase/ibase_result.php deleted file mode 100644 index 85b3219..0000000 --- a/src/Database/drivers/ibase/ibase_result.php +++ /dev/null @@ -1,158 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Interbase/Firebird Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_result extends FW_DB_result { - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return ibase_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $num_fields = $this->num_fields(); $i < $num_fields; $i++) - { - $info = ibase_field_info($this->result_id, $i); - $field_names[] = $info['name']; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $info = ibase_field_info($this->result_id, $i); - - $retval[$i] = new stdClass(); - $retval[$i]->name = $info['name']; - $retval[$i]->type = $info['type']; - $retval[$i]->max_length = $info['length']; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - ibase_free_result($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return ibase_fetch_assoc($this->result_id, IBASE_FETCH_BLOBS); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - $row = ibase_fetch_object($this->result_id, IBASE_FETCH_BLOBS); - - if ($class_name === 'stdClass' OR ! $row) - { - return $row; - } - - $class_name = new $class_name(); - foreach ($row as $key => $value) - { - $class_name->$key = $value; - } - - return $class_name; - } - -} diff --git a/src/Database/drivers/ibase/ibase_utility.php b/src/Database/drivers/ibase/ibase_utility.php deleted file mode 100644 index 39ec8b9..0000000 --- a/src/Database/drivers/ibase/ibase_utility.php +++ /dev/null @@ -1,66 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Interbase/Firebird Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_ibase_utility extends FW_DB_utility { - - /** - * Export - * - * @param string $filename - * @return mixed - */ - protected function _backup($filename) - { - if ($service = ibase_service_attach($this->db->hostname, $this->db->username, $this->db->password)) - { - $res = ibase_backup($service, $this->db->database, $filename.'.fbk'); - - // Close the service connection - ibase_service_detach($service); - return $res; - } - - return FALSE; - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_driver.php b/src/Database/drivers/mysqli/mysqli_driver.php deleted file mode 100644 index 6193313..0000000 --- a/src/Database/drivers/mysqli/mysqli_driver.php +++ /dev/null @@ -1,543 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Core; - -/** - * MySQLi Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'mysqli'; - - /** - * Compression flag - * - * @var bool - */ - public $compress = FALSE; - - /** - * DELETE hack flag - * - * Whether to use the MySQL "delete hack" which allows the number - * of affected rows to be shown. Uses a preg_replace when enabled, - * adding a bit more processing to all queries. - * - * @var bool - */ - public $delete_hack = TRUE; - - /** - * Strict ON flag - * - * Whether we're running in strict SQL mode. - * - * @var bool - */ - public $stricton; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - // -------------------------------------------------------------------- - - /** - * MySQLi object - * - * Has to be preserved without being assigned to $conn_id. - * - * @var MySQLi - */ - protected $_mysqli; - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - // Do we have a socket path? - if ($this->hostname[0] === '/') - { - $hostname = NULL; - $port = NULL; - $socket = $this->hostname; - } - else - { - // Persistent connection support was added in PHP 5.3.0 - $hostname = ($persistent === TRUE && Core::isPHP('5.3')) - ? 'p:'.$this->hostname : $this->hostname; - $port = empty($this->port) ? NULL : $this->port; - $socket = NULL; - } - - $client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0; - $this->_mysqli = mysqli_init(); - - $this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10); - - if (isset($this->stricton)) - { - if ($this->stricton) - { - $this->_mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'); - } - else - { - $this->_mysqli->options(MYSQLI_INIT_COMMAND, - 'SET SESSION sql_mode = - REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( - @@sql_mode, - "STRICT_ALL_TABLES,", ""), - ",STRICT_ALL_TABLES", ""), - "STRICT_ALL_TABLES", ""), - "STRICT_TRANS_TABLES,", ""), - ",STRICT_TRANS_TABLES", ""), - "STRICT_TRANS_TABLES", "")' - ); - } - } - - if (is_array($this->encrypt)) - { - $ssl = array(); - empty($this->encrypt['ssl_key']) OR $ssl['key'] = $this->encrypt['ssl_key']; - empty($this->encrypt['ssl_cert']) OR $ssl['cert'] = $this->encrypt['ssl_cert']; - empty($this->encrypt['ssl_ca']) OR $ssl['ca'] = $this->encrypt['ssl_ca']; - empty($this->encrypt['ssl_capath']) OR $ssl['capath'] = $this->encrypt['ssl_capath']; - empty($this->encrypt['ssl_cipher']) OR $ssl['cipher'] = $this->encrypt['ssl_cipher']; - - if ( ! empty($ssl)) - { - if (isset($this->encrypt['ssl_verify'])) - { - if ($this->encrypt['ssl_verify']) - { - defined('MYSQLI_OPT_SSL_VERIFY_SERVER_CERT') && $this->_mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, TRUE); - } - // Apparently (when it exists), setting MYSQLI_OPT_SSL_VERIFY_SERVER_CERT - // to FALSE didn't do anything, so PHP 5.6.16 introduced yet another - // constant ... - // - // https://secure.php.net/ChangeLog-5.php#5.6.16 - // https://bugs.php.net/bug.php?id=68344 - elseif (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')) - { - $this->_mysqli->options(MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT, TRUE); - } - } - - $client_flags |= MYSQLI_CLIENT_SSL; - $this->_mysqli->ssl_set( - isset($ssl['key']) ? $ssl['key'] : NULL, - isset($ssl['cert']) ? $ssl['cert'] : NULL, - isset($ssl['ca']) ? $ssl['ca'] : NULL, - isset($ssl['capath']) ? $ssl['capath'] : NULL, - isset($ssl['cipher']) ? $ssl['cipher'] : NULL - ); - } - } - - if ($this->_mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags)) - { - // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails - if ( - ($client_flags & MYSQLI_CLIENT_SSL) - && version_compare($this->_mysqli->client_info, '5.7.3', '<=') - && empty($this->_mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_object()->Value) - ) - { - $this->_mysqli->close(); - $message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!'; - Logger::logError($message); - return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; - } - - return $this->_mysqli; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout - * - * @return void - */ - public function reconnect() - { - if ($this->conn_id !== FALSE && $this->conn_id->ping() === FALSE) - { - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Select the database - * - * @param string $database - * @return bool - */ - public function db_select($database = '') - { - if ($database === '') - { - $database = $this->database; - } - - if ($this->conn_id->select_db($database)) - { - $this->database = $database; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Set client character set - * - * @param string $charset - * @return bool - */ - protected function _db_set_charset($charset) - { - return $this->conn_id->set_charset($charset); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - return $this->data_cache['version'] = $this->conn_id->server_info; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return mixed - */ - protected function _execute($sql) - { - return $this->conn_id->query($this->_prep_query($sql)); - } - - // -------------------------------------------------------------------- - - /** - * Prep the query - * - * If needed, each database adapter can prep the query string - * - * @param string $sql an SQL query - * @return string - */ - protected function _prep_query($sql) - { - // mysqli_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack - // modifies the query so that it a proper number of affected rows is returned. - if ($this->delete_hack === TRUE && preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) - { - return trim($sql).' WHERE 1=1'; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - $this->conn_id->autocommit(FALSE); - return Core::isPHP('5.5') - ? $this->conn_id->begin_transaction() - : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if ($this->conn_id->commit()) - { - $this->conn_id->autocommit(TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if ($this->conn_id->rollback()) - { - $this->conn_id->autocommit(TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return $this->conn_id->real_escape_string($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return $this->conn_id->affected_rows; - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return $this->conn_id->insert_id; - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database); - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occurred. - * - * @return array - */ - public function error() - { - if ( ! empty($this->_mysqli->connect_errno)) - { - return array( - 'code' => $this->_mysqli->connect_errno, - 'message' => Core::isPHP('5.2.9') ? $this->_mysqli->connect_error : mysqli_connect_error() - ); - } - - return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error); - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - $this->conn_id->close(); - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_forge.php b/src/Database/drivers/mysqli/mysqli_forge.php deleted file mode 100644 index aac9099..0000000 --- a/src/Database/drivers/mysqli/mysqli_forge.php +++ /dev/null @@ -1,240 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * MySQLi Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_forge extends FW_DB_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s'; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT', - 'SMALLINT', - 'MEDIUMINT', - 'INT', - 'INTEGER', - 'BIGINT', - 'REAL', - 'DOUBLE', - 'DOUBLE PRECISION', - 'FLOAT', - 'DECIMAL', - 'NUMERIC' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * CREATE TABLE attributes - * - * @param array $attributes Associative array of table attributes - * @return string - */ - protected function _create_table_attr($attributes) - { - $sql = ''; - - foreach (array_keys($attributes) as $key) - { - if (is_string($key)) - { - $sql .= ' '.strtoupper($key).' = '.$attributes[$key]; - } - } - - if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) - { - $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set; - } - - if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE')) - { - $sql .= ' COLLATE = '.$this->db->dbcollat; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = ($alter_type === 'ADD') - ? "\n\tADD ".$field[$i]['_literal'] - : "\n\tMODIFY ".$field[$i]['_literal']; - } - else - { - if ($alter_type === 'ADD') - { - $field[$i]['_literal'] = "\n\tADD "; - } - else - { - $field[$i]['_literal'] = empty($field[$i]['new_name']) ? "\n\tMODIFY " : "\n\tCHANGE "; - } - - $field[$i] = $field[$i]['_literal'].$this->_process_column($field[$i]); - } - } - - return array($sql.implode(',', $field)); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .(empty($field['comment']) ? '' : ' COMMENT '.$field['comment']) - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_result.php b/src/Database/drivers/mysqli/mysqli_result.php deleted file mode 100644 index 6039764..0000000 --- a/src/Database/drivers/mysqli/mysqli_result.php +++ /dev/null @@ -1,182 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * MySQLi Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = $this->result_id->num_rows; - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return $this->result_id->field_count; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - $this->result_id->field_seek(0); - while ($field = $this->result_id->fetch_field()) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - $field_data = $this->result_id->fetch_fields(); - for ($i = 0, $c = count($field_data); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $field_data[$i]->name; - $retval[$i]->type = $field_data[$i]->type; - $retval[$i]->max_length = $field_data[$i]->max_length; - $retval[$i]->primary_key = (int) ($field_data[$i]->flags & 2); - $retval[$i]->default = $field_data[$i]->def; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_object($this->result_id)) - { - $this->result_id->free(); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return $this->result_id->data_seek($n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return $this->result_id->fetch_assoc(); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return $this->result_id->fetch_object($class_name); - } - -} diff --git a/src/Database/drivers/mysqli/mysqli_utility.php b/src/Database/drivers/mysqli/mysqli_utility.php deleted file mode 100644 index 0a0ab95..0000000 --- a/src/Database/drivers/mysqli/mysqli_utility.php +++ /dev/null @@ -1,209 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * MySQLi Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_mysqli_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'SHOW DATABASES'; - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = 'OPTIMIZE TABLE %s'; - - /** - * REPAIR TABLE statement - * - * @var string - */ - protected $_repair_table = 'REPAIR TABLE %s'; - - // -------------------------------------------------------------------- - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - if (count($params) === 0) - { - return FALSE; - } - - // Extract the prefs for simplicity - extract($params); - - // Build the output - $output = ''; - - // Do we need to include a statement to disable foreign key checks? - if ($foreign_key_checks === FALSE) - { - $output .= 'SET foreign_key_checks = 0;'.$newline; - } - - foreach ( (array) $tables as $table) - { - // Is the table in the "ignore" list? - if (in_array($table, (array) $ignore, TRUE)) - { - continue; - } - - // Get the table schema - $query = $this->db->query('SHOW CREATE TABLE '.$this->db->escape_identifiers($this->db->database.'.'.$table)); - - // No result means the table name was invalid - if ($query === FALSE) - { - continue; - } - - // Write out the table schema - $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline; - - if ($add_drop === TRUE) - { - $output .= 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table).';'.$newline.$newline; - } - - $i = 0; - $result = $query->result_array(); - foreach ($result[0] as $val) - { - if ($i++ % 2) - { - $output .= $val.';'.$newline.$newline; - } - } - - // If inserts are not needed we're done... - if ($add_insert === FALSE) - { - continue; - } - - // Grab all the data from the current table - $query = $this->db->query('SELECT * FROM '.$this->db->protect_identifiers($table)); - - if ($query->num_rows() === 0) - { - continue; - } - - // Fetch the field names and determine if the field is an - // integer type. We use this info to decide whether to - // surround the data with quotes or not - - $i = 0; - $field_str = ''; - $is_int = array(); - while ($field = $query->result_id->fetch_field()) - { - // Most versions of MySQL store timestamp as a string - $is_int[$i] = in_array(strtolower($field->type), - array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), - TRUE); - - // Create a string of field names - $field_str .= $this->db->escape_identifiers($field->name).', '; - $i++; - } - - // Trim off the end comma - $field_str = preg_replace('/, $/' , '', $field_str); - - // Build the insert string - foreach ($query->result_array() as $row) - { - $val_str = ''; - - $i = 0; - foreach ($row as $v) - { - // Is the value NULL? - if ($v === NULL) - { - $val_str .= 'NULL'; - } - else - { - // Escape the data if it's not an integer - $val_str .= ($is_int[$i] === FALSE) ? $this->db->escape($v) : $v; - } - - // Append a comma - $val_str .= ', '; - $i++; - } - - // Remove the comma at the end of the string - $val_str = preg_replace('/, $/' , '', $val_str); - - // Build the INSERT string - $output .= 'INSERT INTO '.$this->db->protect_identifiers($table).' ('.$field_str.') VALUES ('.$val_str.');'.$newline; - } - - $output .= $newline.$newline; - } - - // Do we need to include a statement to re-enable foreign key checks? - if ($foreign_key_checks === FALSE) - { - $output .= 'SET foreign_key_checks = 1;'.$newline; - } - - return $output; - } - -} diff --git a/src/Database/drivers/oci8/oci8_driver.php b/src/Database/drivers/oci8/oci8_driver.php deleted file mode 100644 index 9211f30..0000000 --- a/src/Database/drivers/oci8/oci8_driver.php +++ /dev/null @@ -1,680 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Core; - -/** - * oci8 Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ - -/** - * oci8 Database Adapter Class - * - * This is a modification of the DB_driver class to - * permit access to oracle databases - * - * @author Kelly McArdle - */ -class FW_DB_oci8_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'oci8'; - - /** - * Statement ID - * - * @var resource - */ - public $stmt_id; - - /** - * Cursor ID - * - * @var resource - */ - public $curs_id; - - /** - * Commit mode flag - * - * @var int - */ - - /** - * Limit used flag - * - * If we use LIMIT, we'll add a field that will - * throw off num_fields later. - * - * @var bool - */ - public $limit_used; - - // -------------------------------------------------------------------- - - /** - * Reset $stmt_id flag - * - * Used by stored_procedure() to prevent _execute() from - * re-setting the statement ID. - */ - protected $_reset_stmt_id = TRUE; - - /** - * List of reserved identifiers - * - * Identifiers that must NOT be escaped. - * - * @var string[] - */ - protected $_reserved_identifiers = array('*', 'rownum'); - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('ASC', 'ASC'); // not currently supported - - /** - * COUNT string - * - * @used-by FW_DB_driver::count_all() - * @used-by FW_DB_query_builder::count_all_results() - * - * @var string - */ - protected $_count_string = 'SELECT COUNT(1) AS '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - $valid_dsns = array( - 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS - // Easy Connect string (Oracle 10g+) - 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i', - 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora) - ); - - /* Space characters don't have any effect when actually - * connecting, but can be a hassle while validating the DSN. - */ - $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn); - - if ($this->dsn !== '') - { - foreach ($valid_dsns as $regexp) - { - if (preg_match($regexp, $this->dsn)) - { - return; - } - } - } - - // Legacy support for TNS in the hostname configuration field - $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname); - if (preg_match($valid_dsns['tns'], $this->hostname)) - { - $this->dsn = $this->hostname; - return; - } - elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE - && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== '')) - { - /* If the hostname field isn't empty, doesn't contain - * ':' and/or '/' and if port and/or database aren't - * empty, then the hostname field is most likely indeed - * just a hostname. Therefore we'll try and build an - * Easy Connect string from these 3 settings, assuming - * that the database field is a service name. - */ - $this->dsn = $this->hostname - .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '') - .($this->database !== '' ? '/'.ltrim($this->database, '/') : ''); - - if (preg_match($valid_dsns['ec'], $this->dsn)) - { - return; - } - } - - /* At this point, we can only try and validate the hostname and - * database fields separately as DSNs. - */ - if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname)) - { - $this->dsn = $this->hostname; - return; - } - - $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database); - foreach ($valid_dsns as $regexp) - { - if (preg_match($regexp, $this->database)) - { - return; - } - } - - /* Well - OK, an empty string should work as well. - * PHP will try to use environment variables to - * determine which Oracle instance to connect to. - */ - $this->dsn = ''; - } - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - $func = ($persistent === TRUE) ? 'oci_pconnect' : 'oci_connect'; - return empty($this->char_set) - ? $func($this->username, $this->password, $this->dsn) - : $func($this->username, $this->password, $this->dsn, $this->char_set); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if ( ! $this->conn_id OR ($version_string = oci_server_version($this->conn_id)) === FALSE) - { - return FALSE; - } - elseif (preg_match('#Release\s(\d+(?:\.\d+)+)#', $version_string, $match)) - { - return $this->data_cache['version'] = $match[1]; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - /* Oracle must parse the query before it is run. All of the actions with - * the query are based on the statement id returned by oci_parse(). - */ - if ($this->_reset_stmt_id === TRUE) - { - $this->stmt_id = oci_parse($this->conn_id, $sql); - } - - oci_set_prefetch($this->stmt_id, 1000); - return oci_execute($this->stmt_id, $this->commit_mode); - } - - // -------------------------------------------------------------------- - - /** - * Get cursor. Returns a cursor from the database - * - * @return resource - */ - public function get_cursor() - { - return $this->curs_id = oci_new_cursor($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Stored Procedure. Executes a stored procedure - * - * @param string package name in which the stored procedure is in - * @param string stored procedure name to execute - * @param array parameters - * @return mixed - * - * params array keys - * - * KEY OPTIONAL NOTES - * name no the name of the parameter should be in : format - * value no the value of the parameter. If this is an OUT or IN OUT parameter, - * this should be a reference to a variable - * type yes the type of the parameter - * length yes the max size of the parameter - */ - public function stored_procedure($package, $procedure, array $params) - { - if ($package === '' OR $procedure === '') - { - Logger::logError('Invalid query: '.$package.'.'.$procedure); - return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; - } - - // Build the query string - $sql = 'BEGIN '.$package.'.'.$procedure.'('; - - $have_cursor = FALSE; - foreach ($params as $param) - { - $sql .= $param['name'].','; - - if (isset($param['type']) && $param['type'] === OCI_B_CURSOR) - { - $have_cursor = TRUE; - } - } - $sql = trim($sql, ',').'); END;'; - - $this->_reset_stmt_id = FALSE; - $this->stmt_id = oci_parse($this->conn_id, $sql); - $this->_bind_params($params); - $result = $this->query($sql, FALSE, $have_cursor); - $this->_reset_stmt_id = TRUE; - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Bind parameters - * - * @param array $params - * @return void - */ - protected function _bind_params($params) - { - if ( ! is_array($params) OR ! is_resource($this->stmt_id)) - { - return; - } - - foreach ($params as $param) - { - foreach (array('name', 'value', 'type', 'length') as $val) - { - if ( ! isset($param[$val])) - { - $param[$val] = ''; - } - } - - oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']); - } - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - $this->commit_mode = Core::isPHP('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT; - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - $this->commit_mode = OCI_COMMIT_ON_SUCCESS; - - return oci_commit($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - $this->commit_mode = OCI_COMMIT_ON_SUCCESS; - return oci_rollback($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return oci_num_rows($this->stmt_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - // not supported in oracle - return $this->display_error('db_unsupported_function'); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"'; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - return 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHAR_LENGTH, DATA_PRECISION, DATA_LENGTH, DATA_DEFAULT, NULLABLE - FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - - $length = ($query[$i]->CHAR_LENGTH > 0) - ? $query[$i]->CHAR_LENGTH : $query[$i]->DATA_PRECISION; - if ($length === NULL) - { - $length = $query[$i]->DATA_LENGTH; - } - $retval[$i]->max_length = $length; - - $default = $query[$i]->DATA_DEFAULT; - if ($default === NULL && $query[$i]->NULLABLE === 'N') - { - $default = ''; - } - $retval[$i]->default = $default; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - /* oci_error() returns an array that already contains the - * 'code' and 'message' keys, so we can just return it. - */ - if (is_resource($this->curs_id)) - { - return oci_error($this->curs_id); - } - elseif (is_resource($this->stmt_id)) - { - return oci_error($this->stmt_id); - } - elseif (is_resource($this->conn_id)) - { - return oci_error($this->conn_id); - } - - return oci_error(); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _insert_batch($table, $keys, $values) - { - $keys = implode(', ', $keys); - $sql = "INSERT ALL\n"; - - for ($i = 0, $c = count($values); $i < $c; $i++) - { - $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n"; - } - - return $sql.'SELECT * FROM dual'; - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - $this->where('rownum <= ',$this->qb_limit, FALSE); - $this->qb_limit = FALSE; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - if (version_compare($this->version(), '12.1', '>=')) - { - // OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - $this->limit_used = TRUE; - return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')' - .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1) : ''); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - oci_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/oci8/oci8_forge.php b/src/Database/drivers/oci8/oci8_forge.php deleted file mode 100644 index 533d17a..0000000 --- a/src/Database/drivers/oci8/oci8_forge.php +++ /dev/null @@ -1,146 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Oracle Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_oci8_forge extends FW_DB_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - elseif ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = "\n\t".$field[$i]['_literal']; - } - else - { - $field[$i]['_literal'] = "\n\t".$this->_process_column($field[$i]); - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - - if ($alter_type === 'MODIFY' && ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - } - - $sql .= ' '.$alter_type.' '; - $sql .= (count($field) === 1) - ? $field[0] - : '('.implode(',', $field).')'; - - // RENAME COLUMN must be executed after MODIFY - array_unshift($sqls, $sql); - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - sequences and triggers must be used instead - } - -} diff --git a/src/Database/drivers/oci8/oci8_result.php b/src/Database/drivers/oci8/oci8_result.php deleted file mode 100644 index 8bd66a5..0000000 --- a/src/Database/drivers/oci8/oci8_result.php +++ /dev/null @@ -1,226 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * oci8 Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_oci8_result extends FW_DB_result { - - /** - * Statement ID - * - * @var resource - */ - public $stmt_id; - - /** - * Cursor ID - * - * @var resource - */ - public $curs_id; - - /** - * Limit used flag - * - * @var bool - */ - public $limit_used; - - /** - * Commit mode flag - * - * @var int - */ - public $commit_mode; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$driver_object - * @return void - */ - public function __construct(&$driver_object) - { - parent::__construct($driver_object); - - $this->stmt_id = $driver_object->stmt_id; - $this->curs_id = $driver_object->curs_id; - $this->limit_used = $driver_object->limit_used; - $this->commit_mode =& $driver_object->commit_mode; - $driver_object->stmt_id = FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - $count = oci_num_fields($this->stmt_id); - - // if we used a limit we subtract it - return ($this->limit_used) ? $count - 1 : $count; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++) - { - $field_names[] = oci_field_name($this->stmt_id, $c); - } - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++) - { - $F = new stdClass(); - $F->name = oci_field_name($this->stmt_id, $c); - $F->type = oci_field_type($this->stmt_id, $c); - $F->max_length = oci_field_size($this->stmt_id, $c); - - $retval[] = $F; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - oci_free_statement($this->result_id); - $this->result_id = FALSE; - } - - if (is_resource($this->stmt_id)) - { - oci_free_statement($this->stmt_id); - } - - if (is_resource($this->curs_id)) - { - oci_cancel($this->curs_id); - $this->curs_id = NULL; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id; - return oci_fetch_assoc($id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - $row = ($this->curs_id) - ? oci_fetch_object($this->curs_id) - : oci_fetch_object($this->stmt_id); - - if ($class_name === 'stdClass' OR ! $row) - { - return $row; - } - - $class_name = new $class_name(); - foreach ($row as $key => $value) - { - $class_name->$key = $value; - } - - return $class_name; - } - -} diff --git a/src/Database/drivers/oci8/oci8_utility.php b/src/Database/drivers/oci8/oci8_utility.php deleted file mode 100644 index 0fbdda6..0000000 --- a/src/Database/drivers/oci8/oci8_utility.php +++ /dev/null @@ -1,65 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Oracle Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_oci8_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'SELECT username FROM dba_users'; // Schemas are actual usernames - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/odbc/odbc_driver.php b/src/Database/drivers/odbc/odbc_driver.php deleted file mode 100644 index 05baae7..0000000 --- a/src/Database/drivers/odbc/odbc_driver.php +++ /dev/null @@ -1,374 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Utf8; - -/** - * ODBC Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'odbc'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * Must be empty for ODBC. - * - * @var string - */ - protected $_escape_char = ''; - - /** - * ESCAPE statement string - * - * @var string - */ - protected $_like_escape_str = " {escape '%s'} "; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RND()', 'RND(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - // Legacy support for DSN in the hostname field - if (empty($this->dsn)) - { - $this->dsn = $this->hostname; - } - } - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - return ($persistent === TRUE) - ? odbc_pconnect($this->dsn, $this->username, $this->password) - : odbc_connect($this->dsn, $this->username, $this->password); - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return odbc_exec($this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return odbc_autocommit($this->conn_id, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - if (odbc_commit($this->conn_id)) - { - odbc_autocommit($this->conn_id, TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - if (odbc_rollback($this->conn_id)) - { - odbc_autocommit($this->conn_id, TRUE); - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return Utf8::remove_invisible_characters($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return odbc_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return bool - */ - public function insert_id() - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = '".$this->schema."'"; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Field data query - * - * Generates a platform-specific query so that the column data can be retrieved - * - * @param string $table - * @return string - */ - protected function _field_data($table) - { - return 'SELECT TOP 1 FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => odbc_error($this->conn_id), 'message' => odbc_errormsg($this->conn_id)); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - odbc_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/odbc/odbc_forge.php b/src/Database/drivers/odbc/odbc_forge.php deleted file mode 100644 index 71a8d88..0000000 --- a/src/Database/drivers/odbc/odbc_forge.php +++ /dev/null @@ -1,82 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * ODBC Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported (in most databases at least) - } - -} diff --git a/src/Database/drivers/odbc/odbc_result.php b/src/Database/drivers/odbc/odbc_result.php deleted file mode 100644 index 4635eda..0000000 --- a/src/Database/drivers/odbc/odbc_result.php +++ /dev/null @@ -1,264 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * ODBC Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - if (is_int($this->num_rows)) - { - return $this->num_rows; - } - elseif (($this->num_rows = odbc_num_rows($this->result_id)) !== -1) - { - return $this->num_rows; - } - - // Work-around for ODBC subdrivers that don't support num_rows() - if (count($this->result_array) > 0) - { - return $this->num_rows = count($this->result_array); - } - elseif (count($this->result_object) > 0) - { - return $this->num_rows = count($this->result_object); - } - - return $this->num_rows = count($this->result_array()); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return odbc_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - $num_fields = $this->num_fields(); - - if ($num_fields > 0) - { - for ($i = 1; $i <= $num_fields; $i++) - { - $field_names[] = odbc_field_name($this->result_id, $i); - } - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $odbc_index = 1, $c = $this->num_fields(); $i < $c; $i++, $odbc_index++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = odbc_field_name($this->result_id, $odbc_index); - $retval[$i]->type = odbc_field_type($this->result_id, $odbc_index); - $retval[$i]->max_length = odbc_field_len($this->result_id, $odbc_index); - $retval[$i]->primary_key = 0; - $retval[$i]->default = ''; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - odbc_free_result($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return odbc_fetch_array($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - $row = odbc_fetch_object($this->result_id); - - if ($class_name === 'stdClass' OR ! $row) - { - return $row; - } - - $class_name = new $class_name(); - foreach ($row as $key => $value) - { - $class_name->$key = $value; - } - - return $class_name; - } - -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('odbc_fetch_array')) -{ - /** - * ODBC Fetch array - * - * Emulates the native odbc_fetch_array() function when - * it is not available (odbc_fetch_array() requires unixODBC) - * - * @param resource &$result - * @param int $rownumber - * @return array - */ - function odbc_fetch_array(&$result, $rownumber = 1) - { - $rs = array(); - if ( ! odbc_fetch_into($result, $rs, $rownumber)) - { - return FALSE; - } - - $rs_assoc = array(); - foreach ($rs as $k => $v) - { - $field_name = odbc_field_name($result, $k+1); - $rs_assoc[$field_name] = $v; - } - - return $rs_assoc; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('odbc_fetch_object')) -{ - /** - * ODBC Fetch object - * - * Emulates the native odbc_fetch_object() function when - * it is not available. - * - * @param resource &$result - * @param int $rownumber - * @return object - */ - function odbc_fetch_object(&$result, $rownumber = 1) - { - $rs = array(); - if ( ! odbc_fetch_into($result, $rs, $rownumber)) - { - return FALSE; - } - - $rs_object = new stdClass(); - foreach ($rs as $k => $v) - { - $field_name = odbc_field_name($result, $k+1); - $rs_object->$field_name = $v; - } - - return $rs_object; - } -} diff --git a/src/Database/drivers/odbc/odbc_utility.php b/src/Database/drivers/odbc/odbc_utility.php deleted file mode 100644 index d1aa41f..0000000 --- a/src/Database/drivers/odbc/odbc_utility.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * ODBC Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_odbc_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/pdo/pdo_driver.php b/src/Database/drivers/pdo/pdo_driver.php deleted file mode 100644 index 10d5325..0000000 --- a/src/Database/drivers/pdo/pdo_driver.php +++ /dev/null @@ -1,371 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Exception\DatabaseException; - -/** - * PDO Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'pdo'; - - /** - * PDO Options - * - * @var array - */ - public $options = array(); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Validates the DSN string and/or detects the subdriver. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (preg_match('/([^:]+):/', $this->dsn, $match) && count($match) === 2) - { - // If there is a minimum valid dsn string pattern found, we're done - // This is for general PDO users, who tend to have a full DSN string. - $this->subdriver = $match[1]; - return; - } - // Legacy support for DSN specified in the hostname field - elseif (preg_match('/([^:]+):/', $this->hostname, $match) && count($match) === 2) - { - $this->dsn = $this->hostname; - $this->hostname = NULL; - $this->subdriver = $match[1]; - return; - } - elseif (in_array($this->subdriver, array('mssql', 'sybase'), TRUE)) - { - $this->subdriver = 'dblib'; - } - elseif ($this->subdriver === '4D') - { - $this->subdriver = '4d'; - } - elseif ( ! in_array($this->subdriver, array('4d', 'cubrid', 'dblib', 'firebird', 'ibm', 'informix', 'mysql', 'oci', 'odbc', 'pgsql', 'sqlite', 'sqlsrv'), TRUE)) - { - Logger::logError('PDO: Invalid or non-existent subdriver'); - - if ($this->db_debug) - { - throw new DatabaseException('Invalid or non-existent PDO subdriver', 1); - } - } - - $this->dsn = NULL; - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - $this->options[PDO::ATTR_PERSISTENT] = $persistent; - - try - { - return new PDO($this->dsn, $this->username, $this->password, $this->options); - } - catch (PDOException $e) - { - if ($this->db_debug && empty($this->failover)) - { - $this->display_error($e->getMessage(), '', TRUE); - } - - return FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - // Not all subdrivers support the getAttribute() method - try - { - return $this->data_cache['version'] = $this->conn_id->getAttribute(PDO::ATTR_SERVER_VERSION); - } - catch (PDOException $e) - { - return parent::version(); - } - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql SQL query - * @return mixed - */ - protected function _execute($sql) - { - return $this->conn_id->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return $this->conn_id->beginTransaction(); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return $this->conn_id->commit(); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return $this->conn_id->rollBack(); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - // Escape the string - $str = $this->conn_id->quote($str); - - // If there are duplicated quotes, trim them away - return ($str[0] === "'") - ? substr($str, 1, -1) - : $str; - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return is_object($this->result_id) ? $this->result_id->rowCount() : 0; - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @param string $name - * @return int - */ - public function insert_id($name = NULL) - { - return $this->conn_id->lastInsertId($name); - } - - // -------------------------------------------------------------------- - - /** - * Field data query - * - * Generates a platform-specific query so that the column data can be retrieved - * - * @param string $table - * @return string - */ - protected function _field_data($table) - { - return 'SELECT TOP 1 * FROM '.$this->protect_identifiers($table); - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - $error = array('code' => '00000', 'message' => ''); - $pdo_error = $this->conn_id->errorInfo(); - - if (empty($pdo_error[0])) - { - return $error; - } - - $error['code'] = isset($pdo_error[1]) ? $pdo_error[0].'/'.$pdo_error[1] : $pdo_error[0]; - if (isset($pdo_error[2])) - { - $error['message'] = $pdo_error[2]; - } - - return $error; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = CASE '."\n"; - - foreach ($v as $row) - { - $cases .= $row."\n"; - } - - $cases .= 'ELSE '.$k.' END, '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE '.$table; - } - -} diff --git a/src/Database/drivers/pdo/pdo_forge.php b/src/Database/drivers/pdo/pdo_forge.php deleted file mode 100644 index 18998fa..0000000 --- a/src/Database/drivers/pdo/pdo_forge.php +++ /dev/null @@ -1,61 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = FALSE; - -} diff --git a/src/Database/drivers/pdo/pdo_result.php b/src/Database/drivers/pdo/pdo_result.php deleted file mode 100644 index 4bac608..0000000 --- a/src/Database/drivers/pdo/pdo_result.php +++ /dev/null @@ -1,194 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - if (is_int($this->num_rows)) - { - return $this->num_rows; - } - elseif (count($this->result_array) > 0) - { - return $this->num_rows = count($this->result_array); - } - elseif (count($this->result_object) > 0) - { - return $this->num_rows = count($this->result_object); - } - elseif (($num_rows = $this->result_id->rowCount()) > 0) - { - return $this->num_rows = $num_rows; - } - - return $this->num_rows = count($this->result_array()); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return $this->result_id->columnCount(); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return bool - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - // Might trigger an E_WARNING due to not all subdrivers - // supporting getColumnMeta() - $field_names[$i] = @$this->result_id->getColumnMeta($i); - $field_names[$i] = $field_names[$i]['name']; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - try - { - $retval = array(); - - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field = $this->result_id->getColumnMeta($i); - - $retval[$i] = new stdClass(); - $retval[$i]->name = $field['name']; - $retval[$i]->type = $field['native_type']; - $retval[$i]->max_length = ($field['len'] > 0) ? $field['len'] : NULL; - $retval[$i]->primary_key = (int) ( ! empty($field['flags']) && in_array('primary_key', $field['flags'], TRUE)); - } - - return $retval; - } - catch (Exception $e) - { - if ($this->db->db_debug) - { - return $this->db->display_error('db_unsupported_feature'); - } - - return FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_object($this->result_id)) - { - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return $this->result_id->fetch(PDO::FETCH_ASSOC); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return $this->result_id->fetchObject($class_name); - } - -} diff --git a/src/Database/drivers/pdo/pdo_utility.php b/src/Database/drivers/pdo/pdo_utility.php deleted file mode 100644 index a4b40b3..0000000 --- a/src/Database/drivers/pdo/pdo_utility.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_4d_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_4d_driver.php deleted file mode 100644 index d5c20b2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_4d_driver.php +++ /dev/null @@ -1,196 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO 4D Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_4d_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = '4d'; - - /** - * Identifier escape character - * - * @var string[] - */ - protected $_escape_char = array('[', ']'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = '4D:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 3) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('TABLE_NAME').' FROM '.$this->escape_identifiers('_USER_TABLES'); - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' WHERE '.$this->escape_identifiers('TABLE_NAME')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT '.$this->escape_identifiers('COLUMN_NAME').' FROM '.$this->escape_identifiers('_USER_COLUMNS') - .' WHERE '.$this->escape_identifiers('TABLE_NAME').' = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Field data query - * - * Generates a platform-specific query so that the column data can be retrieved - * - * @param string $table - * @return string - */ - protected function _field_data($table) - { - return 'SELECT * FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE).' LIMIT 1'; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.$this->qb_limit.($this->qb_offset ? ' OFFSET '.$this->qb_offset : ''); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_4d_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_4d_forge.php deleted file mode 100644 index 0c39529..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_4d_forge.php +++ /dev/null @@ -1,214 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO 4D Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_4d_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE SCHEMA %s'; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = 'DROP SCHEMA %s'; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = FALSE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'INT16' => 'INT', - 'SMALLINT' => 'INT', - 'INT' => 'INT64', - 'INT32' => 'INT64' - ); - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - // No method of modifying columns is supported - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['null'] - .$field['unique'] - .$field['auto_increment']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - case 'BIGINT': - $attributes['TYPE'] = 'INT64'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE'; - - // UNIQUE must be used with NOT NULL - $field['null'] = ' NOT NULL'; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) - { - if (stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' AUTO_INCREMENT'; - } - elseif (strcasecmp($field['type'], 'UUID') === 0) - { - $field['auto_increment'] = ' AUTO_GENERATE'; - } - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_cubrid_driver.php deleted file mode 100644 index 88d659e..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_driver.php +++ /dev/null @@ -1,246 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO CUBRID Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_cubrid_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'cubrid'; - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'cubrid:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES'; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k." = CASE \n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_cubrid_forge.php deleted file mode 100644 index e1383e2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_cubrid_forge.php +++ /dev/null @@ -1,224 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO CUBRID Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_cubrid_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SHORT' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'BIGINT' => 'NUMERIC', - 'FLOAT' => 'DOUBLE', - 'REAL' => 'DOUBLE' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $sqls[] = $sql.' CHANGE '.$field[$i]['_literal']; - } - else - { - $alter_type = empty($field[$i]['new_name']) ? ' MODIFY ' : ' CHANGE '; - $sqls[] = $sql.$alter_type.$this->_process_column($field[$i]); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_dblib_driver.php deleted file mode 100644 index 77bdb5f..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_dblib_driver.php +++ /dev/null @@ -1,328 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO DBLIB Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_dblib_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'dblib'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('NEWID()', 'RAND(%d)'); - - /** - * Quoted identifier flag - * - * Whether to use SQL-92 standard quoted identifier - * (double quotes) or brackets for identifier escaping. - * - * @var bool - */ - protected $_quoted_identifier; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = $params['subdriver'].':host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - if ( ! empty($this->port)) - { - $this->dsn .= (DIRECTORY_SEPARATOR === '\\' ? ',' : ':').$this->port; - } - - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - empty($this->appname) OR $this->dsn .= ';appname='.$this->appname; - } - else - { - if ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - - $this->subdriver = 'dblib'; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - $this->conn_id = parent::db_connect($persistent); - - if ( ! is_object($this->conn_id)) - { - return $this->conn_id; - } - - // Determine how identifiers are escaped - $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); - $query = $query->row_array(); - $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; - $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('name') - .' FROM '.$this->escape_identifiers('sysobjects') - .' WHERE '.$this->escape_identifiers('type')." = 'U'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql.' ORDER BY '.$this->escape_identifiers('name'); - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, COLUMN_DEFAULT - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - $retval[$i]->max_length = ($query[$i]->CHARACTER_MAXIMUM_LENGTH > 0) ? $query[$i]->CHARACTER_MAXIMUM_LENGTH : $query[$i]->NUMERIC_PRECISION; - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - return 'WITH fw_delete AS (SELECT TOP '.$this->qb_limit.' * FROM '.$table.$this->_compile_wh('qb_where').') DELETE FROM fw_delete'; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - $limit = $this->qb_offset + $this->qb_limit; - - // As of SQL Server 2005 (9.0.*) ROW_NUMBER() is supported, - // however an ORDER BY clause is required for it to work - if (version_compare($this->version(), '9', '>=') && $this->qb_offset && ! empty($this->qb_orderby)) - { - $orderby = $this->_compile_order_by(); - - // We have to strip the ORDER BY clause - $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); - - // Get the fields to select from our subquery, so that we can avoid FW_rownum appearing in the actual results - if (count($this->qb_select) === 0) - { - $select = '*'; // Inevitable - } - else - { - // Use only field names and their aliases, everything else is out of our scope. - $select = array(); - $field_regexp = ($this->_quoted_identifier) - ? '("[^\"]+")' : '(\[[^\]]+\])'; - for ($i = 0, $c = count($this->qb_select); $i < $c; $i++) - { - $select[] = preg_match('/(?:\s|\.)'.$field_regexp.'$/i', $this->qb_select[$i], $m) - ? $m[1] : $this->qb_select[$i]; - } - $select = implode(', ', $select); - } - - return 'SELECT '.$select." FROM (\n\n" - .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.trim($orderby).') AS '.$this->escape_identifiers('FW_rownum').', ', $sql) - ."\n\n) ".$this->escape_identifiers('FW_subquery') - ."\nWHERE ".$this->escape_identifiers('FW_rownum').' BETWEEN '.($this->qb_offset + 1).' AND '.$limit; - } - - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string|bool - */ - protected function _insert_batch($table, $keys, $values) - { - // Multiple-value inserts are only supported as of SQL Server 2008 - if (version_compare($this->version(), '10', '>=')) - { - return parent::_insert_batch($table, $keys, $values); - } - - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_dblib_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_dblib_forge.php deleted file mode 100644 index 8c3ddd3..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_dblib_forge.php +++ /dev/null @@ -1,141 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO DBLIB Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_dblib_forge extends FW_DB_pdo_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nCREATE TABLE"; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = "IF EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nDROP TABLE"; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT' => 'SMALLINT', - 'SMALLINT' => 'INT', - 'INT' => 'BIGINT', - 'REAL' => 'FLOAT' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' ALTER COLUMN '; - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql.$this->_process_column($field[$i]); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' IDENTITY(1,1)'; - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_firebird_driver.php deleted file mode 100644 index c589048..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_firebird_driver.php +++ /dev/null @@ -1,259 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Firebird Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_firebird_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'firebird'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RAND()', 'RAND()'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'firebird:'; - - if ( ! empty($this->database)) - { - $this->dsn .= 'dbname='.$this->database; - } - elseif ( ! empty($this->hostname)) - { - $this->dsn .= 'dbname='.$this->hostname; - } - - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - empty($this->role) OR $this->dsn .= ';role='.$this->role; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 9) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\''; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "rfields"."RDB$FIELD_NAME" AS "name", - CASE "fields"."RDB$FIELD_TYPE" - WHEN 7 THEN \'SMALLINT\' - WHEN 8 THEN \'INTEGER\' - WHEN 9 THEN \'QUAD\' - WHEN 10 THEN \'FLOAT\' - WHEN 11 THEN \'DFLOAT\' - WHEN 12 THEN \'DATE\' - WHEN 13 THEN \'TIME\' - WHEN 14 THEN \'CHAR\' - WHEN 16 THEN \'INT64\' - WHEN 27 THEN \'DOUBLE\' - WHEN 35 THEN \'TIMESTAMP\' - WHEN 37 THEN \'VARCHAR\' - WHEN 40 THEN \'CSTRING\' - WHEN 261 THEN \'BLOB\' - ELSE NULL - END AS "type", - "fields"."RDB$FIELD_LENGTH" AS "max_length", - "rfields"."RDB$DEFAULT_VALUE" AS "default" - FROM "RDB$RELATION_FIELDS" "rfields" - JOIN "RDB$FIELDS" "fields" ON "rfields"."RDB$FIELD_SOURCE" = "fields"."RDB$FIELD_NAME" - WHERE "rfields"."RDB$RELATION_NAME" = '.$this->escape($table).' - ORDER BY "rfields"."RDB$FIELD_POSITION"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // Limit clause depends on if Interbase or Firebird - if (stripos($this->version(), 'firebird') !== FALSE) - { - $select = 'FIRST '.$this->qb_limit - .($this->qb_offset > 0 ? ' SKIP '.$this->qb_offset : ''); - } - else - { - $select = 'ROWS ' - .($this->qb_offset > 0 ? $this->qb_offset.' TO '.($this->qb_limit + $this->qb_offset) : $this->qb_limit); - } - - return preg_replace('`SELECT`i', 'SELECT '.$select, $sql); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_firebird_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_firebird_forge.php deleted file mode 100644 index 3cb7bd3..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_firebird_forge.php +++ /dev/null @@ -1,234 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Firebird Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_firebird_forge extends FW_DB_pdo_forge { - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = FALSE; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INTEGER' => 'INT64', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return string - */ - public function create_database($db_name) - { - // Firebird databases are flat files, so a path is required - - // Hostname is needed for remote access - empty($this->db->hostname) OR $db_name = $this->hostname.':'.$db_name; - - return parent::create_database('"'.$db_name.'"'); - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - if ( ! ibase_drop_db($this->conn_id)) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = 'UPDATE "RDB$RELATION_FIELDS" SET "RDB$NULL_FLAG" = ' - .($field[$i]['null'] === TRUE ? 'NULL' : '1') - .' WHERE "RDB$FIELD_NAME" = '.$this->db->escape($field[$i]['name']) - .' AND "RDB$RELATION_NAME" = '.$this->db->escape($table); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'].$field['length'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INT': - $attributes['TYPE'] = 'INTEGER'; - return; - case 'BIGINT': - $attributes['TYPE'] = 'INT64'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_ibm_driver.php deleted file mode 100644 index 3a361b0..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_ibm_driver.php +++ /dev/null @@ -1,240 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO IBM DB2 Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_ibm_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'ibm'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'ibm:'; - - // Pre-defined DSN - if (empty($this->hostname) && empty($this->HOSTNAME) && empty($this->port) && empty($this->PORT)) - { - if (isset($this->DSN)) - { - $this->dsn .= 'DSN='.$this->DSN; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DSN='.$this->database; - } - - return; - } - - $this->dsn .= 'DRIVER='.(isset($this->DRIVER) ? '{'.$this->DRIVER.'}' : '{IBM DB2 ODBC DRIVER}').';'; - - if (isset($this->DATABASE)) - { - $this->dsn .= 'DATABASE='.$this->DATABASE.';'; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DATABASE='.$this->database.';'; - } - - if (isset($this->HOSTNAME)) - { - $this->dsn .= 'HOSTNAME='.$this->HOSTNAME.';'; - } - else - { - $this->dsn .= 'HOSTNAME='.(empty($this->hostname) ? '127.0.0.1;' : $this->hostname.';'); - } - - if (isset($this->PORT)) - { - $this->dsn .= 'PORT='.$this->port.';'; - } - elseif ( ! empty($this->port)) - { - $this->dsn .= ';PORT='.$this->port.';'; - } - - $this->dsn .= 'PROTOCOL='.(isset($this->PROTOCOL) ? $this->PROTOCOL.';' : 'TCPIP;'); - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "tabname" FROM "syscat"."tables" - WHERE "type" = \'T\' AND LOWER("tabschema") = '.$this->escape(strtolower($this->database)); - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND "tabname" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return array - */ - protected function _list_columns($table = '') - { - return 'SELECT "colname" FROM "syscat"."columns" - WHERE LOWER("tabschema") = '.$this->escape(strtolower($this->database)).' - AND LOWER("tabname") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "colname" AS "name", "typename" AS "type", "default" AS "default", "length" AS "max_length", - CASE "keyseq" WHEN NULL THEN 0 ELSE 1 END AS "primary_key" - FROM "syscat"."columns" - WHERE LOWER("tabschema") = '.$this->escape(strtolower($this->database)).' - AND LOWER("tabname") = '.$this->escape(strtolower($table)).' - ORDER BY "colno"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - $sql .= ' FETCH FIRST '.($this->qb_limit + $this->qb_offset).' ROWS ONLY'; - - return ($this->qb_offset) - ? 'SELECT * FROM ('.$sql.') WHERE rownum > '.$this->qb_offset - : $sql; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_ibm_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_ibm_forge.php deleted file mode 100644 index cc2d48a..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_ibm_forge.php +++ /dev/null @@ -1,151 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO IBM DB2 Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_ibm_forge extends FW_DB_pdo_forge { - - /** - * RENAME TABLE IF statement - * - * @var string - */ - protected $_rename_table = 'RENAME TABLE %s TO %s'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT' - ); - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE'; - - // UNIQUE must be used with NOT NULL - $field['null'] = ' NOT NULL'; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_informix_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_informix_driver.php deleted file mode 100644 index 47da5af..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_informix_driver.php +++ /dev/null @@ -1,305 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Informix Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_informix_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'informix'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('ASC', 'ASC'); // Currently not supported - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'informix:'; - - // Pre-defined DSN - if (empty($this->hostname) && empty($this->host) && empty($this->port) && empty($this->service)) - { - if (isset($this->DSN)) - { - $this->dsn .= 'DSN='.$this->DSN; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DSN='.$this->database; - } - - return; - } - - if (isset($this->host)) - { - $this->dsn .= 'host='.$this->host; - } - else - { - $this->dsn .= 'host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - } - - if (isset($this->service)) - { - $this->dsn .= '; service='.$this->service; - } - elseif ( ! empty($this->port)) - { - $this->dsn .= '; service='.$this->port; - } - - empty($this->database) OR $this->dsn .= '; database='.$this->database; - empty($this->server) OR $this->dsn .= '; server='.$this->server; - - $this->dsn .= '; protocol='.(isset($this->protocol) ? $this->protocol : 'onsoctcp') - .'; EnableScrollableCursors=1'; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "tabname" FROM "systables" - WHERE "tabid" > 99 AND "tabtype" = \'T\' AND LOWER("owner") = '.$this->escape(strtolower($this->username)); - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND "tabname" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - return 'SELECT "colname" FROM "systables", "syscolumns" - WHERE "systables"."tabid" = "syscolumns"."tabid" - AND "systables"."tabtype" = \'T\' - AND LOWER("systables"."owner") = '.$this->escape(strtolower($owner)).' - AND LOWER("systables"."tabname") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "syscolumns"."colname" AS "name", - CASE "syscolumns"."coltype" - WHEN 0 THEN \'CHAR\' - WHEN 1 THEN \'SMALLINT\' - WHEN 2 THEN \'INTEGER\' - WHEN 3 THEN \'FLOAT\' - WHEN 4 THEN \'SMALLFLOAT\' - WHEN 5 THEN \'DECIMAL\' - WHEN 6 THEN \'SERIAL\' - WHEN 7 THEN \'DATE\' - WHEN 8 THEN \'MONEY\' - WHEN 9 THEN \'NULL\' - WHEN 10 THEN \'DATETIME\' - WHEN 11 THEN \'BYTE\' - WHEN 12 THEN \'TEXT\' - WHEN 13 THEN \'VARCHAR\' - WHEN 14 THEN \'INTERVAL\' - WHEN 15 THEN \'NCHAR\' - WHEN 16 THEN \'NVARCHAR\' - WHEN 17 THEN \'INT8\' - WHEN 18 THEN \'SERIAL8\' - WHEN 19 THEN \'SET\' - WHEN 20 THEN \'MULTISET\' - WHEN 21 THEN \'LIST\' - WHEN 22 THEN \'Unnamed ROW\' - WHEN 40 THEN \'LVARCHAR\' - WHEN 41 THEN \'BLOB/CLOB/BOOLEAN\' - WHEN 4118 THEN \'Named ROW\' - ELSE "syscolumns"."coltype" - END AS "type", - "syscolumns"."collength" as "max_length", - CASE "sysdefaults"."type" - WHEN \'L\' THEN "sysdefaults"."default" - ELSE NULL - END AS "default" - FROM "syscolumns", "systables", "sysdefaults" - WHERE "syscolumns"."tabid" = "systables"."tabid" - AND "systables"."tabid" = "sysdefaults"."tabid" - AND "syscolumns"."colno" = "sysdefaults"."colno" - AND "systables"."tabtype" = \'T\' - AND LOWER("systables"."owner") = '.$this->escape(strtolower($this->username)).' - AND LOWER("systables"."tabname") = '.$this->escape(strtolower($table)).' - ORDER BY "syscolumns"."colno"'; - - return (($query = $this->query($sql)) !== FALSE) - ? $query->result_object() - : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE ONLY '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql $SQL Query - * @return string - */ - protected function _limit($sql) - { - $select = 'SELECT '.($this->qb_offset ? 'SKIP '.$this->qb_offset : '').'FIRST '.$this->qb_limit.' '; - return preg_replace('/^(SELECT\s)/i', $select, $sql, 1); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_informix_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_informix_forge.php deleted file mode 100644 index 266bc82..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_informix_forge.php +++ /dev/null @@ -1,160 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Informix Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_informix_forge extends FW_DB_pdo_forge { - - /** - * RENAME TABLE statement - * - * @var string - */ - protected $_rename_table = 'RENAME TABLE %s TO %s'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'REAL' => 'DOUBLE PRECISION', - 'SMALLFLOAT' => 'DOUBLE PRECISION' - ); - - /** - * DEFAULT value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_default = ', '; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'BYTE': - case 'TEXT': - case 'BLOB': - case 'CLOB': - $attributes['UNIQUE'] = FALSE; - if (isset($attributes['DEFAULT'])) - { - unset($attributes['DEFAULT']); - } - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute UNIQUE - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_unique(&$attributes, &$field) - { - if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE) - { - $field['unique'] = ' UNIQUE CONSTRAINT '.$this->db->escape_identifiers($field['name']); - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_mysql_driver.php deleted file mode 100644 index 07876ae..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_mysql_driver.php +++ /dev/null @@ -1,335 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use FuzeWorks\Core; - -/** - * PDO MySQL Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_mysql_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'mysql'; - - /** - * Compression flag - * - * @var bool - */ - public $compress = FALSE; - - /** - * Strict ON flag - * - * Whether we're running in strict SQL mode. - * - * @var bool - */ - public $stricton; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * @var string - */ - protected $_escape_char = '`'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'mysql:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE && Core::isPHP('5.3.6')) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - /* Prior to PHP 5.3.6, even if the charset was supplied in the DSN - * on connect - it was ignored. This is a work-around for the issue. - * - * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php - */ - if ( ! Core::isPHP('5.3.6') && ! empty($this->char_set)) - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set - .(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat); - } - - if (isset($this->stricton)) - { - if ($this->stricton) - { - $sql = 'CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'; - } - else - { - $sql = 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( - @@sql_mode, - "STRICT_ALL_TABLES,", ""), - ",STRICT_ALL_TABLES", ""), - "STRICT_ALL_TABLES", ""), - "STRICT_TRANS_TABLES,", ""), - ",STRICT_TRANS_TABLES", ""), - "STRICT_TRANS_TABLES", "")'; - } - - if ( ! empty($sql)) - { - if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND])) - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode = '.$sql; - } - else - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = '.$sql; - } - } - } - - if ($this->compress === TRUE) - { - $this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE; - } - - // SSL support was added to PDO_MYSQL in PHP 5.3.7 - if (is_array($this->encrypt) && Core::isPHP('5.3.7')) - { - $ssl = array(); - empty($this->encrypt['ssl_key']) OR $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key']; - empty($this->encrypt['ssl_cert']) OR $ssl[PDO::MYSQL_ATTR_SSL_CERT] = $this->encrypt['ssl_cert']; - empty($this->encrypt['ssl_ca']) OR $ssl[PDO::MYSQL_ATTR_SSL_CA] = $this->encrypt['ssl_ca']; - empty($this->encrypt['ssl_capath']) OR $ssl[PDO::MYSQL_ATTR_SSL_CAPATH] = $this->encrypt['ssl_capath']; - empty($this->encrypt['ssl_cipher']) OR $ssl[PDO::MYSQL_ATTR_SSL_CIPHER] = $this->encrypt['ssl_cipher']; - - // DO NOT use array_merge() here! - // It re-indexes numeric keys and the PDO_MYSQL_ATTR_SSL_* constants are integers. - empty($ssl) OR $this->options += $ssl; - } - - // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails - if ( - ($pdo = parent::db_connect($persistent)) !== FALSE - && ! empty($ssl) - && version_compare($pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), '5.7.3', '<=') - && empty($pdo->query("SHOW STATUS LIKE 'ssl_cipher'")->fetchObject()->Value) - ) - { - $message = 'PDO_MYSQL was configured for an SSL connection, but got an unencrypted connection instead!'; - Logger::logError($message); - return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; - } - - return $pdo; - } - - // -------------------------------------------------------------------- - - /** - * Select the database - * - * @param string $database - * @return bool - */ - public function db_select($database = '') - { - if ($database === '') - { - $database = $this->database; - } - - if (FALSE !== $this->simple_query('USE '.$this->escape_identifiers($database))) - { - $this->database = $database; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SHOW TABLES'; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'"; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->Field; - - sscanf($query[$i]->Type, '%[a-z](%d)', - $retval[$i]->type, - $retval[$i]->max_length - ); - - $retval[$i]->default = $query[$i]->Default; - $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI'); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * FROM tables - * - * Groups tables in FROM clauses if needed, so there is no confusion - * about operator precedence. - * - * @return string - */ - protected function _from_tables() - { - if ( ! empty($this->qb_join) && count($this->qb_from) > 1) - { - return '('.implode(', ', $this->qb_from).')'; - } - - return implode(', ', $this->qb_from); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_mysql_forge.php deleted file mode 100644 index 9cd27d2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_mysql_forge.php +++ /dev/null @@ -1,253 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO MySQL Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_mysql_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s'; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * CREATE TABLE keys flag - * - * Whether table keys are created from within the - * CREATE TABLE statement. - * - * @var bool - */ - protected $_create_table_keys = TRUE; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT', - 'SMALLINT', - 'MEDIUMINT', - 'INT', - 'INTEGER', - 'BIGINT', - 'REAL', - 'DOUBLE', - 'DOUBLE PRECISION', - 'FLOAT', - 'DECIMAL', - 'NUMERIC' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * CREATE TABLE attributes - * - * @param array $attributes Associative array of table attributes - * @return string - */ - protected function _create_table_attr($attributes) - { - $sql = ''; - - foreach (array_keys($attributes) as $key) - { - if (is_string($key)) - { - $sql .= ' '.strtoupper($key).' = '.$attributes[$key]; - } - } - - if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) - { - $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set; - } - - if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE')) - { - $sql .= ' COLLATE = '.$this->db->dbcollat; - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = ($alter_type === 'ADD') - ? "\n\tADD ".$field[$i]['_literal'] - : "\n\tMODIFY ".$field[$i]['_literal']; - } - else - { - if ($alter_type === 'ADD') - { - $field[$i]['_literal'] = "\n\tADD "; - } - else - { - $field[$i]['_literal'] = empty($field[$i]['new_name']) ? "\n\tMODIFY " : "\n\tCHANGE "; - } - - $field[$i] = $field[$i]['_literal'].$this->_process_column($field[$i]); - } - } - - return array($sql.implode(',', $field)); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - $extra_clause = isset($field['after']) - ? ' AFTER '.$this->db->escape_identifiers($field['after']) : ''; - - if (empty($extra_clause) && isset($field['first']) && $field['first'] === TRUE) - { - $extra_clause = ' FIRST'; - } - - return $this->db->escape_identifiers($field['name']) - .(empty($field['new_name']) ? '' : ' '.$this->db->escape_identifiers($field['new_name'])) - .' '.$field['type'].$field['length'] - .$field['unsigned'] - .$field['null'] - .$field['default'] - .$field['auto_increment'] - .$field['unique'] - .(empty($field['comment']) ? '' : ' COMMENT '.$field['comment']) - .$extra_clause; - } - - // -------------------------------------------------------------------- - - /** - * Process indexes - * - * @param string $table (ignored) - * @return string - */ - protected function _process_indexes($table) - { - $sql = ''; - - for ($i = 0, $c = count($this->keys); $i < $c; $i++) - { - if (is_array($this->keys[$i])) - { - for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) - { - if ( ! isset($this->fields[$this->keys[$i][$i2]])) - { - unset($this->keys[$i][$i2]); - continue; - } - } - } - elseif ( ! isset($this->fields[$this->keys[$i]])) - { - unset($this->keys[$i]); - continue; - } - - is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - - $sql .= ",\n\tKEY ".$this->db->escape_identifiers(implode('_', $this->keys[$i])) - .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).')'; - } - - $this->keys = array(); - - return $sql; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_oci_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_oci_driver.php deleted file mode 100644 index 091d995..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_oci_driver.php +++ /dev/null @@ -1,322 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Oracle Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_oci_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'oci'; - - // -------------------------------------------------------------------- - - /** - * List of reserved identifiers - * - * Identifiers that must NOT be escaped. - * - * @var string[] - */ - protected $_reserved_identifiers = array('*', 'rownum'); - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('ASC', 'ASC'); // Currently not supported - - /** - * COUNT string - * - * @used-by FW_DB_driver::count_all() - * @used-by FW_DB_query_builder::count_all_results() - * - * @var string - */ - protected $_count_string = 'SELECT COUNT(1) AS '; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'oci:dbname='; - - // Oracle has a slightly different PDO DSN format (Easy Connect), - // which also supports pre-defined DSNs. - if (empty($this->hostname) && empty($this->port)) - { - $this->dsn .= $this->database; - } - else - { - $this->dsn .= '//'.(empty($this->hostname) ? '127.0.0.1' : $this->hostname) - .(empty($this->port) ? '' : ':'.$this->port).'/'; - - empty($this->database) OR $this->dsn .= $this->database; - } - - empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; - } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 4) === FALSE) - { - $this->dsn .= ';charset='.$this->char_set; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - $version_string = parent::version(); - if (preg_match('#Release\s(?\d+(?:\.\d+)+)#', $version_string, $match)) - { - return $this->data_cache['version'] = $match[1]; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"'; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - return 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (strpos($table, '.') !== FALSE) - { - sscanf($table, '%[^.].%s', $owner, $table); - } - else - { - $owner = $this->username; - } - - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHAR_LENGTH, DATA_PRECISION, DATA_LENGTH, DATA_DEFAULT, NULLABLE - FROM ALL_TAB_COLUMNS - WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).' - AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - - $length = ($query[$i]->CHAR_LENGTH > 0) - ? $query[$i]->CHAR_LENGTH : $query[$i]->DATA_PRECISION; - if ($length === NULL) - { - $length = $query[$i]->DATA_LENGTH; - } - $retval[$i]->max_length = $length; - - $default = $query[$i]->DATA_DEFAULT; - if ($default === NULL && $query[$i]->NULLABLE === 'N') - { - $default = ''; - } - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _insert_batch($table, $keys, $values) - { - $keys = implode(', ', $keys); - $sql = "INSERT ALL\n"; - - for ($i = 0, $c = count($values); $i < $c; $i++) - { - $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n"; - } - - return $sql.'SELECT * FROM dual'; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - $this->where('rownum <= ',$this->qb_limit, FALSE); - $this->qb_limit = FALSE; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - if (version_compare($this->version(), '12.1', '>=')) - { - // OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')' - .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1): ''); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_oci_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_oci_forge.php deleted file mode 100644 index c27d0c2..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_oci_forge.php +++ /dev/null @@ -1,146 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO Oracle Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_oci_forge extends FW_DB_pdo_forge { - - /** - * CREATE DATABASE statement - * - * @var string - */ - protected $_create_database = FALSE; - - /** - * DROP DATABASE statement - * - * @var string - */ - protected $_drop_database = FALSE; - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP') - { - return parent::_alter_table($alter_type, $table, $field); - } - elseif ($alter_type === 'CHANGE') - { - $alter_type = 'MODIFY'; - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - $field[$i] = "\n\t".$field[$i]['_literal']; - } - else - { - $field[$i]['_literal'] = "\n\t".$this->_process_column($field[$i]); - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - - if ($alter_type === 'MODIFY' && ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' '.$this->db->escape_identifiers($field[$i]['new_name']); - } - } - } - - $sql .= ' '.$alter_type.' '; - $sql .= (count($field) === 1) - ? $field[0] - : '('.implode(',', $field).')'; - - // RENAME COLUMN must be executed after MODIFY - array_unshift($sqls, $sql); - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported - sequences and triggers must be used instead - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_odbc_driver.php deleted file mode 100644 index b3064b6..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_odbc_driver.php +++ /dev/null @@ -1,280 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO ODBC Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_odbc_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'odbc'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * Identifier escape character - * - * Must be empty for ODBC. - * - * @var string - */ - protected $_escape_char = ''; - - /** - * ESCAPE statement string - * - * @var string - */ - protected $_like_escape_str = " {escape '%s'} "; - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RND()', 'RND(%d)'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'odbc:'; - - // Pre-defined DSN - if (empty($this->hostname) && empty($this->HOSTNAME) && empty($this->port) && empty($this->PORT)) - { - if (isset($this->DSN)) - { - $this->dsn .= 'DSN='.$this->DSN; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DSN='.$this->database; - } - - return; - } - - // If the DSN is not pre-configured - try to build an IBM DB2 connection string - $this->dsn .= 'DRIVER='.(isset($this->DRIVER) ? '{'.$this->DRIVER.'}' : '{IBM DB2 ODBC DRIVER}').';'; - - if (isset($this->DATABASE)) - { - $this->dsn .= 'DATABASE='.$this->DATABASE.';'; - } - elseif ( ! empty($this->database)) - { - $this->dsn .= 'DATABASE='.$this->database.';'; - } - - if (isset($this->HOSTNAME)) - { - $this->dsn .= 'HOSTNAME='.$this->HOSTNAME.';'; - } - else - { - $this->dsn .= 'HOSTNAME='.(empty($this->hostname) ? '127.0.0.1;' : $this->hostname.';'); - } - - if (isset($this->PORT)) - { - $this->dsn .= 'PORT='.$this->port.';'; - } - elseif ( ! empty($this->port)) - { - $this->dsn .= ';PORT='.$this->port.';'; - } - - $this->dsn .= 'PROTOCOL='.(isset($this->PROTOCOL) ? $this->PROTOCOL.';' : 'TCPIP;'); - } - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = '".$this->schema."'"; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql." AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT column_name FROM information_schema.columns WHERE table_name = '.$this->escape($table); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string the table name - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$this->qb_limit.' ', $sql); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_odbc_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_odbc_forge.php deleted file mode 100644 index 7670315..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_odbc_forge.php +++ /dev/null @@ -1,67 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO ODBC Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_odbc_forge extends FW_DB_pdo_forge { - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - // Not supported (in most databases at least) - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_pgsql_driver.php deleted file mode 100644 index c0e1aa6..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ /dev/null @@ -1,380 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO PostgreSQL Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_pgsql_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'pgsql'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'pgsql:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ';port='.$this->port; - empty($this->database) OR $this->dsn .= ';dbname='.$this->database; - - if ( ! empty($this->username)) - { - $this->dsn .= ';username='.$this->username; - empty($this->password) OR $this->dsn .= ';password='.$this->password; - } - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - $this->conn_id = parent::db_connect($persistent); - - if (is_object($this->conn_id) && ! empty($this->schema)) - { - $this->simple_query('SET search_path TO '.$this->schema.',public'); - } - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @param string $name - * @return int - */ - public function insert_id($name = NULL) - { - if ($name === NULL && version_compare($this->version(), '8.1', '>=')) - { - $query = $this->query('SELECT LASTVAL() AS ins_id'); - $query = $query->row(); - return $query->ins_id; - } - - return $this->conn_id->lastInsertId($name); - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * "Smart" Escape String - * - * Escapes data based on type - * - * @param string $str - * @return mixed - */ - public function escape($str) - { - if (is_bool($str)) - { - return ($str) ? 'TRUE' : 'FALSE'; - } - - return parent::escape($str); - } - - // -------------------------------------------------------------------- - - /** - * ORDER BY - * - * @param string $orderby - * @param string $direction ASC, DESC or RANDOM - * @param bool $escape - * @return object - */ - public function order_by($orderby, $direction = '', $escape = NULL) - { - $direction = strtoupper(trim($direction)); - if ($direction === 'RANDOM') - { - if ( ! is_float($orderby) && ctype_digit((string) $orderby)) - { - $orderby = ($orderby > 1) - ? (float) '0.'.$orderby - : (float) $orderby; - } - - if (is_float($orderby)) - { - $this->simple_query('SET SEED '.$orderby); - } - - $orderby = $this->_random_keyword[0]; - $direction = ''; - $escape = FALSE; - } - - return parent::order_by($orderby, $direction, $escape); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \''.$this->schema."'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' AND "table_name" LIKE \'' - .$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * List column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT "column_name" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->column_name; - $retval[$i]->type = $query[$i]->data_type; - $retval[$i]->max_length = ($query[$i]->character_maximum_length > 0) ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision; - $retval[$i]->default = $query[$i]->column_default; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = (CASE '.$index."\n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.$this->qb_limit.($this->qb_offset ? ' OFFSET '.$this->qb_offset : ''); - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_pgsql_forge.php deleted file mode 100644 index 595bdcc..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_pgsql_forge.php +++ /dev/null @@ -1,207 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO PostgreSQL Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_pgsql_forge extends FW_DB_pdo_forge { - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'INT2' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INT4' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'INT8' => 'NUMERIC', - 'BIGINT' => 'NUMERIC', - 'REAL' => 'DOUBLE PRECISION', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '9.0', '>')) - { - $this->create_table_if = 'CREATE TABLE IF NOT EXISTS'; - } - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (version_compare($this->db->version(), '8', '>=') && isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .($field[$i]['null'] === TRUE ? ' DROP NOT NULL' : ' SET NOT NULL'); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - // Reset field lenghts for data types that don't support it - if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== FALSE) - { - $attributes['CONSTRAINT'] = NULL; - } - - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) - { - $field['type'] = ($field['type'] === 'NUMERIC') - ? 'BIGSERIAL' - : 'SERIAL'; - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlite_driver.php deleted file mode 100644 index 5a685fc..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_driver.php +++ /dev/null @@ -1,215 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLite Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlite_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'sqlite'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = ' RANDOM()'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'sqlite:'; - - if (empty($this->database) && empty($this->hostname)) - { - $this->database = ':memory:'; - } - - $this->database = empty($this->database) ? $this->hostname : $this->database; - } - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - return $sql.' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * @param string $table Table name - * @return array - */ - public function list_fields($table) - { - // Is there a cached result? - if (isset($this->data_cache['field_names'][$table])) - { - return $this->data_cache['field_names'][$table]; - } - - if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $this->data_cache['field_names'][$table] = array(); - foreach ($result->result_array() as $row) - { - $this->data_cache['field_names'][$table][] = $row['name']; - } - - return $this->data_cache['field_names'][$table]; - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $query = $query->result_array(); - if (empty($query)) - { - return FALSE; - } - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]['name']; - $retval[$i]->type = $query[$i]['type']; - $retval[$i]->max_length = NULL; - $retval[$i]->default = $query[$i]['dflt_value']; - $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'INSERT OR '.parent::_replace($table, $keys, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlite_forge.php deleted file mode 100644 index 294b127..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlite_forge.php +++ /dev/null @@ -1,235 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLite Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlite_forge extends FW_DB_pdo_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = 'DROP TABLE IF EXISTS'; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '3.3', '<')) - { - $this->_create_table_if = FALSE; - $this->_drop_table_if = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name (ignored) - * @return bool - */ - public function create_database($db_name = '') - { - // In SQLite, a database is created when you connect to the database. - // We'll return TRUE so that an error isn't generated - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - // In SQLite, a database is dropped when we delete a file - if (file_exists($this->db->database)) - { - // We need to close the pseudo-connection first - $this->db->close(); - if ( ! @unlink($this->db->database)) - { - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP' OR $alter_type === 'CHANGE') - { - // drop_column(): - // BEGIN TRANSACTION; - // CREATE TEMPORARY TABLE t1_backup(a,b); - // INSERT INTO t1_backup SELECT a,b FROM t1; - // DROP TABLE t1; - // CREATE TABLE t1(a,b); - // INSERT INTO t1 SELECT a,b FROM t1_backup; - // DROP TABLE t1_backup; - // COMMIT; - - return FALSE; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'] - .$field['auto_increment'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['TYPE'] = 'TEXT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['type'] = 'INTEGER PRIMARY KEY'; - $field['default'] = ''; - $field['null'] = ''; - $field['unique'] = ''; - $field['auto_increment'] = ' AUTOINCREMENT'; - - $this->primary_keys = array(); - } - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php deleted file mode 100644 index 102d84e..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php +++ /dev/null @@ -1,365 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLSRV Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlsrv_driver extends FW_DB_pdo_driver { - - /** - * Sub-driver - * - * @var string - */ - public $subdriver = 'sqlsrv'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('NEWID()', 'RAND(%d)'); - - /** - * Quoted identifier flag - * - * Whether to use SQL-92 standard quoted identifier - * (double quotes) or brackets for identifier escaping. - * - * @var bool - */ - protected $_quoted_identifier; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Builds the DSN if not already set. - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if (empty($this->dsn)) - { - $this->dsn = 'sqlsrv:Server='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname); - - empty($this->port) OR $this->dsn .= ','.$this->port; - empty($this->database) OR $this->dsn .= ';Database='.$this->database; - - // Some custom options - - if (isset($this->QuotedId)) - { - $this->dsn .= ';QuotedId='.$this->QuotedId; - $this->_quoted_identifier = (bool) $this->QuotedId; - } - - if (isset($this->ConnectionPooling)) - { - $this->dsn .= ';ConnectionPooling='.$this->ConnectionPooling; - } - - if ($this->encrypt === TRUE) - { - $this->dsn .= ';Encrypt=1'; - } - - if (isset($this->TraceOn)) - { - $this->dsn .= ';TraceOn='.$this->TraceOn; - } - - if (isset($this->TrustServerCertificate)) - { - $this->dsn .= ';TrustServerCertificate='.$this->TrustServerCertificate; - } - - empty($this->APP) OR $this->dsn .= ';APP='.$this->APP; - empty($this->Failover_Partner) OR $this->dsn .= ';Failover_Partner='.$this->Failover_Partner; - empty($this->LoginTimeout) OR $this->dsn .= ';LoginTimeout='.$this->LoginTimeout; - empty($this->MultipleActiveResultSets) OR $this->dsn .= ';MultipleActiveResultSets='.$this->MultipleActiveResultSets; - empty($this->TraceFile) OR $this->dsn .= ';TraceFile='.$this->TraceFile; - empty($this->WSID) OR $this->dsn .= ';WSID='.$this->WSID; - } - elseif (preg_match('/QuotedId=(0|1)/', $this->dsn, $match)) - { - $this->_quoted_identifier = (bool) $match[1]; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return object - */ - public function db_connect($persistent = FALSE) - { - if ( ! empty($this->char_set) && preg_match('/utf[^8]*8/i', $this->char_set)) - { - $this->options[PDO::SQLSRV_ENCODING_UTF8] = 1; - } - - $this->conn_id = parent::db_connect($persistent); - - if ( ! is_object($this->conn_id) OR is_bool($this->_quoted_identifier)) - { - return $this->conn_id; - } - - // Determine how identifiers are escaped - $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); - $query = $query->row_array(); - $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; - $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('name') - .' FROM '.$this->escape_identifiers('sysobjects') - .' WHERE '.$this->escape_identifiers('type')." = 'U'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql.' ORDER BY '.$this->escape_identifiers('name'); - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, COLUMN_DEFAULT - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - $retval[$i]->max_length = ($query[$i]->CHARACTER_MAXIMUM_LENGTH > 0) ? $query[$i]->CHARACTER_MAXIMUM_LENGTH : $query[$i]->NUMERIC_PRECISION; - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - return 'WITH fw_delete AS (SELECT TOP '.$this->qb_limit.' * FROM '.$table.$this->_compile_wh('qb_where').') DELETE FROM fw_delete'; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // As of SQL Server 2012 (11.0.*) OFFSET is supported - if (version_compare($this->version(), '11', '>=')) - { - // SQL Server OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - $limit = $this->qb_offset + $this->qb_limit; - - // An ORDER BY clause is required for ROW_NUMBER() to work - if ($this->qb_offset && ! empty($this->qb_orderby)) - { - $orderby = $this->_compile_order_by(); - - // We have to strip the ORDER BY clause - $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); - - // Get the fields to select from our subquery, so that we can avoid FW_rownum appearing in the actual results - if (count($this->qb_select) === 0) - { - $select = '*'; // Inevitable - } - else - { - // Use only field names and their aliases, everything else is out of our scope. - $select = array(); - $field_regexp = ($this->_quoted_identifier) - ? '("[^\"]+")' : '(\[[^\]]+\])'; - for ($i = 0, $c = count($this->qb_select); $i < $c; $i++) - { - $select[] = preg_match('/(?:\s|\.)'.$field_regexp.'$/i', $this->qb_select[$i], $m) - ? $m[1] : $this->qb_select[$i]; - } - $select = implode(', ', $select); - } - - return 'SELECT '.$select." FROM (\n\n" - .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.trim($orderby).') AS '.$this->escape_identifiers('FW_rownum').', ', $sql) - ."\n\n) ".$this->escape_identifiers('FW_subquery') - ."\nWHERE ".$this->escape_identifiers('FW_rownum').' BETWEEN '.($this->qb_offset + 1).' AND '.$limit; - } - - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string|bool - */ - protected function _insert_batch($table, $keys, $values) - { - // Multiple-value inserts are only supported as of SQL Server 2008 - if (version_compare($this->version(), '10', '>=')) - { - return parent::_insert_batch($table, $keys, $values); - } - - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - -} diff --git a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php b/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php deleted file mode 100644 index 46bd93a..0000000 --- a/src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php +++ /dev/null @@ -1,141 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * PDO SQLSRV Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_pdo_sqlsrv_forge extends FW_DB_pdo_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nCREATE TABLE"; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = "IF EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nDROP TABLE"; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT' => 'SMALLINT', - 'SMALLINT' => 'INT', - 'INT' => 'BIGINT', - 'REAL' => 'FLOAT' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' ALTER COLUMN '; - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql.$this->_process_column($field[$i]); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' IDENTITY(1,1)'; - } - } - -} diff --git a/src/Database/drivers/postgre/postgre_driver.php b/src/Database/drivers/postgre/postgre_driver.php deleted file mode 100644 index e9e6b47..0000000 --- a/src/Database/drivers/postgre/postgre_driver.php +++ /dev/null @@ -1,618 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Core; - -/** - * Postgre Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'postgre'; - - /** - * Database schema - * - * @var string - */ - public $schema = 'public'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Creates a DSN string to be used for db_connect() and db_pconnect() - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - if ( ! empty($this->dsn)) - { - return; - } - - $this->dsn === '' OR $this->dsn = ''; - - if (strpos($this->hostname, '/') !== FALSE) - { - // If UNIX sockets are used, we shouldn't set a port - $this->port = ''; - } - - $this->hostname === '' OR $this->dsn = 'host='.$this->hostname.' '; - - if ( ! empty($this->port) && ctype_digit($this->port)) - { - $this->dsn .= 'port='.$this->port.' '; - } - - if ($this->username !== '') - { - $this->dsn .= 'user='.$this->username.' '; - - /* An empty password is valid! - * - * $db['password'] = NULL must be done in order to ignore it. - */ - $this->password === NULL OR $this->dsn .= "password='".$this->password."' "; - } - - $this->database === '' OR $this->dsn .= 'dbname='.$this->database.' '; - - /* We don't have these options as elements in our standard configuration - * array, but they might be set by parse_url() if the configuration was - * provided via string. Example: - * - * postgre://username:password@localhost:5432/database?connect_timeout=5&sslmode=1 - */ - foreach (array('connect_timeout', 'options', 'sslmode', 'service') as $key) - { - if (isset($this->$key) && is_string($this->key) && $this->key !== '') - { - $this->dsn .= $key."='".$this->key."' "; - } - } - - $this->dsn = rtrim($this->dsn); - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - $this->conn_id = ($persistent === TRUE) - ? pg_pconnect($this->dsn) - : pg_connect($this->dsn); - - if ($this->conn_id !== FALSE) - { - if ($persistent === TRUE - && pg_connection_status($this->conn_id) === PGSQL_CONNECTION_BAD - && pg_ping($this->conn_id) === FALSE - ) - { - return FALSE; - } - - empty($this->schema) OR $this->simple_query('SET search_path TO '.$this->schema.',public'); - } - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Reconnect - * - * Keep / reestablish the db connection if no queries have been - * sent for a length of time exceeding the server's idle timeout - * - * @return void - */ - public function reconnect() - { - if (pg_ping($this->conn_id) === FALSE) - { - $this->conn_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Set client character set - * - * @param string $charset - * @return bool - */ - protected function _db_set_charset($charset) - { - return (pg_set_client_encoding($this->conn_id, $charset) === 0); - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if ( ! $this->conn_id OR ($pg_version = pg_version($this->conn_id)) === FALSE) - { - return FALSE; - } - - /* If PHP was compiled with PostgreSQL lib versions earlier - * than 7.4, pg_version() won't return the server version - * and so we'll have to fall back to running a query in - * order to get it. - */ - return isset($pg_version['server']) - ? $this->data_cache['version'] = $pg_version['server'] - : parent::version(); - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return pg_query($this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return (bool) pg_query($this->conn_id, 'BEGIN'); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return (bool) pg_query($this->conn_id, 'COMMIT'); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return (bool) pg_query($this->conn_id, 'ROLLBACK'); - } - - // -------------------------------------------------------------------- - - /** - * Determines if a query is a "write" type. - * - * @param string An SQL query string - * @return bool - */ - public function is_write_type($sql) - { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) - { - return FALSE; - } - - return parent::is_write_type($sql); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return pg_escape_string($this->conn_id, $str); - } - - // -------------------------------------------------------------------- - - /** - * "Smart" Escape String - * - * Escapes data based on type - * - * @param string $str - * @return mixed - */ - public function escape($str) - { - if (Core::isPHP('5.4.4') && (is_string($str) OR (is_object($str) && method_exists($str, '__toString')))) - { - return pg_escape_literal($this->conn_id, $str); - } - elseif (is_bool($str)) - { - return ($str) ? 'TRUE' : 'FALSE'; - } - - return parent::escape($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return pg_affected_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return string - */ - public function insert_id() - { - $v = pg_version($this->conn_id); - $v = isset($v['server']) ? $v['server'] : 0; // 'server' key is only available since PosgreSQL 7.4 - - $table = (func_num_args() > 0) ? func_get_arg(0) : NULL; - $column = (func_num_args() > 1) ? func_get_arg(1) : NULL; - - if ($table === NULL && $v >= '8.1') - { - $sql = 'SELECT LASTVAL() AS ins_id'; - } - elseif ($table !== NULL) - { - if ($column !== NULL && $v >= '8.0') - { - $sql = 'SELECT pg_get_serial_sequence(\''.$table."', '".$column."') AS seq"; - $query = $this->query($sql); - $query = $query->row(); - $seq = $query->seq; - } - else - { - // seq_name passed in table parameter - $seq = $table; - } - - $sql = 'SELECT CURRVAL(\''.$seq."') AS ins_id"; - } - else - { - return pg_last_oid($this->result_id); - } - - $query = $this->query($sql); - $query = $query->row(); - return (int) $query->ins_id; - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \''.$this->schema."'"; - - if ($prefix_limit !== FALSE && $this->dbprefix !== '') - { - return $sql.' AND "table_name" LIKE \'' - .$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * List column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT "column_name" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default" - FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->column_name; - $retval[$i]->type = $query[$i]->data_type; - $retval[$i]->max_length = ($query[$i]->character_maximum_length > 0) ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision; - $retval[$i]->default = $query[$i]->column_default; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => '', 'message' => pg_last_error($this->conn_id)); - } - - // -------------------------------------------------------------------- - - /** - * ORDER BY - * - * @param string $orderby - * @param string $direction ASC, DESC or RANDOM - * @param bool $escape - * @return object - */ - public function order_by($orderby, $direction = '', $escape = NULL) - { - $direction = strtoupper(trim($direction)); - if ($direction === 'RANDOM') - { - if ( ! is_float($orderby) && ctype_digit((string) $orderby)) - { - $orderby = ($orderby > 1) - ? (float) '0.'.$orderby - : (float) $orderby; - } - - if (is_float($orderby)) - { - $this->simple_query('SET SEED '.$orderby); - } - - $orderby = $this->_random_keyword[0]; - $direction = ''; - $escape = FALSE; - } - - return parent::order_by($orderby, $direction, $escape); - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = (CASE '.$index."\n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return $sql.' LIMIT '.$this->qb_limit.($this->qb_offset ? ' OFFSET '.$this->qb_offset : ''); - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - pg_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/postgre/postgre_forge.php b/src/Database/drivers/postgre/postgre_forge.php deleted file mode 100644 index 39495bf..0000000 --- a/src/Database/drivers/postgre/postgre_forge.php +++ /dev/null @@ -1,201 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Postgre Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_forge extends FW_DB_forge { - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'INT2' => 'INTEGER', - 'SMALLINT' => 'INTEGER', - 'INT' => 'BIGINT', - 'INT4' => 'BIGINT', - 'INTEGER' => 'BIGINT', - 'INT8' => 'NUMERIC', - 'BIGINT' => 'NUMERIC', - 'REAL' => 'DOUBLE PRECISION', - 'FLOAT' => 'DOUBLE PRECISION' - ); - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '9.0', '>')) - { - $this->create_table_if = 'CREATE TABLE IF NOT EXISTS'; - } - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table); - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - if ($field[$i]['_literal'] !== FALSE) - { - return FALSE; - } - - if (version_compare($this->db->version(), '8', '>=') && isset($field[$i]['type'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TYPE '.$field[$i]['type'].$field[$i]['length']; - } - - if ( ! empty($field[$i]['default'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; - } - - if (isset($field[$i]['null'])) - { - $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .($field[$i]['null'] === TRUE ? ' DROP NOT NULL' : ' SET NOT NULL'); - } - - if ( ! empty($field[$i]['new_name'])) - { - $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' TO '.$this->db->escape_identifiers($field[$i]['new_name']); - } - - if ( ! empty($field[$i]['comment'])) - { - $sqls[] = 'COMMENT ON COLUMN ' - .$this->db->escape_identifiers($table).'.'.$this->db->escape_identifiers($field[$i]['name']) - .' IS '.$field[$i]['comment']; - } - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - // Reset field lenghts for data types that don't support it - if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== FALSE) - { - $attributes['CONSTRAINT'] = NULL; - } - - switch (strtoupper($attributes['TYPE'])) - { - case 'TINYINT': - $attributes['TYPE'] = 'SMALLINT'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) - { - $field['type'] = ($field['type'] === 'NUMERIC') - ? 'BIGSERIAL' - : 'SERIAL'; - } - } - -} diff --git a/src/Database/drivers/postgre/postgre_result.php b/src/Database/drivers/postgre/postgre_result.php deleted file mode 100644 index d0a8433..0000000 --- a/src/Database/drivers/postgre/postgre_result.php +++ /dev/null @@ -1,178 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Postgres Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = pg_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return pg_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field_names[] = pg_field_name($this->result_id, $i); - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = pg_field_name($this->result_id, $i); - $retval[$i]->type = pg_field_type($this->result_id, $i); - $retval[$i]->max_length = pg_field_size($this->result_id, $i); - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - pg_free_result($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return pg_result_seek($this->result_id, $n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return pg_fetch_assoc($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return pg_fetch_object($this->result_id, NULL, $class_name); - } - -} diff --git a/src/Database/drivers/postgre/postgre_utility.php b/src/Database/drivers/postgre/postgre_utility.php deleted file mode 100644 index adc3a90..0000000 --- a/src/Database/drivers/postgre/postgre_utility.php +++ /dev/null @@ -1,74 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * Postgre Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_postgre_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'SELECT datname FROM pg_database'; - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = 'REINDEX TABLE %s'; - - // -------------------------------------------------------------------- - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } -} diff --git a/src/Database/drivers/sqlite/sqlite_driver.php b/src/Database/drivers/sqlite/sqlite_driver.php deleted file mode 100644 index 4714d91..0000000 --- a/src/Database/drivers/sqlite/sqlite_driver.php +++ /dev/null @@ -1,328 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; - -/** - * SQLite Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'sqlite'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return resource - */ - public function db_connect($persistent = FALSE) - { - $error = NULL; - $conn_id = ($persistent === TRUE) - ? sqlite_popen($this->database, 0666, $error) - : sqlite_open($this->database, 0666, $error); - - isset($error) && Logger::logError($error); - - return $conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - return isset($this->data_cache['version']) - ? $this->data_cache['version'] - : $this->data_cache['version'] = sqlite_libversion(); - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return $this->is_write_type($sql) - ? sqlite_exec($this->conn_id, $sql) - : sqlite_query($this->conn_id, $sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return $this->simple_query('BEGIN TRANSACTION'); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return $this->simple_query('COMMIT'); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return $this->simple_query('ROLLBACK'); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return sqlite_escape_string($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return sqlite_changes($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return sqlite_last_insert_rowid($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = "SELECT name FROM sqlite_master WHERE type='table'"; - - if ($prefix_limit !== FALSE && $this->dbprefix != '') - { - return $sql." AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr); - } - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Show column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return bool - */ - protected function _list_columns($table = '') - { - // Not supported - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $query = $query->result_array(); - if (empty($query)) - { - return FALSE; - } - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]['name']; - $retval[$i]->type = $query[$i]['type']; - $retval[$i]->max_length = NULL; - $retval[$i]->default = $query[$i]['dflt_value']; - $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - $error = array('code' => sqlite_last_error($this->conn_id)); - $error['message'] = sqlite_error_string($error['code']); - return $error; - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * Generates a platform-specific replace string from the supplied data - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'INSERT OR '.parent::_replace($table, $keys, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this function maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - sqlite_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/sqlite/sqlite_forge.php b/src/Database/drivers/sqlite/sqlite_forge.php deleted file mode 100644 index a4e4abc..0000000 --- a/src/Database/drivers/sqlite/sqlite_forge.php +++ /dev/null @@ -1,202 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = FALSE; - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name (ignored) - * @return bool - */ - public function create_database($db_name = '') - { - // In SQLite, a database is created when you connect to the database. - // We'll return TRUE so that an error isn't generated - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - if ( ! file_exists($this->db->database) OR ! @unlink($this->db->database)) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @todo implement drop_column(), modify_column() - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP' OR $alter_type === 'CHANGE') - { - // drop_column(): - // BEGIN TRANSACTION; - // CREATE TEMPORARY TABLE t1_backup(a,b); - // INSERT INTO t1_backup SELECT a,b FROM t1; - // DROP TABLE t1; - // CREATE TABLE t1(a,b); - // INSERT INTO t1 SELECT a,b FROM t1_backup; - // DROP TABLE t1_backup; - // COMMIT; - - return FALSE; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'] - .$field['auto_increment'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['TYPE'] = 'TEXT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['type'] = 'INTEGER PRIMARY KEY'; - $field['default'] = ''; - $field['null'] = ''; - $field['unique'] = ''; - $field['auto_increment'] = ' AUTOINCREMENT'; - - $this->primary_keys = array(); - } - } - -} diff --git a/src/Database/drivers/sqlite/sqlite_result.php b/src/Database/drivers/sqlite/sqlite_result.php deleted file mode 100644 index 8284fa1..0000000 --- a/src/Database/drivers/sqlite/sqlite_result.php +++ /dev/null @@ -1,161 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_result extends FW_DB_result { - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = @sqlite_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return @sqlite_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field_names[$i] = sqlite_field_name($this->result_id, $i); - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = sqlite_field_name($this->result_id, $i); - $retval[$i]->type = NULL; - $retval[$i]->max_length = NULL; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n - * @return bool - */ - public function data_seek($n = 0) - { - return sqlite_seek($this->result_id, $n); - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return sqlite_fetch_array($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return sqlite_fetch_object($this->result_id, $class_name); - } - -} diff --git a/src/Database/drivers/sqlite/sqlite_utility.php b/src/Database/drivers/sqlite/sqlite_utility.php deleted file mode 100644 index af8dc80..0000000 --- a/src/Database/drivers/sqlite/sqlite_utility.php +++ /dev/null @@ -1,58 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_driver.php b/src/Database/drivers/sqlite3/sqlite3_driver.php deleted file mode 100644 index e4a83dd..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_driver.php +++ /dev/null @@ -1,349 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; -use \Exception; - -/** - * SQLite3 Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'sqlite3'; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('RANDOM()', 'RANDOM()'); - - // -------------------------------------------------------------------- - - /** - * Non-persistent database connection - * - * @param bool $persistent - * @return SQLite3 - */ - public function db_connect($persistent = FALSE) - { - if ($persistent) - { - Logger::logDebug('SQLite3 doesn\'t support persistent connections'); - } - - try - { - return ( ! $this->password) - ? new SQLite3($this->database) - : new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password); - } - catch (Exception $e) - { - return FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - $version = SQLite3::version(); - return $this->data_cache['version'] = $version['versionString']; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @todo Implement use of SQLite3::querySingle(), if needed - * @param string $sql - * @return mixed SQLite3Result object or bool - */ - protected function _execute($sql) - { - return $this->is_write_type($sql) - ? $this->conn_id->exec($sql) - : $this->conn_id->query($sql); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return $this->conn_id->exec('BEGIN TRANSACTION'); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return $this->conn_id->exec('END TRANSACTION'); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return $this->conn_id->exec('ROLLBACK'); - } - - // -------------------------------------------------------------------- - - /** - * Platform-dependant string escape - * - * @param string - * @return string - */ - protected function _escape_str($str) - { - return $this->conn_id->escapeString($str); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return $this->conn_id->changes(); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * @return int - */ - public function insert_id() - { - return $this->conn_id->lastInsertRowID(); - } - - // -------------------------------------------------------------------- - - /** - * Show table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool $prefix_limit - * @return string - */ - protected function _list_tables($prefix_limit = FALSE) - { - return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\'' - .(($prefix_limit !== FALSE && $this->dbprefix != '') - ? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr) - : ''); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * @param string $table Table name - * @return array - */ - public function list_fields($table) - { - // Is there a cached result? - if (isset($this->data_cache['field_names'][$table])) - { - return $this->data_cache['field_names'][$table]; - } - - if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $this->data_cache['field_names'][$table] = array(); - foreach ($result->result_array() as $row) - { - $this->data_cache['field_names'][$table][] = $row['name']; - } - - return $this->data_cache['field_names'][$table]; - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) - { - return FALSE; - } - - $query = $query->result_array(); - if (empty($query)) - { - return FALSE; - } - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]['name']; - $retval[$i]->type = $query[$i]['type']; - $retval[$i]->max_length = NULL; - $retval[$i]->default = $query[$i]['dflt_value']; - $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - return array('code' => $this->conn_id->lastErrorCode(), 'message' => $this->conn_id->lastErrorMsg()); - } - - // -------------------------------------------------------------------- - - /** - * Replace statement - * - * Generates a platform-specific replace string from the supplied data - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string - */ - protected function _replace($table, $keys, $values) - { - return 'INSERT OR '.parent::_replace($table, $keys, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - $this->conn_id->close(); - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_forge.php b/src/Database/drivers/sqlite3/sqlite3_forge.php deleted file mode 100644 index d8d67c8..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_forge.php +++ /dev/null @@ -1,222 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite3 Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_forge extends FW_DB_forge { - - /** - * UNSIGNED support - * - * @var bool|array - */ - protected $_unsigned = FALSE; - - /** - * NULL value representation in CREATE/ALTER TABLE statements - * - * @var string - */ - protected $_null = 'NULL'; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param object &$db Database object - * @return void - */ - public function __construct(&$db) - { - parent::__construct($db); - - if (version_compare($this->db->version(), '3.3', '<')) - { - $this->_create_table_if = FALSE; - $this->_drop_table_if = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Create database - * - * @param string $db_name - * @return bool - */ - public function create_database($db_name = '') - { - // In SQLite, a database is created when you connect to the database. - // We'll return TRUE so that an error isn't generated - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Drop database - * - * @param string $db_name (ignored) - * @return bool - */ - public function drop_database($db_name = '') - { - // In SQLite, a database is dropped when we delete a file - if (file_exists($this->db->database)) - { - // We need to close the pseudo-connection first - $this->db->close(); - if ( ! @unlink($this->db->database)) - { - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - elseif ( ! empty($this->db->data_cache['db_names'])) - { - $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); - if ($key !== FALSE) - { - unset($this->db->data_cache['db_names'][$key]); - } - } - - return TRUE; - } - - return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @todo implement drop_column(), modify_column() - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if ($alter_type === 'DROP' OR $alter_type === 'CHANGE') - { - // drop_column(): - // BEGIN TRANSACTION; - // CREATE TEMPORARY TABLE t1_backup(a,b); - // INSERT INTO t1_backup SELECT a,b FROM t1; - // DROP TABLE t1; - // CREATE TABLE t1(a,b); - // INSERT INTO t1 SELECT a,b FROM t1_backup; - // DROP TABLE t1_backup; - // COMMIT; - - return FALSE; - } - - return parent::_alter_table($alter_type, $table, $field); - } - - // -------------------------------------------------------------------- - - /** - * Process column - * - * @param array $field - * @return string - */ - protected function _process_column($field) - { - return $this->db->escape_identifiers($field['name']) - .' '.$field['type'] - .$field['auto_increment'] - .$field['null'] - .$field['unique'] - .$field['default']; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'ENUM': - case 'SET': - $attributes['TYPE'] = 'TEXT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['type'] = 'INTEGER PRIMARY KEY'; - $field['default'] = ''; - $field['null'] = ''; - $field['unique'] = ''; - $field['auto_increment'] = ' AUTOINCREMENT'; - - $this->primary_keys = array(); - } - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_result.php b/src/Database/drivers/sqlite3/sqlite3_result.php deleted file mode 100644 index b78ac15..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_result.php +++ /dev/null @@ -1,191 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite3 Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_result extends FW_DB_result { - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return $this->result_id->numColumns(); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $field_names[] = $this->result_id->columnName($i); - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - static $data_types = array( - SQLITE3_INTEGER => 'integer', - SQLITE3_FLOAT => 'float', - SQLITE3_TEXT => 'text', - SQLITE3_BLOB => 'blob', - SQLITE3_NULL => 'null' - ); - - $retval = array(); - for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $this->result_id->columnName($i); - - $type = $this->result_id->columnType($i); - $retval[$i]->type = isset($data_types[$type]) ? $data_types[$type] : $type; - - $retval[$i]->max_length = NULL; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_object($this->result_id)) - { - $this->result_id->finalize(); - $this->result_id = NULL; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return $this->result_id->fetchArray(SQLITE3_ASSOC); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - // No native support for fetching rows as objects - if (($row = $this->result_id->fetchArray(SQLITE3_ASSOC)) === FALSE) - { - return FALSE; - } - elseif ($class_name === 'stdClass') - { - return (object) $row; - } - - $class_name = new $class_name(); - foreach (array_keys($row) as $key) - { - $class_name->$key = $row[$key]; - } - - return $class_name; - } - - // -------------------------------------------------------------------- - - /** - * Data Seek - * - * Moves the internal pointer to the desired offset. We call - * this internally before fetching results to make sure the - * result set starts at zero. - * - * @param int $n (ignored) - * @return array - */ - public function data_seek($n = 0) - { - // Only resetting to the start of the result set is supported - return ($n > 0) ? FALSE : $this->result_id->reset(); - } - -} diff --git a/src/Database/drivers/sqlite3/sqlite3_utility.php b/src/Database/drivers/sqlite3/sqlite3_utility.php deleted file mode 100644 index 4d43081..0000000 --- a/src/Database/drivers/sqlite3/sqlite3_utility.php +++ /dev/null @@ -1,58 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLite3 Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlite3_utility extends FW_DB_utility { - - /** - * Export - * - * @param array $params Preferences - * @return mixed - */ - protected function _backup($params = array()) - { - // Not supported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_driver.php b/src/Database/drivers/sqlsrv/sqlsrv_driver.php deleted file mode 100644 index cc5256e..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_driver.php +++ /dev/null @@ -1,538 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Database Adapter Class - * - * Note: _DB is an extender class that the app controller - * creates dynamically based on whether the query builder - * class is being used or not. - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Drivers - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_driver extends FW_DB { - - /** - * Database driver - * - * @var string - */ - public $dbdriver = 'sqlsrv'; - - /** - * Scrollable flag - * - * Determines what cursor type to use when executing queries. - * - * FALSE or SQLSRV_CURSOR_FORWARD would increase performance, - * but would disable num_rows() (and possibly insert_id()) - * - * @var mixed - */ - public $scrollable; - - // -------------------------------------------------------------------- - - /** - * ORDER BY random keyword - * - * @var array - */ - protected $_random_keyword = array('NEWID()', 'RAND(%d)'); - - /** - * Quoted identifier flag - * - * Whether to use SQL-92 standard quoted identifier - * (double quotes) or brackets for identifier escaping. - * - * @var bool - */ - protected $_quoted_identifier = TRUE; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * @param array $params - * @return void - */ - public function __construct($params) - { - parent::__construct($params); - - // This is only supported as of SQLSRV 3.0 - if ($this->scrollable === NULL) - { - $this->scrollable = defined('SQLSRV_CURSOR_CLIENT_BUFFERED') - ? SQLSRV_CURSOR_CLIENT_BUFFERED - : FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Database connection - * - * @param bool $pooling - * @return resource - */ - public function db_connect($pooling = FALSE) - { - $charset = in_array(strtolower($this->char_set), array('utf-8', 'utf8'), TRUE) - ? 'UTF-8' : SQLSRV_ENC_CHAR; - - $connection = array( - 'UID' => empty($this->username) ? '' : $this->username, - 'PWD' => empty($this->password) ? '' : $this->password, - 'Database' => $this->database, - 'ConnectionPooling' => ($pooling === TRUE) ? 1 : 0, - 'CharacterSet' => $charset, - 'Encrypt' => ($this->encrypt === TRUE) ? 1 : 0, - 'ReturnDatesAsStrings' => 1 - ); - - // If the username and password are both empty, assume this is a - // 'Windows Authentication Mode' connection. - if (empty($connection['UID']) && empty($connection['PWD'])) - { - unset($connection['UID'], $connection['PWD']); - } - - if (FALSE !== ($this->conn_id = sqlsrv_connect($this->hostname, $connection))) - { - // Determine how identifiers are escaped - $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); - $query = $query->row_array(); - $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; - $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); - } - - return $this->conn_id; - } - - // -------------------------------------------------------------------- - - /** - * Select the database - * - * @param string $database - * @return bool - */ - public function db_select($database = '') - { - if ($database === '') - { - $database = $this->database; - } - - if ($this->_execute('USE '.$this->escape_identifiers($database))) - { - $this->database = $database; - return TRUE; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Execute the query - * - * @param string $sql an SQL query - * @return resource - */ - protected function _execute($sql) - { - return ($this->scrollable === FALSE OR $this->is_write_type($sql)) - ? sqlsrv_query($this->conn_id, $sql) - : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => $this->scrollable)); - } - - // -------------------------------------------------------------------- - - /** - * Begin Transaction - * - * @return bool - */ - protected function _trans_begin() - { - return sqlsrv_begin_transaction($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Commit Transaction - * - * @return bool - */ - protected function _trans_commit() - { - return sqlsrv_commit($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Rollback Transaction - * - * @return bool - */ - protected function _trans_rollback() - { - return sqlsrv_rollback($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Affected Rows - * - * @return int - */ - public function affected_rows() - { - return sqlsrv_rows_affected($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Insert ID - * - * Returns the last id created in the Identity column. - * - * @return string - */ - public function insert_id() - { - return $this->query('SELECT SCOPE_IDENTITY() AS insert_id')->row()->insert_id; - } - - // -------------------------------------------------------------------- - - /** - * Database version number - * - * @return string - */ - public function version() - { - if (isset($this->data_cache['version'])) - { - return $this->data_cache['version']; - } - - if ( ! $this->conn_id OR ($info = sqlsrv_server_info($this->conn_id)) === FALSE) - { - return FALSE; - } - - return $this->data_cache['version'] = $info['SQLServerVersion']; - } - - // -------------------------------------------------------------------- - - /** - * List table query - * - * Generates a platform-specific query string so that the table names can be fetched - * - * @param bool - * @return string $prefix_limit - */ - protected function _list_tables($prefix_limit = FALSE) - { - $sql = 'SELECT '.$this->escape_identifiers('name') - .' FROM '.$this->escape_identifiers('sysobjects') - .' WHERE '.$this->escape_identifiers('type')." = 'U'"; - - if ($prefix_limit === TRUE && $this->dbprefix !== '') - { - $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " - .sprintf($this->_escape_like_str, $this->_escape_like_chr); - } - - return $sql.' ORDER BY '.$this->escape_identifiers('name'); - } - - // -------------------------------------------------------------------- - - /** - * List column query - * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string - */ - protected function _list_columns($table = '') - { - return 'SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - } - - // -------------------------------------------------------------------- - - /** - * Returns an object with field data - * - * @param string $table - * @return array - */ - public function field_data($table) - { - $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, COLUMN_DEFAULT - FROM INFORMATION_SCHEMA.Columns - WHERE UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table)); - - if (($query = $this->query($sql)) === FALSE) - { - return FALSE; - } - $query = $query->result_object(); - - $retval = array(); - for ($i = 0, $c = count($query); $i < $c; $i++) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $query[$i]->COLUMN_NAME; - $retval[$i]->type = $query[$i]->DATA_TYPE; - $retval[$i]->max_length = ($query[$i]->CHARACTER_MAXIMUM_LENGTH > 0) ? $query[$i]->CHARACTER_MAXIMUM_LENGTH : $query[$i]->NUMERIC_PRECISION; - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Error - * - * Returns an array containing code and message of the last - * database error that has occured. - * - * @return array - */ - public function error() - { - $error = array('code' => '00000', 'message' => ''); - $sqlsrv_errors = sqlsrv_errors(SQLSRV_ERR_ERRORS); - - if ( ! is_array($sqlsrv_errors)) - { - return $error; - } - - $sqlsrv_error = array_shift($sqlsrv_errors); - if (isset($sqlsrv_error['SQLSTATE'])) - { - $error['code'] = isset($sqlsrv_error['code']) ? $sqlsrv_error['SQLSTATE'].'/'.$sqlsrv_error['code'] : $sqlsrv_error['SQLSTATE']; - } - elseif (isset($sqlsrv_error['code'])) - { - $error['code'] = $sqlsrv_error['code']; - } - - if (isset($sqlsrv_error['message'])) - { - $error['message'] = $sqlsrv_error['message']; - } - - return $error; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'TRUNCATE TABLE '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - if ($this->qb_limit) - { - return 'WITH fw_delete AS (SELECT TOP '.$this->qb_limit.' * FROM '.$table.$this->_compile_wh('qb_where').') DELETE FROM fw_delete'; - } - - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - // As of SQL Server 2012 (11.0.*) OFFSET is supported - if (version_compare($this->version(), '11', '>=')) - { - // SQL Server OFFSET-FETCH can be used only with the ORDER BY clause - empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; - - return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; - } - - $limit = $this->qb_offset + $this->qb_limit; - - // An ORDER BY clause is required for ROW_NUMBER() to work - if ($this->qb_offset && ! empty($this->qb_orderby)) - { - $orderby = $this->_compile_order_by(); - - // We have to strip the ORDER BY clause - $sql = trim(substr($sql, 0, strrpos($sql, $orderby))); - - // Get the fields to select from our subquery, so that we can avoid FW_rownum appearing in the actual results - if (count($this->qb_select) === 0) - { - $select = '*'; // Inevitable - } - else - { - // Use only field names and their aliases, everything else is out of our scope. - $select = array(); - $field_regexp = ($this->_quoted_identifier) - ? '("[^\"]+")' : '(\[[^\]]+\])'; - for ($i = 0, $c = count($this->qb_select); $i < $c; $i++) - { - $select[] = preg_match('/(?:\s|\.)'.$field_regexp.'$/i', $this->qb_select[$i], $m) - ? $m[1] : $this->qb_select[$i]; - } - $select = implode(', ', $select); - } - - return 'SELECT '.$select." FROM (\n\n" - .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.trim($orderby).') AS '.$this->escape_identifiers('FW_rownum').', ', $sql) - ."\n\n) ".$this->escape_identifiers('FW_subquery') - ."\nWHERE ".$this->escape_identifiers('FW_rownum').' BETWEEN '.($this->qb_offset + 1).' AND '.$limit; - } - - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql); - } - - // -------------------------------------------------------------------- - - /** - * Insert batch statement - * - * Generates a platform-specific insert string from the supplied data. - * - * @param string $table Table name - * @param array $keys INSERT keys - * @param array $values INSERT values - * @return string|bool - */ - protected function _insert_batch($table, $keys, $values) - { - // Multiple-value inserts are only supported as of SQL Server 2008 - if (version_compare($this->version(), '10', '>=')) - { - return parent::_insert_batch($table, $keys, $values); - } - - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Close DB Connection - * - * @return void - */ - protected function _close() - { - sqlsrv_close($this->conn_id); - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_forge.php b/src/Database/drivers/sqlsrv/sqlsrv_forge.php deleted file mode 100644 index ec5674b..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_forge.php +++ /dev/null @@ -1,141 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Forge Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_forge extends FW_DB_forge { - - /** - * CREATE TABLE IF statement - * - * @var string - */ - protected $_create_table_if = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nCREATE TABLE"; - - /** - * DROP TABLE IF statement - * - * @var string - */ - protected $_drop_table_if = "IF EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'%s') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\nDROP TABLE"; - - /** - * UNSIGNED support - * - * @var array - */ - protected $_unsigned = array( - 'TINYINT' => 'SMALLINT', - 'SMALLINT' => 'INT', - 'INT' => 'BIGINT', - 'REAL' => 'FLOAT' - ); - - // -------------------------------------------------------------------- - - /** - * ALTER TABLE - * - * @param string $alter_type ALTER type - * @param string $table Table name - * @param mixed $field Column definition - * @return string|string[] - */ - protected function _alter_table($alter_type, $table, $field) - { - if (in_array($alter_type, array('ADD', 'DROP'), TRUE)) - { - return parent::_alter_table($alter_type, $table, $field); - } - - $sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' ALTER COLUMN '; - $sqls = array(); - for ($i = 0, $c = count($field); $i < $c; $i++) - { - $sqls[] = $sql.$this->_process_column($field[$i]); - } - - return $sqls; - } - - // -------------------------------------------------------------------- - - /** - * Field attribute TYPE - * - * Performs a data type mapping between different databases. - * - * @param array &$attributes - * @return void - */ - protected function _attr_type(&$attributes) - { - switch (strtoupper($attributes['TYPE'])) - { - case 'MEDIUMINT': - $attributes['TYPE'] = 'INTEGER'; - $attributes['UNSIGNED'] = FALSE; - return; - case 'INTEGER': - $attributes['TYPE'] = 'INT'; - return; - default: return; - } - } - - // -------------------------------------------------------------------- - - /** - * Field attribute AUTO_INCREMENT - * - * @param array &$attributes - * @param array &$field - * @return void - */ - protected function _attr_auto_increment(&$attributes, &$field) - { - if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) - { - $field['auto_increment'] = ' IDENTITY(1,1)'; - } - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_result.php b/src/Database/drivers/sqlsrv/sqlsrv_result.php deleted file mode 100644 index c241eca..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_result.php +++ /dev/null @@ -1,190 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Result Class - * - * This class extends the parent result class: FW_DB_result - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_result extends FW_DB_result { - - /** - * Scrollable flag - * - * @var mixed - */ - public $scrollable; - - // -------------------------------------------------------------------- - - /** - * Constructor - * - * @param object $driver_object - * @return void - */ - public function __construct(&$driver_object) - { - parent::__construct($driver_object); - - $this->scrollable = $driver_object->scrollable; - } - - // -------------------------------------------------------------------- - - /** - * Number of rows in the result set - * - * @return int - */ - public function num_rows() - { - // sqlsrv_num_rows() doesn't work with the FORWARD and DYNAMIC cursors (FALSE is the same as FORWARD) - if ( ! in_array($this->scrollable, array(FALSE, SQLSRV_CURSOR_FORWARD, SQLSRV_CURSOR_DYNAMIC), TRUE)) - { - return parent::num_rows(); - } - - return is_int($this->num_rows) - ? $this->num_rows - : $this->num_rows = sqlsrv_num_rows($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Number of fields in the result set - * - * @return int - */ - public function num_fields() - { - return @sqlsrv_num_fields($this->result_id); - } - - // -------------------------------------------------------------------- - - /** - * Fetch Field Names - * - * Generates an array of column names - * - * @return array - */ - public function list_fields() - { - $field_names = array(); - foreach (sqlsrv_field_metadata($this->result_id) as $offset => $field) - { - $field_names[] = $field['Name']; - } - - return $field_names; - } - - // -------------------------------------------------------------------- - - /** - * Field data - * - * Generates an array of objects containing field meta-data - * - * @return array - */ - public function field_data() - { - $retval = array(); - foreach (sqlsrv_field_metadata($this->result_id) as $i => $field) - { - $retval[$i] = new stdClass(); - $retval[$i]->name = $field['Name']; - $retval[$i]->type = $field['Type']; - $retval[$i]->max_length = $field['Size']; - } - - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Free the result - * - * @return void - */ - public function free_result() - { - if (is_resource($this->result_id)) - { - sqlsrv_free_stmt($this->result_id); - $this->result_id = FALSE; - } - } - - // -------------------------------------------------------------------- - - /** - * Result - associative array - * - * Returns the result set as an array - * - * @return array - */ - protected function _fetch_assoc() - { - return sqlsrv_fetch_array($this->result_id, SQLSRV_FETCH_ASSOC); - } - - // -------------------------------------------------------------------- - - /** - * Result - object - * - * Returns the result set as an object - * - * @param string $class_name - * @return object - */ - protected function _fetch_object($class_name = 'stdClass') - { - return sqlsrv_fetch_object($this->result_id, $class_name); - } - -} diff --git a/src/Database/drivers/sqlsrv/sqlsrv_utility.php b/src/Database/drivers/sqlsrv/sqlsrv_utility.php deleted file mode 100644 index 91efcd6..0000000 --- a/src/Database/drivers/sqlsrv/sqlsrv_utility.php +++ /dev/null @@ -1,74 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * SQLSRV Utility Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @category Database - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_DB_sqlsrv_utility extends FW_DB_utility { - - /** - * List databases statement - * - * @var string - */ - protected $_list_databases = 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases - - /** - * OPTIMIZE TABLE statement - * - * @var string - */ - protected $_optimize_table = 'ALTER INDEX all ON %s REORGANIZE'; - - // -------------------------------------------------------------------- - - /** - * Export - * - * @param array $params Preferences - * @return bool - */ - protected function _backup($params = array()) - { - // Currently unsupported - return $this->db->display_error('db_unsupported_feature'); - } - -} diff --git a/src/FuzeWorks/Config.php b/src/FuzeWorks/Config.php index d1ad958..71c22a4 100644 --- a/src/FuzeWorks/Config.php +++ b/src/FuzeWorks/Config.php @@ -64,7 +64,7 @@ class Config public function __construct() { - $this->configPaths[] = Core::$appDir . DS. 'Config'; + $this->configPaths = Core::$appDirs; } /** diff --git a/src/FuzeWorks/Configurator.php b/src/FuzeWorks/Configurator.php index eff42f7..f9f1a8e 100644 --- a/src/FuzeWorks/Configurator.php +++ b/src/FuzeWorks/Configurator.php @@ -4,7 +4,7 @@ * * The FuzeWorks MVC PHP FrameWork * - * Copyright (C) 2015 TechFuze + * Copyright (C) 2018 TechFuze * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +27,7 @@ * @link http://techfuze.net/fuzeworks * @since Version 0.0.1 * - * @version Version 1.0.0 + * @version Version 1.2.0 */ namespace FuzeWorks; @@ -44,110 +44,214 @@ use Tracy\Debugger; * * This allows for more flexible startups. * @author Abel Hoogeveen - * @author David Grudl - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) + * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) */ class Configurator { + /** * The parameters that will be passed to FuzeWorks. * * @var array */ - protected $parameters; + protected $parameters = ['debugEnabled' => false]; + + /** + * Components that will be attached to the Factory. + * + * @var array Array of classnames + */ + protected $components = []; + + /** + * Directories that will be passed to FuzeWorks components. + * + * These are NOT the temp and log directory. + * + * @var array of directories + */ + protected $directories = ['app' => []]; + + /** + * Plugins that can be loaded outside of a directory and through a classname. + * + * @var array of plugins + */ + protected $plugins = []; + + /** + * Libraries that can be loaded outside of a directory and through a classname. + * + * @var array of plugins + */ + protected $libraries = []; const COOKIE_SECRET = 'fuzeworks-debug'; - /** - * Constructs the Configurator class. - * - * Loads the default parameters - */ - public function __construct() - { - $this->parameters = $this->getDefaultParameters(); - } + /* ---------------- Core Directories--------------------- */ /** - * @return array + * Sets path to temporary directory. */ - protected function getDefaultParameters(): array + public function setLogDirectory($path) { - $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - $last = end($trace); - $debugMode = static::detectDebugMode(); - return [ - 'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL, - 'wwwDir' => isset($last['file']) ? dirname($last['file']) : NULL, - 'debugMode' => $debugMode - ]; + if (!is_dir($path)) + throw new InvalidArgumentException("Could not set log directory. Directory does not exist", 1); + $this->parameters['logDir'] = $path; } /** * Sets path to temporary directory. - * @return self */ - public function setLogDirectory($path): self + public function setTempDirectory($path) { - $this->parameters['logDir'] = $path; - return $this; + if (!is_dir($path)) + throw new InvalidArgumentException("Could not set temp directory. Directory does not exist", 1); + $this->parameters['tempDir'] = $path; } + /* ---------------- Components -------------------------- */ + + /** + * Registers a component that will be added to the Factory when the container is built + */ + public function addComponent(array $components) + { + foreach ($components as $componentName => $componentClass) { + $this->components[$componentName] = $componentClass; + } + } + + /** + * Registers a plugin that will be loaded outside of a directory + * + * @param array Array with pluginName and pluginClass ('name' => 'classname') + */ + public function addPlugin(array $plugin) + { + foreach ($plugin as $key => $value) { + $this->plugins[$key] = $value; + } + } + + /** + * Registers a library that will be loaded outside of a directory + * + * @param array Array with libraryName and libraryClass ('name' => 'classname') + */ + public function addLibrary(array $library) + { + foreach ($library as $key => $value) { + $this->libraries[$key] = $value; + } + } + + /* ---------------- App Directories --------------------- */ + + public function addAppDirectory(string $directory) + { + $this->directories['app'][] = $directory; + } + + /*public function addConfigDirectory(string $directory) + { + $this->directories['config'][] = $directory; + } + + public function addEventDirectory(string $directory) + { + $this->directories['events'][] = $directory; + } + + public function addHelperDirectory(string $directory) + { + $this->directories['helpers'][] = $directory; + } + + public function addLibraryDirectory(string $directory) + { + $this->directories['libraries'][] = $directory; + } + + public function addPluginDirectory(string $directory) + { + $this->directories['plugins'][] = $directory; + }*/ + + // @todo How do we add these dynamically for components? + + /* ---------------- Other Features ---------------------- */ /** * Sets the default timezone. - * @return self */ - public function setTimeZone($timezone): self + public function setTimeZone($timezone) { - date_default_timezone_set($timezone); + if (!date_default_timezone_set($timezone)) + throw new InvalidArgumentException("Could not set timezone. Invalid timezone provided.", 1); @ini_set('date.timezone', $timezone); // @ - function may be disabled - return $this; } /** - * Adds new parameters. The %params% will be expanded. - * @return self + * Adds new parameters. Use to quickly set multiple parameters at once */ - public function setParameters(array $params): self + public function setParameters(array $params) { foreach ($params as $key => $value) { $this->parameters[$key] = $value; } - return $this; + } + + /* ---------------- Debug Mode -------------------------- */ + + /** + * Fully enable or disable debug mode using one variable + */ + public function enableDebugMode(bool $bool = true) + { + $this->parameters['debugEnabled'] = $bool; } /** - * Sets path to temporary directory. - * @return self + * Provide a string from where debug mode can be accessed. + * Can be the following type of addresses: + * @todo */ - public function setTempDirectory($path): self + public function setDebugAddress($address = 'NONE') { - $this->parameters['tempDir'] = $path; - return $this; - } + // First we fetch the list + if (!is_string($address) && !is_array($address)) + throw new InvalidArgumentException("Can not set debug address. Address must be a string or array",1); - /** - * @return bool - */ - public function isDebugMode(): bool - { - return $this->parameters['debugMode']; - } - - /** - * Set parameter %debugMode%. - * @param bool|string|array - * @return self - */ - public function setDebugMode($value): self - { - if (is_string($value) || is_array($value)) { - $value = static::detectDebugMode($value); - } elseif (!is_bool($value)) { - throw new InvalidArgumentException(sprintf('Value must be either a string, array, or boolean, %s given.', gettype($value))); + // Then we test some common cases + if (is_string($address) && $address == 'NONE') + { + $this->parameters['debugMatch'] = false; + return; } - $this->parameters['debugMode'] = $value; - return $this; + elseif (is_string($address) && $address == 'ALL') + { + $this->parameters['debugMatch'] = true; + return; + } + + // Otherwise we run the regular tracy detectDebugMode + $list = is_string($address) + ? preg_split('#[,\s]+#', $address) + : (array) $address; + $addr = isset($_SERVER['REMOTE_ADDR']) + ? $_SERVER['REMOTE_ADDR'] + : php_uname('n'); + $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET]) + ? $_COOKIE[self::COOKIE_SECRET] + : NULL; + if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $list[] = '127.0.0.1'; + $list[] = '::1'; + } + + $this->parameters['debugMatch'] = in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE); + + return; } /** @@ -161,26 +265,11 @@ class Configurator } /** - * Detects debug mode by IP address. - * @param string|array IP addresses or computer names whitelist detection * @return bool */ - public static function detectDebugMode($list = NULL): bool + public function isDebugMode(): bool { - $addr = isset($_SERVER['REMOTE_ADDR']) - ? $_SERVER['REMOTE_ADDR'] - : php_uname('n'); - $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET]) - ? $_COOKIE[self::COOKIE_SECRET] - : NULL; - $list = is_string($list) - ? preg_split('#[,\s]+#', $list) - : (array) $list; - if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $list[] = '127.0.0.1'; - $list[] = '::1'; - } - return in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE); + return $this->parameters['debugEnabled'] && $this->parameters['debugMatch']; } /** @@ -193,26 +282,19 @@ class Configurator */ public function createContainer(): Factory { - // First set all the directories - Core::$appDir = $this->parameters['appDir']; - Core::$wwwDir = $this->parameters['wwwDir']; + // First set all the fixed directories Core::$tempDir = $this->parameters['tempDir']; Core::$logDir = $this->parameters['logDir']; + Core::$appDirs = $this->directories['app']; - // Then set debug mode - if ($this->parameters['debugMode']) - { - define('ENVIRONMENT', 'DEVELOPMENT'); - } - else - { - define('ENVIRONMENT', 'PRODUCTION'); - } + // Then prepare the debugger + $debug = ($this->parameters['debugEnabled'] && $this->parameters['debugMatch'] ? true : false); + define('ENVIRONMENT', ($debug ? 'DEVELOPMENT' : 'PRODUCTION')); // And enable Tracy Debugger if (class_exists('Tracy\Debugger', true)) { - Debugger::enable(!$this->parameters['debugMode'], realpath($this->parameters['logDir'])); + Debugger::enable(!$debug, realpath($this->parameters['logDir'])); if (isset($this->parameters['debugEmail'])) { Debugger::$email = $this->parameters['debugEmail']; @@ -221,8 +303,21 @@ class Configurator } // Then load the framework - Core::init(); + $container = Core::init(); - return Factory::getInstance(); + // Add all components + foreach ($this->components as $componentName => $componentClass) { + $container->setInstance($componentName, new $componentClass()); + } + + // And add all directories to the components + foreach ($this->directories as $component => $directories) { + if ($component == 'app') + continue; + + $container->{$component}->setDirectories($directories); + } + + return $container; } } \ No newline at end of file diff --git a/src/FuzeWorks/ControllerAbstract.php b/src/FuzeWorks/ControllerAbstract.php deleted file mode 100644 index e4e278c..0000000 --- a/src/FuzeWorks/ControllerAbstract.php +++ /dev/null @@ -1,46 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Abstract class ControllerAbstract. - * - * Extends all controllers to use the Factory. - * Factory should in the future be replaced with a DI container - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -abstract class ControllerAbstract extends Factory -{ -} diff --git a/src/FuzeWorks/Core.php b/src/FuzeWorks/Core.php index d323c32..93931dd 100644 --- a/src/FuzeWorks/Core.php +++ b/src/FuzeWorks/Core.php @@ -60,16 +60,14 @@ class Core */ public static $cwd; - public static $appDir; - - public static $wwwDir; - public static $coreDir; public static $tempDir; public static $logDir; + public static $appDirs = []; + /** * The HTTP status code of the current request * @@ -82,19 +80,13 @@ class Core * * @throws \Exception */ - public static function init() + public static function init(): Factory { // Set the CWD for usage in the shutdown function self::$cwd = getcwd(); // Set the core dir for when the loading of classes is required self::$coreDir = dirname(__DIR__); - - // If the environment is not yet defined, use production settings - if (!defined('ENVIRONMENT')) - { - define('ENVIRONMENT', 'PRODUCTION'); - } // Defines the time the framework starts. Used for timing functions in the framework if (!defined('STARTTIME')) { @@ -118,10 +110,6 @@ class Core Events::disable(); } - // And initialize multiple classes - $container->layout->init(); - Language::init(); - // And load all the plugins $container->plugins->loadHeaders(); @@ -130,6 +118,8 @@ class Core if ($event->isCancelled()) { exit; } + + return $container; } /** @@ -147,9 +137,7 @@ class Core if ($event->isCancelled() === false) { - // If the output should be displayed, send the final render and parse the logger Logger::shutdownError(); - Factory::getInstance()->output->_display(); Logger::shutdown(); } } diff --git a/src/FuzeWorks/Database.php b/src/FuzeWorks/Database.php deleted file mode 100644 index e99a8dc..0000000 --- a/src/FuzeWorks/Database.php +++ /dev/null @@ -1,278 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\Exception\DatabaseException; -use FW_DB; -use FW_DB_forge; -use FW_DB_utility; - -/** - * Database loading class - * - * Loads databases, forges and utilities in a standardized manner. - * - * @author TechFuze - * @copyright (c) 2013 - 2014, TechFuze. (https://techfuze.net) - * - */ -class Database -{ - - /** - * The default database forge. - * @var FW_DB|null - */ - protected static $defaultDB = null; - - /** - * Array of all the non-default databases - * @var array FW_DB|null - */ - protected static $databases = array(); - - /** - * The default database forge. - * @var FW_DB_forge|null - */ - protected static $defaultForge = null; - - /** - * Array of all the non-default databases forges. - * @var array FW_DB_forge|null - */ - protected static $forges = array(); - - /** - * The default database utility. - * @var FW_DB_utility|null - */ - protected static $defaultUtil = null; - - /** - * Register with the TracyBridge upon startup - */ - public function __construct() - { - if (class_exists('Tracy\Debugger', true)) - { - DatabaseTracyBridge::register(); - } - } - - /** - * Retrieve a database using a DSN or the default configuration. - * - * If a string is provided like this: 'dbdriver://username:password@hostname/database', - * the string will be interpreted and converted into a database connection parameter array. - * - * If a string is provided with a name, like this: 'default' the 'default' connection from the - * configuration file will be loaded. If no string is provided the default database will be loaded. - * - * If the $newInstance is a true boolean, a new instance will be loaded instead of loading the - * default one. $newInstance will also make sure that the loaded database is not default one. - * This behaviour will be changed in the future. - * - * - * If $queryBuilder = false is provided, the database will load without a queryBuilder. - * By default the queryBuilder will load. - * - * @param string $parameters - * @param bool $newInstance - * @param bool $queryBuilder - * @return FW_DB|bool - */ - public static function get($parameters = '', $newInstance = false, $queryBuilder = null) - { - // Fire the event to allow settings to be changed - $event = Events::fireEvent('databaseLoadDriverEvent', $parameters, $newInstance, $queryBuilder); - if ($event->isCancelled()) - { - return false; - } - - // If an instance already exists and is requested, return it - if (isset($event->database) && empty($event->parameters)) - { - return self::$defaultDB = $event->database; - } - elseif (isset($event->database) && !empty($event->parameters)) - { - return self::$databases[$event->parameters] = $event->database; - } - elseif (empty($event->parameters) && !$event->newInstance && is_object(self::$defaultDB) && ! empty(self::$defaultDB->conn_id)) - { - return $reference = self::$defaultDB; - } - elseif (!empty($event->parameters) && !$event->newInstance && isset(self::$databases[$event->parameters])) - { - return $reference = self::$databases[$event->parameters]; - } - - // If a new instance is required, load it - require_once (Core::$coreDir . DS . 'Database'.DS.'DB.php'); - - if ($event->newInstance === TRUE) - { - $database = DB($event->parameters, $event->queryBuilder); - } - elseif (empty($event->parameters) && $event->newInstance === FALSE) - { - $database = self::$defaultDB = DB($event->parameters, $event->queryBuilder); - } - else - { - $database = self::$databases[$event->parameters] = DB($event->parameters, $event->queryBuilder); - } - - // Tie it into the Tracy Bar if available - if (class_exists('\Tracy\Debugger', true)) - { - DatabaseTracyBridge::registerDatabase($database); - } - - return $database; - } - - /** - * Retrieves a database forge from the provided or default database. - * - * If no database is provided, the default database will be used. - * - * @param FW_DB|null $database - * @param bool $newInstance - * @return FW_DB_forge - */ - public static function getForge($database = null, $newInstance = false) - { - // Fire the event to allow settings to be changed - $event = Events::fireEvent('databaseLoadForgeEvent', $database, $newInstance); - if ($event->isCancelled()) - { - return false; - } - - // First check if we're talking about the default forge and that one is already set - if (is_object($event->forge) && ($event->forge instanceof FW_DB_forge) ) - { - return $event->forge; - } - elseif (is_object($event->database) && $event->database === self::$defaultDB && is_object(self::$defaultForge)) - { - return $reference = self::$defaultForge; - } - elseif ( ! is_object($event->database) OR ! ($event->database instanceof FW_DB)) - { - isset(self::$defaultDB) OR self::get('', false); - $database =& self::$defaultDB; - } - - require_once (Core::$coreDir . DS . 'Database'.DS.'DB_forge.php'); - require_once(Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$database->dbdriver.DS.$database->dbdriver.'_forge.php'); - - if ( ! empty($database->subdriver)) - { - $driver_path = Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$database->dbdriver.DS.'subdrivers'.DS.$database->dbdriver.'_'.$database->subdriver.'_forge.php'; - if (file_exists($driver_path)) - { - require_once($driver_path); - $class = 'FW_DB_'.$database->dbdriver.'_'.$database->subdriver.'_forge'; - } - else - { - throw new DatabaseException("Could not load forge. Driver file does not exist.", 1); - } - } - else - { - $class = 'FW_DB_'.$database->dbdriver.'_forge'; - } - - // Create a new instance of set the default database - if ($event->newInstance) - { - return new $class($database); - } - else - { - return self::$defaultForge = new $class($database); - } - } - - /** - * Retrieves a database utility from the provided or default database. - * - * If no database is provided, the default database will be used. - * - * @param FW_DB|null $database - * @param bool $newInstance - * @return FW_DB_utility - */ - public static function getUtil($database = null, $newInstance = false) - { - // Fire the event to allow settings to be changed - $event = Events::fireEvent('databaseLoadUtilEvent', $database, $newInstance); - if ($event->isCancelled()) - { - return false; - } - - // First check if we're talking about the default util and that one is already set - if (is_object($event->util) && ($event->util instanceof FW_DB_utility)) - { - return $event->util; - } - elseif (is_object($event->database) && $event->database === self::$defaultDB && is_object(self::$defaultUtil)) - { - return $reference = self::$defaultUtil; - } - - if ( ! is_object($event->database) OR ! ($event->database instanceof FW_DB)) - { - isset(self::$defaultDB) OR self::get('', false); - $database = & self::$defaultDB; - } - - require_once (Core::$coreDir . DS . 'Database'.DS.'DB_utility.php'); - require_once(Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$database->dbdriver.DS.$database->dbdriver.'_utility.php'); - $class = 'FW_DB_'.$database->dbdriver.'_utility'; - - if ($event->newInstance) - { - return new $class($database); - } - else - { - return self::$defaultUtil = new $class($database); - } - } -} \ No newline at end of file diff --git a/src/FuzeWorks/DatabaseTracyBridge.php b/src/FuzeWorks/DatabaseTracyBridge.php deleted file mode 100644 index ccb97e8..0000000 --- a/src/FuzeWorks/DatabaseTracyBridge.php +++ /dev/null @@ -1,142 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks; -use Tracy\IBarPanel; -use Tracy\Debugger; - -/** - * DatabaseTracyBridge Class. - * - * This class provides a bridge between FuzeWorks\Database and Tracy Debugging tool. - * - * This class registers in Tracy, and creates a Bar object which contains information about database sessions. - * It hooks into database usage and provides the information on the Tracy Bar panel. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseTracyBridge implements IBarPanel -{ - - public static $databases = array(); - protected $results = array(); - - public static function register() - { - $class = new self(); - $bar = Debugger::getBar(); - $bar->addPanel($class); - } - - public static function registerDatabase($database) - { - self::$databases[] = $database; - } - - protected function getResults(): array - { - if (!empty($this->results)) - { - return $this->results; - } - - // First prepare global variables - $results = array(); - $results['dbCount'] = 0; - $results['queryCount'] = 0; - $results['queryTimings'] = 0.0; - $results['errorsFound'] = false; - - // Go through all databases - foreach (self::$databases as $database) { - // Increase total databases - $results['dbCount']++; - - // First determine the ID - if (!empty($database->dsn)) - { - $databaseId = $database->dsn; - } - elseif (!empty($database->username) && !empty($database->database) && !empty($database->hostname)) - { - $databaseId = $database->username . '@' . $database->hostname . '/' . $database->database; - } - else - { - $databaseId = spl_object_hash($database); - } - - // Go through all queries - foreach ($database->queries as $key => $query) { - $results['queryCount']++; - $results['queryTimings'] += $database->query_times[$key]; - $results['queries'][$databaseId][$key]['query'] = $query; - $results['queries'][$databaseId][$key]['timings'] = $database->query_times[$key]; - $results['queries'][$databaseId][$key]['data'] = $database->query_data[$key]; - - // If errors are found, set this at the top of the array - if ($database->query_data[$key]['error']['code'] != 0) - { - $results['errorsFound'] = true; - } - } - } - - // Limit the amount in order to keep things readable - $results['queryCountProvided'] = 0; - foreach ($results['queries'] as $id => $database) { - $results['queries'][$id] = array_reverse(array_slice($database, -10)); - $results['queryCountProvided'] += count($results['queries'][$id]); - } - $results = array_slice($results, -10); - - return $this->results = $results; - } - - public function getTab(): string - { - $results = $this->getResults(); - ob_start(function () {}); - require dirname(__DIR__) . DS . 'Layout' . DS . 'layout.tracydatabasetab.php'; - return ob_get_clean(); - } - - public function getPanel(): string - { - // Parse the panel - $results = $this->getResults(); - ob_start(function () {}); - require dirname(__DIR__) . DS . 'Layout' . DS . 'layout.tracydatabasepanel.php'; - return ob_get_clean(); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/Event/DatabaseLoadDriverEvent.php b/src/FuzeWorks/Event/DatabaseLoadDriverEvent.php deleted file mode 100644 index 2b6fc82..0000000 --- a/src/FuzeWorks/Event/DatabaseLoadDriverEvent.php +++ /dev/null @@ -1,85 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a database driver is loaded - * - * Use this to cancel the loading of a database, or change the provided database - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseLoadDriverEvent extends Event -{ - /** - * A possible database that can be loaded. - * - * Provide a database in this variable and it will be loaded. It shall be identified as default if - * the parameters variable is empty. If there is a string in parameters this database shall be identified as - * such. - * - * @var FW_DB|null - */ - public $database = null; - - /** - * Parameters of the database to be loaded - * - * @var string - */ - public $parameters; - - /** - * Whether a database instance shall be cloned if existing - * - * @var bool - */ - public $newInstance; - - /** - * Whether to attach the queryBuilder to the database driver - * - * @var null|bool - */ - public $queryBuilder; - - public function init($parameters = '', $newInstance = false, $queryBuilder = null) - { - $this->parameters = $parameters; - $this->newInstance = $newInstance; - $this->queryBuilder = $queryBuilder; - } -} diff --git a/src/FuzeWorks/Event/DatabaseLoadForgeEvent.php b/src/FuzeWorks/Event/DatabaseLoadForgeEvent.php deleted file mode 100644 index ab2d8cc..0000000 --- a/src/FuzeWorks/Event/DatabaseLoadForgeEvent.php +++ /dev/null @@ -1,77 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a database forge is loaded - * - * Use this to cancel the loading of a forge, or change the provided database - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseLoadForgeEvent extends Event -{ - /** - * A possible forge that can be loaded. - * - * Provide a forge in this variable and it will be loaded. - * - * @var FW_DB_forge|null - */ - public $forge = null; - - /** - * Database to be used by the forge. - * - * If no database is provided, FuzeWorks\Database shall provide the default database - * - * @var FW_DB|null - */ - public $database = null; - - /** - * Whether a database instance shall be cloned if existing - * - * @var bool - */ - public $newInstance; - - public function init($database = null, $newInstance = false) - { - $this->database = $database; - $this->newInstance = $newInstance; - } -} diff --git a/src/FuzeWorks/Event/DatabaseLoadUtilEvent.php b/src/FuzeWorks/Event/DatabaseLoadUtilEvent.php deleted file mode 100644 index bde7470..0000000 --- a/src/FuzeWorks/Event/DatabaseLoadUtilEvent.php +++ /dev/null @@ -1,77 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a database utility is loaded - * - * Use this to cancel the loading of a util, or change the provided database - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class DatabaseLoadUtilEvent extends Event -{ - /** - * A possible util that can be loaded. - * - * Provide a util in this variable and it will be loaded. - * - * @var FW_DB_util|null - */ - public $util = null; - - /** - * Database to be used by the util. - * - * If no database is provided, FuzeWorks\Database shall provide the default database - * - * @var FW_DB_utility|null - */ - public $database = null; - - /** - * Whether a database instance shall be cloned if existing - * - * @var bool - */ - public $newInstance; - - public function init($database = null, $newInstance = false) - { - $this->database = $database; - $this->newInstance = $newInstance; - } -} diff --git a/src/FuzeWorks/Event/LayoutLoadEvent.php b/src/FuzeWorks/Event/LayoutLoadEvent.php deleted file mode 100644 index b6c7fcf..0000000 --- a/src/FuzeWorks/Event/LayoutLoadEvent.php +++ /dev/null @@ -1,82 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a layout is loaded. - * - * Use this to cancel the loading of a layout, or change the file or engine of a layout - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LayoutLoadEvent extends Event -{ - /** - * The directory of the layout to be loaded. - * - * @var string - */ - public $directory; - - /** - * The file of the layout to be loaded. - * - * @var string - */ - public $file; - - /** - * The engine the file will be loaded with. - * - * @var object - */ - public $engine; - - /** - * The assigned variables to the template. - * - * @var array - */ - public $assigned_variables; - - public function init($file, $directory, $engine, $assigned_variables) - { - $this->file = $file; - $this->directory = $directory; - $this->engine = $engine; - $this->assigned_variables = $assigned_variables; - } -} diff --git a/src/FuzeWorks/Event/ModelLoadEvent.php b/src/FuzeWorks/Event/ModelLoadEvent.php deleted file mode 100644 index f2819e4..0000000 --- a/src/FuzeWorks/Event/ModelLoadEvent.php +++ /dev/null @@ -1,66 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets loaded when a model is loaded. - * - * Use this to cancel the loading of a model, or change the model to be loaded - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class ModelLoadEvent extends Event -{ - /** - * The directories the model can get loaded from. - * - * @var array - */ - public $directories = array(); - - /** - * The name of the model to be loaded. - * - * @var string|null - */ - public $modelName = null; - - public function init($modelName, $directories) - { - $this->modelName = $modelName; - $this->directories = $directories; - } -} diff --git a/src/FuzeWorks/Event/RouterLoadCallableEvent.php b/src/FuzeWorks/Event/RouterLoadCallableEvent.php deleted file mode 100644 index f079b52..0000000 --- a/src/FuzeWorks/Event/RouterLoadCallableEvent.php +++ /dev/null @@ -1,70 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Class routerLoadCallableEvent. - * - * Called when a callable is about to be loaded - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class routerLoadCallableEvent extends Event -{ - /** - * @var callable The callable - */ - public $callable; - - /** - * @var array The matches with the routing path - */ - public $matches = array(); - - /** - * The route which was matched. - * - * @var null|string - */ - public $route = null; - - public function init($callable, $matches, $route) - { - $this->callable = $callable; - $this->matches = $matches; - $this->route = $route; - } -} diff --git a/src/FuzeWorks/Event/RouterLoadControllerEvent.php b/src/FuzeWorks/Event/RouterLoadControllerEvent.php deleted file mode 100644 index ce209a4..0000000 --- a/src/FuzeWorks/Event/RouterLoadControllerEvent.php +++ /dev/null @@ -1,100 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Event that gets fired when a controller is loaded. - * - * Use this to cancel the loading of a controller, or change the details of what is loaded. - * - * Currently only used by Router::defaultCallable(); - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class RouterLoadControllerEvent extends Event -{ - /** - * The directory where the controller is located - * - * @var string - */ - public $directory; - - /** - * The file in which the controller is found - * - * @var string - */ - public $file; - - /** - * The class of the controller - * - * @var string - */ - public $className; - - /** - * The name of the controller - * - * @var string - */ - public $controller; - - /** - * The function that will be loaded in the controller - * - * @var string - */ - public $function; - - /** - * The parameters that will be provided to the function in the controller - * - * @var string|null - */ - public $parameters; - - public function init($file, $directory, $className, $controller, $function, $parameters) - { - $this->file = $file; - $this->directory = $directory; - $this->className = $className; - $this->controller = $controller; - $this->function = $function; - $this->parameters = $parameters; - } -} diff --git a/src/FuzeWorks/Event/RouterRouteEvent.php b/src/FuzeWorks/Event/RouterRouteEvent.php deleted file mode 100644 index 8a7c62e..0000000 --- a/src/FuzeWorks/Event/RouterRouteEvent.php +++ /dev/null @@ -1,89 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Event; - -use FuzeWorks\Event; - -/** - * Class routerRouteEvent. - * - * Fired after the router has extracted the path, and is about to find out what route matches the path. - * - * This Event is usefull for adding routes. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class routerRouteEvent extends Event -{ - /** - * @var array The routing table - */ - public $routes; - - /** - * @var bool Whether the callable will be loaded directly after or not - */ - public $performLoading; - - /** - * Whether a cached page should be ignored or not - * - * @var bool true if cache should not be used - */ - public $cacheOverride = false; - - /** - * The current path input to FuzeWorks. - * - * @var null|string - */ - public $path; - - public function init($routes, $performLoading, $path) - { - $this->routes = $routes; - $this->performLoading = $performLoading; - $this->path = $path; - } - - /** - * Whether a cached page should be ignored or not - * - * @param bool $overrideCache true if cache should not be used - */ - public function overrideCache($bool = true) - { - $this->cacheOverride = $bool; - } -} diff --git a/src/FuzeWorks/Exception/DatabaseException.php b/src/FuzeWorks/Exception/DatabaseException.php deleted file mode 100644 index 31e1cf9..0000000 --- a/src/FuzeWorks/Exception/DatabaseException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class DatabaseException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class DatabaseException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/LanguageException.php b/src/FuzeWorks/Exception/LanguageException.php deleted file mode 100644 index 2c5be7a..0000000 --- a/src/FuzeWorks/Exception/LanguageException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class LanguageException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LanguageException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/LayoutException.php b/src/FuzeWorks/Exception/LayoutException.php deleted file mode 100644 index 3bfaec0..0000000 --- a/src/FuzeWorks/Exception/LayoutException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class LayoutException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LayoutException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/ModelException.php b/src/FuzeWorks/Exception/ModelException.php deleted file mode 100644 index c58aae2..0000000 --- a/src/FuzeWorks/Exception/ModelException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class ModelException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class ModelException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/RouterException.php b/src/FuzeWorks/Exception/RouterException.php deleted file mode 100644 index 28c743b..0000000 --- a/src/FuzeWorks/Exception/RouterException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class RouterException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class RouterException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/SecurityException.php b/src/FuzeWorks/Exception/SecurityException.php deleted file mode 100644 index 87473f8..0000000 --- a/src/FuzeWorks/Exception/SecurityException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class SecurityException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class SecurityException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Exception/UriException.php b/src/FuzeWorks/Exception/UriException.php deleted file mode 100644 index 8097b0b..0000000 --- a/src/FuzeWorks/Exception/UriException.php +++ /dev/null @@ -1,45 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.1 - */ - -namespace FuzeWorks\Exception; - -/** - * Class UriException. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class UriException extends Exception -{ -} - -?> \ No newline at end of file diff --git a/src/FuzeWorks/Factory.php b/src/FuzeWorks/Factory.php index a7b0db0..7bf1d16 100644 --- a/src/FuzeWorks/Factory.php +++ b/src/FuzeWorks/Factory.php @@ -89,18 +89,6 @@ class Factory */ public $events; - /** - * Models Object - * @var Models - */ - public $models; - - /** - * Layout Object - * @var Layout - */ - public $layout; - /** * Libraries Object * @var Libraries @@ -113,54 +101,6 @@ class Factory */ public $helpers; - /** - * Database Object - * @var Database - */ - public $database; - - /** - * Language Object - * @var Language - */ - public $language; - - /** - * Utf8 Object - * @var Utf8 - */ - public $utf8; - - /** - * URI Object - * @var URI - */ - public $uri; - - /** - * Security Object - * @var Security - */ - public $security; - - /** - * Input Object - * @var Input - */ - public $input; - - /** - * Output Object - * @var Output - */ - public $output; - - /** - * Router Object - * @var Router - */ - public $router; - /** * Plugins Object * @var Plugins @@ -181,18 +121,8 @@ class Factory $this->config = new Config(); $this->logger = new Logger(); $this->events = new Events(); - $this->models = new Models(); - $this->layout = new Layout(); $this->libraries = new Libraries(); $this->helpers = new Helpers(); - $this->database = new Database(); - $this->language = new Language(); - $this->utf8 = new Utf8(); - $this->uri = new URI(); - $this->output = new Output(); - $this->security = new Security(); - $this->input = new Input(); - $this->router = new Router(); $this->plugins = new Plugins(); return true; @@ -306,14 +236,14 @@ class Factory * Set an instance of one of the loaded classes with your own $object. * Replace the existing class with one of your own. * - * @param string $className The name of the loaded class, WITHOUT the namespace + * @param string $objectName The name of the loaded class, WITHOUT the namespace * @param mixed $object Object to replace the class with * @return Factory Instance */ - public function setInstance($className, $object): self + public function setInstance($objectName, $object): self { // Determine the instance name - $instanceName = strtolower($className); + $instanceName = strtolower($objectName); // Unset and set unset($this->{$instanceName}); diff --git a/src/FuzeWorks/Helpers.php b/src/FuzeWorks/Helpers.php index b1bca68..b04e149 100644 --- a/src/FuzeWorks/Helpers.php +++ b/src/FuzeWorks/Helpers.php @@ -73,10 +73,8 @@ class Helpers public function __construct() { - $this->helperPaths = [ - Core::$appDir . DS . 'Helpers', - Core::$coreDir . DS . 'Helpers' - ]; + $this->helperPaths = Core::$appDirs; + $this->helperPaths[] = Core::$coreDir . DS . 'Helpers'; } /** diff --git a/src/FuzeWorks/Input.php b/src/FuzeWorks/Input.php deleted file mode 100644 index d366a1b..0000000 --- a/src/FuzeWorks/Input.php +++ /dev/null @@ -1,873 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Input Class - * - * Pre-processes global input data for security - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Input { - - /** - * IP address of the current user - * - * @var string - */ - protected $ip_address = FALSE; - - /** - * Allow GET array flag - * - * If set to FALSE, then $_GET will be set to an empty array. - * - * @var bool - */ - protected $_allow_get_array = TRUE; - - /** - * Standardize new lines flag - * - * If set to TRUE, then newlines are standardized. - * - * @var bool - */ - protected $_standardize_newlines; - - /** - * Enable XSS flag - * - * Determines whether the XSS filter is always active when - * GET, POST or COOKIE data is encountered. - * Set automatically based on config setting. - * - * @var bool - */ - protected $_enable_xss = FALSE; - - /** - * Enable CSRF flag - * - * Enables a CSRF cookie token to be set. - * Set automatically based on config setting. - * - * @var bool - */ - protected $_enable_csrf = FALSE; - - /** - * List of all HTTP request headers - * - * @var array - */ - protected $headers = array(); - - /** - * Raw input stream data - * - * Holds a cache of php://input contents - * - * @var string - */ - protected $_raw_input_stream; - - /** - * Parsed input stream data - * - * Parsed from php://input at runtime - * - * @see Input::input_stream() - * @var array - */ - protected $_input_stream; - - /** - * Factory object, allows this class to communicate with everything in FuzeWorks - * - * @var Factory - */ - protected $factory; - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Determines whether to globally enable the XSS processing - * and whether to allow the $_GET array. - * - * @return void - */ - public function __construct() - { - // First load the factory so contact can be made with everything in FuzeWorks - $this->factory = Factory::getInstance(); - - $this->_allow_get_array = ($this->factory->config->get('routing')->allow_get_array === TRUE); - $this->_enable_xss = ($this->factory->config->get('security')->global_xss_filtering === TRUE); - $this->_enable_csrf = ($this->factory->config->get('security')->csrf_protection === TRUE); - $this->_standardize_newlines = (bool) $this->factory->config->get('security')->standardize_newlines; - - // Sanitize global arrays - $this->_sanitize_globals(); - - // CSRF Protection check - if ($this->_enable_csrf === TRUE && ! Core::isCli()) - { - $this->factory->security->csrf_verify(); - } - } - - // -------------------------------------------------------------------- - - /** - * Fetch from array - * - * Internal method used to retrieve values from global arrays. - * - * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc. - * @param mixed $index Index for item to be fetched from $array - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL) - { - is_bool($xss_clean) OR $xss_clean = $this->_enable_xss; - - // If $index is NULL, it means that the whole $array is requested - isset($index) OR $index = array_keys($array); - - // allow fetching multiple keys at once - if (is_array($index)) - { - $output = array(); - foreach ($index as $key) - { - $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean); - } - - return $output; - } - - if (isset($array[$index])) - { - $value = $array[$index]; - } - elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation - { - $value = $array; - for ($i = 0; $i < $count; $i++) - { - $key = trim($matches[0][$i], '[]'); - if ($key === '') // Empty notation will return the value as array - { - break; - } - - if (isset($value[$key])) - { - $value = $value[$key]; - } - else - { - return NULL; - } - } - } - else - { - return NULL; - } - - return ($xss_clean === TRUE) - ? $this->factory->security->xss_clean($value) - : $value; - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the GET array - * - * @param mixed $index Index for item to be fetched from $_GET - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function get($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_GET, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the POST array - * - * @param mixed $index Index for item to be fetched from $_POST - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function post($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_POST, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from POST data with fallback to GET - * - * @param string $index Index for item to be fetched from $_POST or $_GET - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function post_get($index, $xss_clean = NULL) - { - return isset($_POST[$index]) - ? $this->post($index, $xss_clean) - : $this->get($index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from GET data with fallback to POST - * - * @param string $index Index for item to be fetched from $_GET or $_POST - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function get_post($index, $xss_clean = NULL) - { - return isset($_GET[$index]) - ? $this->get($index, $xss_clean) - : $this->post($index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the COOKIE array - * - * @param mixed $index Index for item to be fetched from $_COOKIE - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function cookie($index = NULL, $xss_clean = NULL) - { - return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the SERVER array - * - * @param mixed $index Index for item to be fetched from $_SERVER - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function server($index, $xss_clean = NULL) - { - return $this->_fetch_from_array($_SERVER, $index, $xss_clean); - } - - // ------------------------------------------------------------------------ - - /** - * Fetch an item from the php://input stream - * - * Useful when you need to access PUT, DELETE or PATCH request data. - * - * @param string $index Index for item to be fetched - * @param bool $xss_clean Whether to apply XSS filtering - * @return mixed - */ - public function input_stream($index = NULL, $xss_clean = NULL) - { - // Prior to PHP 5.6, the input stream can only be read once, - // so we'll need to check if we have already done that first. - if ( ! is_array($this->_input_stream)) - { - // $this->raw_input_stream will trigger __get(). - parse_str($this->raw_input_stream, $this->_input_stream); - is_array($this->_input_stream) OR $this->_input_stream = array(); - } - - return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); - } - - // ------------------------------------------------------------------------ - - /** - * Set cookie - * - * Accepts an arbitrary number of parameters (up to 7) or an associative - * array in the first parameter containing all the values. - * - * @param string|mixed[] $name Cookie name or an array containing parameters - * @param string $value Cookie value - * @param int $expire Cookie expiration time in seconds - * @param string $domain Cookie domain (e.g.: '.yourdomain.com') - * @param string $path Cookie path (default: '/') - * @param string $prefix Cookie name prefix - * @param bool $secure Whether to only transfer cookies via SSL - * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) - * @return void - */ - public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) - { - if (is_array($name)) - { - // always leave 'name' in last place, as the loop will break otherwise, due to $$item - foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item) - { - if (isset($name[$item])) - { - $$item = $name[$item]; - } - } - } - - // Get the variables - $cfg = $this->factory->config->get('main'); - - if ($prefix === '' && $cfg->cookie_prefix !== '') - { - $prefix = $cfg->cookie_prefix; - } - - if ($domain == '' && $cfg->cookie_domain != '') - { - $domain = $cfg->cookie_domain; - } - - if ($path === '/' && $cfg->cookie_path !== '/') - { - $path = $cfg->cookie_path; - } - - if ($secure === FALSE && $cfg->cookie_secure === TRUE) - { - $secure = $cfg->cookie_secure; - } - - if ($httponly === FALSE && $cfg->cookie_httponly !== FALSE) - { - $httponly = $cfg->cookie_httponly; - } - - if ( ! is_numeric($expire)) - { - $expire = time() - 86500; - } - else - { - $expire = ($expire > 0) ? time() + $expire : 0; - } - - setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly); - } - - // -------------------------------------------------------------------- - - /** - * Fetch the IP Address - * - * Determines and validates the visitor's IP address. - * - * @return string IP address - */ - public function ip_address(): string - { - if ($this->ip_address !== FALSE) - { - return $this->ip_address; - } - - $proxy_ips = $this->factory->config->get('security')->proxy_ips; - if ( ! empty($proxy_ips) && ! is_array($proxy_ips)) - { - $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips)); - } - - $this->ip_address = $this->server('REMOTE_ADDR'); - - if ($proxy_ips) - { - foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header) - { - if (($spoof = $this->server($header)) !== NULL) - { - // Some proxies typically list the whole chain of IP - // addresses through which the client has reached us. - // e.g. client_ip, proxy_ip1, proxy_ip2, etc. - sscanf($spoof, '%[^,]', $spoof); - - if ( ! $this->valid_ip($spoof)) - { - $spoof = NULL; - } - else - { - break; - } - } - } - - if ($spoof) - { - for ($i = 0, $c = count($proxy_ips); $i < $c; $i++) - { - // Check if we have an IP address or a subnet - if (strpos($proxy_ips[$i], '/') === FALSE) - { - // An IP address (and not a subnet) is specified. - // We can compare right away. - if ($proxy_ips[$i] === $this->ip_address) - { - $this->ip_address = $spoof; - break; - } - - continue; - } - - // We have a subnet ... now the heavy lifting begins - isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.'; - - // If the proxy entry doesn't match the IP protocol - skip it - if (strpos($proxy_ips[$i], $separator) === FALSE) - { - continue; - } - - // Convert the REMOTE_ADDR IP address to binary, if needed - if ( ! isset($ip, $sprintf)) - { - if ($separator === ':') - { - // Make sure we're have the "full" IPv6 format - $ip = explode(':', - str_replace('::', - str_repeat(':', 9 - substr_count($this->ip_address, ':')), - $this->ip_address - ) - ); - - for ($j = 0; $j < 8; $j++) - { - $ip[$j] = intval($ip[$j], 16); - } - - $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b'; - } - else - { - $ip = explode('.', $this->ip_address); - $sprintf = '%08b%08b%08b%08b'; - } - - $ip = vsprintf($sprintf, $ip); - } - - // Split the netmask length off the network address - sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen); - - // Again, an IPv6 address is most likely in a compressed form - if ($separator === ':') - { - $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); - for ($i = 0; $i < 8; $i++) - { - $netaddr[$i] = intval($netaddr[$i], 16); - } - } - else - { - $netaddr = explode('.', $netaddr); - } - - // Convert to binary and finally compare - if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0) - { - $this->ip_address = $spoof; - break; - } - } - } - } - - if ( ! $this->valid_ip($this->ip_address)) - { - return $this->ip_address = '0.0.0.0'; - } - - return $this->ip_address; - } - - // -------------------------------------------------------------------- - - /** - * Validate IP Address - * - * @param string $ip IP address - * @param string $which IP protocol: 'ipv4' or 'ipv6' - * @return bool - */ - public function valid_ip($ip, $which = ''): bool - { - switch (strtolower($which)) - { - case 'ipv4': - $which = FILTER_FLAG_IPV4; - break; - case 'ipv6': - $which = FILTER_FLAG_IPV6; - break; - default: - $which = NULL; - break; - } - - return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which); - } - - // -------------------------------------------------------------------- - - /** - * Fetch User Agent string - * - * @return string|null User Agent string or NULL if it doesn't exist - */ - public function user_agent($xss_clean = NULL) - { - return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Globals - * - * Internal method serving for the following purposes: - * - * - Unsets $_GET data, if query strings are not enabled - * - Cleans POST, COOKIE and SERVER data - * - Standardizes newline characters to PHP_EOL - * - * @return void - */ - protected function _sanitize_globals() - { - // Is $_GET data allowed? If not we'll set the $_GET to an empty array - if ($this->_allow_get_array === FALSE) - { - $_GET = array(); - } - elseif (is_array($_GET)) - { - foreach ($_GET as $key => $val) - { - $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); - } - } - - // Clean $_POST Data - if (is_array($_POST)) - { - foreach ($_POST as $key => $val) - { - $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); - } - } - - // Clean $_COOKIE Data - if (is_array($_COOKIE)) - { - // Also get rid of specially treated cookies that might be set by a server - // or silly application, that are of no use to a CI application anyway - // but that when present will trip our 'Disallowed Key Characters' alarm - // http://www.ietf.org/rfc/rfc2109.txt - // note that the key names below are single quoted strings, and are not PHP variables - unset( - $_COOKIE['$Version'], - $_COOKIE['$Path'], - $_COOKIE['$Domain'] - ); - - foreach ($_COOKIE as $key => $val) - { - if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE) - { - $_COOKIE[$cookie_key] = $this->_clean_input_data($val); - } - else - { - unset($_COOKIE[$key]); - } - } - } - - // Sanitize PHP_SELF - $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']); - - Logger::logDebug('Global POST, GET and COOKIE data sanitized'); - } - - // -------------------------------------------------------------------- - - /** - * Clean Input Data - * - * Internal method that aids in escaping data and - * standardizing newline characters to PHP_EOL. - * - * @param string|string[] $str Input string(s) - * @return string|array - */ - protected function _clean_input_data($str) - { - if (is_array($str)) - { - $new_array = array(); - foreach (array_keys($str) as $key) - { - $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]); - } - return $new_array; - } - - /* We strip slashes if magic quotes is on to keep things consistent - - NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and - it will probably not exist in future versions at all. - */ - if ( ! Core::isPHP('5.4') && get_magic_quotes_gpc()) - { - $str = stripslashes($str); - } - - // Clean UTF-8 if supported - if (UTF8_ENABLED === TRUE) - { - $str = $this->factory->utf8->clean_string($str); - } - - // Remove control characters - $str = UTF8::remove_invisible_characters($str, FALSE); - - // Standardize newlines if needed - if ($this->_standardize_newlines === TRUE) - { - return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Clean Keys - * - * Internal method that helps to prevent malicious users - * from trying to exploit keys we make sure that keys are - * only named with alpha-numeric text and a few other items. - * - * @param string $str Input string - * @param bool $fatal Whether to terminate script exection - * or to return FALSE if an invalid - * key is encountered - * @return string|bool - */ - protected function _clean_input_keys($str, $fatal = TRUE) - { - if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str)) - { - if ($fatal === TRUE) - { - return FALSE; - } - else - { - Core::setStatusHeader(503); - echo 'Disallowed Key Characters.'; - exit(7); // EXIT_USER_INPUT - } - } - - // Clean UTF-8 if supported - if (UTF8_ENABLED === TRUE) - { - return $this->factory->utf8->clean_string($str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Request Headers - * - * @param bool $xss_clean Whether to apply XSS filtering - * @return array - */ - public function request_headers($xss_clean = FALSE): array - { - // If header is already defined, return it immediately - if ( ! empty($this->headers)) - { - return $this->headers; - } - - // In Apache, you can simply call apache_request_headers() - if (function_exists('apache_request_headers')) - { - return $this->headers = apache_request_headers(); - } - - $this->headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE'); - - foreach ($_SERVER as $key => $val) - { - if (sscanf($key, 'HTTP_%s', $header) === 1) - { - // take SOME_HEADER and turn it into Some-Header - $header = str_replace('_', ' ', strtolower($header)); - $header = str_replace(' ', '-', ucwords($header)); - - $this->headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean); - } - } - - return $this->headers; - } - - // -------------------------------------------------------------------- - - /** - * Get Request Header - * - * Returns the value of a single member of the headers class member - * - * @param string $index Header name - * @param bool $xss_clean Whether to apply XSS filtering - * @return string|null The requested header on success or NULL on failure - */ - public function get_request_header($index, $xss_clean = FALSE) - { - static $headers; - - if ( ! isset($headers)) - { - empty($this->headers) && $this->request_headers(); - foreach ($this->headers as $key => $value) - { - $headers[strtolower($key)] = $value; - } - } - - $index = strtolower($index); - - if ( ! isset($headers[$index])) - { - return NULL; - } - - return ($xss_clean === TRUE) - ? $this->factory->security->xss_clean($headers[$index]) - : $headers[$index]; - } - - // -------------------------------------------------------------------- - - /** - * Is AJAX request? - * - * Test to see if a request contains the HTTP_X_REQUESTED_WITH header. - * - * @return bool - */ - public function is_ajax_request(): bool - { - return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); - } - - // -------------------------------------------------------------------- - - /** - * Get Request Method - * - * Return the request method - * - * @param bool $upper Whether to return in upper or lower case - * (default: FALSE) - * @return string - */ - public function method($upper = FALSE): string - { - return ($upper) - ? strtoupper($this->server('REQUEST_METHOD')) - : strtolower($this->server('REQUEST_METHOD')); - } - - // ------------------------------------------------------------------------ - - /** - * Magic __get() - * - * Allows read access to protected properties - * - * @param string $name - * @return mixed - */ - public function __get($name) - { - if ($name === 'raw_input_stream') - { - isset($this->_raw_input_stream) OR $this->_raw_input_stream = file_get_contents('php://input'); - return $this->_raw_input_stream; - } - elseif ($name === 'ip_address') - { - return $this->ip_address; - } - } - -} diff --git a/src/FuzeWorks/Language.php b/src/FuzeWorks/Language.php deleted file mode 100644 index 94db4dc..0000000 --- a/src/FuzeWorks/Language.php +++ /dev/null @@ -1,231 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\Exception\LanguageException; - -/** - * Language Class. - * - * The Language Class provides functions to retrieve language files and lines of text - * for purposes of internationalization. - * - * In your FuzeWorks Core folder, you will find a Language sub-directory containing a set of language files for the english idiom. - * The files in this directory (Core/Language/english/) define the regular messages, error messages, and other generally output terms - * or expressions, for the different parts of the FuzeWorks. - * - * You can create or incorporate your own language files, as needed, in order to provide application-specific error and other messages, - * or to provide translations of the core messages into other languages. These translations or additional messages would go inside your Application/Language/ directory, - * with separate sub-directories for each idiom (for instance, ‘french’ or ‘german’). - * - * FuzeWorks comes with a set of language files for the “english” idiom. Additional approved translations for different idioms may be found in the FuzeWorks Archives. - * Each archive deals with a single idiom. - * - * When FuzeWorks loads language files, it will load the one in Core/Language/ first and will then look for an override in your Application/Language/ directory. - * - * - * @author TechFuze - * @copyright (c) 2013 - 2014, TechFuze. (https://techfuze.net) - */ -class Language -{ - - /** - * Paths where the class can find translations - * @var array - */ - protected static $languagePaths = array(); - - /** - * The current language array - * @var array - */ - protected static $language = array(); - - /** - * Array list of all the loaded languages - * @var array - */ - protected static $is_loaded = array(); - - public static function init() - { - self::$languagePaths[] = Core::$appDir . DS . 'Language'; - } - - /** - * Retrieve a language file and return the language array - * - * @param string $langfile - * @param string $idiom - * @param boolean $add_suffix - * @param string $alt_path - * @return array - * @throws LanguageException - */ - public static function get($langfile, $idiom = '', $add_suffix = TRUE, $alt_path = ''): array - { - // First we determine the file that should be loaded - $langfile = str_replace('.php', '', $langfile); - - if ($add_suffix === TRUE) - { - $langfile = preg_replace('/_lang$/', '', $langfile).'_lang'; - } - - $langfile .= '.php'; - - // Then we determine the idiom - if (empty($idiom) OR ! preg_match('/^[a-z_-]+$/i', $idiom)) - { - $config = Factory::getInstance()->config->get('main'); - $idiom = empty($config->language) ? 'english' : $config->language; - } - - // Is it already loaded? Return the entire language array - if (isset(self::$is_loaded[$langfile]) && self::$is_loaded[$langfile] === $idiom) - { - return self::$language; - } - - // Prepare the language variable - $lang = array(); - - // Load the base file, so any others found can override it - $basepath = Core::$coreDir . DS. 'Language'.DS.$idiom.DS.$langfile; - if (($found = file_exists($basepath)) === TRUE) - { - $lang = array_merge($lang, (array) include($basepath)); - } - - // Do we have an alternative path to look in? - if ($alt_path !== '') - { - $alt_path .= 'Language'.DS.$idiom.DS.$langfile; - if (file_exists($alt_path)) - { - $lang = array_merge($lang, (array) include($alt_path)); - $found = TRUE; - } - } - else - { - foreach (self::$languagePaths as $languagePath) - { - $languagePath .= DS.$idiom.DS.$langfile; - if ($basepath !== $languagePath && file_exists($languagePath)) - { - $lang = array_merge($lang, (array) include($languagePath)); - $found = TRUE; - break; - } - } - } - - // If nothing is found, kill it - if ($found !== TRUE) - { - throw new LanguageException('Unable to load the requested language file: language/'.$idiom.'/'.$langfile, 1); - } - - // If only empty content is found, return the language array - if ( empty($lang) ) - { - Logger::logError('Language file contains no data: language/'.$idiom.'/'.$langfile); - - return self::$language; - } - - // Save the data and return it - self::$is_loaded[$langfile] = $idiom; - self::$language = array_merge(self::$language, $lang); - - Logger::log('Language file loaded: language/'.$idiom.'/'.$langfile); - return self::$language; - } - - /** - * Load a single line from the language array - * - * @param string $line - * @param boolean $log_errors - * @return string - */ - public static function line($line, $log_errors = TRUE): string - { - $value = isset(self::$language[$line]) ? self::$language[$line] : FALSE; - - // Because killer robots like unicorns! - if ($value === FALSE && $log_errors === TRUE) - { - Logger::logError('Could not find the language line "'.$line.'"'); - } - - return $value; - } - - /** - * Add a language path to the class - * - * @param string $directory - */ - public static function addLanguagePath($directory): string - { - if (!in_array($directory, self::$languagePaths)) - { - self::$languagePaths[] = $directory; - } - } - - /** - * Remove a languagePath from the class - * - * @param string $directory - */ - public static function removeLanguagePath($directory): string - { - if (($key = array_search($directory, self::$languagePaths)) !== false) - { - unset(self::$languagePaths[$key]); - } - } - - /** - * Retrieve an array of the languagePaths - * - * @return array - */ - public static function getLanguagePaths(): array - { - return self::$languagePaths; - } -} diff --git a/src/FuzeWorks/Layout.php b/src/FuzeWorks/Layout.php deleted file mode 100644 index ffb77c1..0000000 --- a/src/FuzeWorks/Layout.php +++ /dev/null @@ -1,539 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.4 - */ - -namespace FuzeWorks; - -use FuzeWorks\TemplateEngine\{JsonEngine,PHPEngine,SmartyEngine,LatteEngine,TemplateEngine}; -use FuzeWorks\Exception\LayoutException; - -/** - * Layout and Template Manager for FuzeWorks. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - */ -class Layout -{ - /** - * The file to be loaded by the layout manager. - * - * @var null|string - */ - public $file = null; - - /** - * The directory of the file to be loaded by the layout manager. - * - * @var string - */ - public $directory; - - /** - * All assigned currently assigned to the template. - * - * @var array Associative Assigned Variable Array - */ - private $assigned_variables = array(); - - /** - * All engines that can be used for templates. - * - * @var array of engines - */ - private $engines = array(); - - /** - * All file extensions that can be used and are bound to a template engine. - * - * @var array of names of engines - */ - private $file_extensions = array(); - - /** - * whether the template engines are already called. - * - * @var bool True if loaded - */ - private $engines_loaded = false; - - /** - * The currently selected template engine. - * - * @var string name of engine - */ - private $current_engine; - - public function init() - { - $this->directory = Core::$appDir . DS .'Layout'; - } - - /** - * Retrieve a template file using a string and a directory and immediatly parse it to the output class. - * - * What template file gets loaded depends on the template engine that is being used. - * PHP for example uses .php files. Providing this function with 'home/dashboard' will load the home/layout.dashboard.php file. - * You can also provide no particular engine, and the manager will decide what template to load. - * Remember that doing so will result in a LayoutException when multiple compatible files are found. - * - * @param string $file File to load - * @param string $directory Directory to load it from - * @param bool $directOutput Whether to directly output the result with an echo or send it to the output class. True if echo - * - * @throws LayoutException On error - */ - public function display($file, $directory = null, $directOutput = false) - { - $output = Factory::getInstance()->output; - $directory = (is_null($directory) ? $this->directory : $directory); - - if ($directOutput === true) - { - echo $this->get($file, $directory); - } - else - { - $output->append_output($this->get($file, $directory)); - } - - return; - } - - /** - * Retrieve a template file using a string and a directory. - * - * What template file gets loaded depends on the template engine that is being used. - * PHP for example uses .php files. Providing this function with 'home/dashboard' will load the home/layout.dashboard.php file. - * You can also provide no particular engine, and the manager will decide what template to load. - * Remember that doing so will result in a LayoutException when multiple compatible files are found. - * - * @param string $file File to load - * @param string $directory Directory to load it from - * - * @return string The output of the template - * - * @throws LayoutException On error - */ - public function get($file, $directory = null): string - { - $directory = (is_null($directory) ? $this->directory : $directory); - Logger::newLevel("Loading template file '".$file."' in '".$directory."'"); - - // First load the template engines - $this->loadTemplateEngines(); - - // First retrieve the filepath - if (is_null($this->current_engine)) { - $this->setFileFromString($file, $directory, array_keys($this->file_extensions)); - } else { - $this->setFileFromString($file, $directory, $this->current_engine->getFileExtensions()); - } - - // Then assign some basic variables for the template - $main_config = Factory::getInstance()->config->get('main'); - $contact_config = Factory::getInstance()->config->get('contact'); - $this->assigned_variables['wwwDir'] = $main_config->base_url; - $this->assigned_variables['siteURL'] = $main_config->base_url; - $this->assigned_variables['serverName'] = $main_config->server_name; - $this->assigned_variables['adminMail'] = $main_config->administrator_mail; - $this->assigned_variables['contact'] = $contact_config->toArray(); - $this->assigned_variables['csrfTokenName'] = Factory::getInstance()->security->get_csrf_token_name(); - $this->assigned_variables['csrfHash'] = Factory::getInstance()->security->get_csrf_hash(); - - // Select an engine if one is not already selected - if (is_null($this->current_engine)) { - $this->current_engine = $this->getEngineFromExtension($this->getExtensionFromFile($this->file)); - } - - $this->current_engine->setDirectory($this->directory); - - // And run an Event to see what other parts have to say about it - $event = Events::fireEvent('layoutLoadEvent', $this->file, $this->directory, $this->current_engine, $this->assigned_variables); - - // The event has been cancelled - if ($event->isCancelled()) { - return false; - } - - // And refetch the data from the event - $this->current_engine = $event->engine; - $this->assigned_variables = $event->assigned_variables; - - Logger::stopLevel(); - - // And finally run it - if (file_exists($event->file)) { - return $this->current_engine->get($event->file, $this->assigned_variables); - } - - throw new LayoutException('The requested file was not found', 1); - } - - /** - * Retrieve a Template Engine from a File Extension. - * - * @param string $extension File extention to look for - * - * @return TemplateEngine - */ - public function getEngineFromExtension($extension): TemplateEngine - { - if (isset($this->file_extensions[strtolower($extension)])) { - return $this->engines[ $this->file_extensions[strtolower($extension)]]; - } - - throw new LayoutException('Could not get Template Engine. No engine has corresponding file extension', 1); - } - - /** - * Retrieve the extension from a file string. - * - * @param string $fileString The path to the file - * - * @return string Extension of the file - */ - public function getExtensionFromFile($fileString): string - { - return substr($fileString, strrpos($fileString, '.') + 1); - } - - /** - * Converts a layout string to a file using the directory and the used extensions. - * - * It will detect whether the file exists and choose a file according to the provided extensions - * - * @param string $string The string used by a controller. eg: 'dashboard/home' - * @param string $directory The directory to search in for the template - * @param array $extensions Extensions to use for this template. Eg array('php', 'tpl') etc. - * - * @return string Filepath of the template - * @throws LayoutException On error - */ - public function getFileFromString($string, $directory, $extensions = array()): string - { - $directory = preg_replace('#/+#', '/', (!is_null($directory) ? $directory : $this->directory).DS); - - if (strpbrk($directory, "\\/?%*:|\"<>") === TRUE || strpbrk($string, "\\/?%*:|\"<>") === TRUE) - { - throw new LayoutException('Could not get file. Invalid file string', 1); - } - - if (!file_exists($directory)) { - throw new LayoutException('Could not get file. Directory does not exist', 1); - } - - // Set the file name and location - $layoutSelector = explode('/', $string); - if (count($layoutSelector) == 1) { - $layoutSelector = 'layout.'.$layoutSelector[0]; - } else { - // Get last file - $file = end($layoutSelector); - - // Reset to start - reset($layoutSelector); - - // Remove last value - array_pop($layoutSelector); - - $layoutSelector[] = 'layout.'.$file; - - // And create the final value - $layoutSelector = implode(DS, $layoutSelector); - } - - // Then try and select a file - $fileSelected = false; - $selectedFile = null; - foreach ($extensions as $extension) { - $file = $directory.$layoutSelector.'.'.strtolower($extension); - $file = preg_replace('#/+#', '/', $file); - if (file_exists($file) && !$fileSelected) { - $selectedFile = $file; - $fileSelected = true; - Logger::log("Found matching file: '".$file."'"); - } elseif (file_exists($file) && $fileSelected) { - throw new LayoutException('Could not select template. Multiple valid extensions detected. Can not choose.', 1); - } - } - - // And choose what to output - if (!$fileSelected) { - throw new LayoutException('Could not select template. No matching file found.'); - } - - return $selectedFile; - } - - /** - * Converts a layout string to a file using the directory and the used extensions. - * It also sets the file variable of this class. - * - * It will detect whether the file exists and choose a file according to the provided extensions - * - * @param string $string The string used by a controller. eg: 'dashboard/home' - * @param string $directory The directory to search in for the template - * @param array $extensions Extensions to use for this template. Eg array('php', 'tpl') etc. - * - * @return string Filepath of the template - * @throws LayoutException On error - */ - public function setFileFromString($string, $directory, $extensions = array()) - { - $this->file = $this->getFileFromString($string, $directory, $extensions); - $this->directory = preg_replace('#/+#', '/', (!is_null($directory) ? $directory : $this->directory).DS); - } - - /** - * Get the current file to be loaded. - * - * @return null|string Path to the file - */ - public function getFile() - { - return $this->file; - } - - /** - * Set the file to be loaded. - * - * @param string $file Path to the file - */ - public function setFile($file): string - { - $this->file = $file; - } - - /** - * Get the directory of the file to be loaded. - * - * @return null|string Path to the directory - */ - public function getDirectory() - { - return $this->directory; - } - - /** - * Set the directory of the file to be loaded. - * - * @param string $directory Path to the directory - */ - public function setDirectory($directory) - { - $this->directory = $directory; - } - - /** - * Assign a variable for the template. - * - * @param string $key Key of the variable - * @param mixed $value Value of the variable - */ - public function assign($key, $value) - { - $this->assigned_variables[$key] = $value; - } - - /** - * Set the title of the template. - * - * @param string $title title of the template - */ - public function setTitle($title) - { - $this->assigned_variables['title'] = $title; - } - - /** - * Get the title of the template. - * - * @return string|bool title of the template - */ - public function getTitle() - { - if (!isset($this->assigned_variables['title'])) - { - return false; - } - return $this->assigned_variables['title']; - } - - /** - * Set the engine for the next layout. - * - * @param string $name Name of the template engine - * - * @return bool true on success - * @throws LayoutException on error - */ - public function setEngine($name): bool - { - $this->loadTemplateEngines(); - if (isset($this->engines[$name])) { - $this->current_engine = $this->engines[$name]; - Logger::log('Set the Template Engine to '.$name); - - return true; - } - throw new LayoutException('Could not set engine. Engine does not exist', 1); - } - - /** - * Reset the engine so a new one can be used the next time - * - */ - public function resetEngine() - { - $this->current_engine = null; - Logger::log('Reset the active engine for Layout'); - } - - /** - * Get a loaded template engine. - * - * @param string $name Name of the template engine - * - * @return TemplateEngine - */ - public function getEngine($name): TemplateEngine - { - $this->loadTemplateEngines(); - if (isset($this->engines[$name])) { - return $this->engines[$name]; - } - throw new LayoutException('Could not return engine. Engine does not exist', 1); - } - - /** - * Register a new template engine. - * - * @param object $engineClass Object that implements the \FuzeWorks\TemplateEngine - * @param string $engineName Name of the template engine - * @param array $engineFileExtensions File extensions this template engine should be used for - * - * @return bool true on success - * @throws LayoutException - */ - public function registerEngine($engineClass, $engineName, $engineFileExtensions = array()): bool - { - // First check if the engine already exists - if (isset($this->engines[$engineName])) { - throw new LayoutException("Could not register engine. Engine '".$engineName."' already registered", 1); - } - - // Then check if the object is correct - if ($engineClass instanceof TemplateEngine) { - // Install it - $this->engines[$engineName] = $engineClass; - - // Then define for what file extensions this Template Engine will work - if (!is_array($engineFileExtensions)) { - throw new LayoutException('Could not register engine. File extensions must be an array', 1); - } - - // Then install them - foreach ($engineFileExtensions as $extension) { - if (isset($this->file_extensions[strtolower($extension)])) { - throw new LayoutException('Could not register engine. File extension already bound to engine', 1); - } - - // And add it - $this->file_extensions[strtolower($extension)] = $engineName; - } - - // And log it - Logger::log('Registered Template Engine: '.$engineName); - - return true; - } - - throw new LayoutException("Could not register engine. Engine must implement \FuzeWorks\TemplateEngine", 1); - } - - /** - * Load the template engines by sending a layoutLoadEngineEvent. - */ - public function loadTemplateEngines() - { - if (!$this->engines_loaded) { - Events::fireEvent('layoutLoadEngineEvent'); - - // Load the engines provided in this file - $this->registerEngine(new PHPEngine(), 'PHP', array('php')); - $this->registerEngine(new JsonEngine(), 'JSON', array('json')); - $this->registerEngine(new SmartyEngine(), 'Smarty', array('tpl')); - $this->registerEngine(new LatteEngine(), 'Latte', array('latte')); - $this->engines_loaded = true; - } - } - - /** - * Calls a function in the current Template engine. - * - * @param string $name Name of the function to be called - * @param mixed $params Parameters to be used - * - * @return mixed Function output - */ - public static function __callStatic($name, $params) - { - // First load the template engines - $this->loadTemplateEngines(); - - if (!is_null($this->current_engine)) { - // Call user func array here - return call_user_func_array(array($this->current_engine, $name), $params); - } - throw new LayoutException('Could not access Engine. Engine not loaded', 1); - } - - /** - * Resets the layout manager to its default state. - */ - public function reset() - { - if (!is_null($this->current_engine)) { - $this->current_engine->reset(); - } - - // Unload the engines - $this->engines = array(); - $this->engines_loaded = false; - $this->file_extensions = array(); - - $this->current_engine = null; - $this->assigned_variables = array(); - $this->directory = Core::$appDir . DS . 'Layout'; - Logger::log('Reset the layout manager to its default state'); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/Libraries.php b/src/FuzeWorks/Libraries.php index 4f05b67..d4735df 100644 --- a/src/FuzeWorks/Libraries.php +++ b/src/FuzeWorks/Libraries.php @@ -91,8 +91,8 @@ class Libraries public function __construct() { $this->factory = Factory::getInstance(); + $this->libraryPaths = Core::$appDirs; $this->libraryPaths[] = Core::$coreDir . DS . 'Libraries'; - $this->libraryPaths[] = Core::$appDir . DS . 'Libraries'; } /** diff --git a/src/FuzeWorks/Logger.php b/src/FuzeWorks/Logger.php index 20a447a..1e686ac 100644 --- a/src/FuzeWorks/Logger.php +++ b/src/FuzeWorks/Logger.php @@ -34,7 +34,6 @@ namespace FuzeWorks; use FuzeWorks\Exception\Exception; -use FuzeWorks\Exception\LayoutException; /** * Logger Class. @@ -104,19 +103,32 @@ class Logger { */ public function __construct() { + // Get the config file + $cfg_error = Factory::getInstance()->config->getConfig('error'); + // Register the error handler, Untestable // @codeCoverageIgnoreStart - if (Factory::getInstance()->config->get('error')->error_reporting == true && self::$useTracy === false) { + if ($cfg_error->fuzeworks_error_reporting == true) + { set_error_handler(array('\FuzeWorks\Logger', 'errorHandler'), E_ALL); - set_Exception_handler(array('\FuzeWorks\Logger', 'exceptionHandler')); + set_Exception_handler(array('\FuzeWorks\Logger', 'exceptionHandler')); + } + elseif ($cfg_error->tracy_error_reporting == true && self::$useTracy === true) + { + // Register with tracy } // @codeCoverageIgnoreEnd - error_reporting(false); + // Set PHP error reporting + if (!$cfg_error->php_error_reporting) + error_reporting(false); + else + error_reporting(true); + // Set the environment variables self::$debug = (ENVIRONMENT === 'DEVELOPMENT'); - self::$log_to_file = Factory::getInstance()->config->get('error')->log_to_file; - self::$logger_template = Factory::getInstance()->config->get('error')->logger_template; + self::$log_to_file = $cfg_error->log_to_file; + self::$logger_template = $cfg_error->logger_template; self::newLevel('Logger Initiated'); if (self::$useTracy) @@ -173,7 +185,6 @@ class Logger { // Log it! $thisType = self::getType($errno); - Factory::getInstance()->output->set_output(''); self::errorHandler($errno, $errstr, $errfile, $errline); if ($thisType == 'ERROR') @@ -537,16 +548,7 @@ class Logger { self::log('Loading layout ' . $layout); // Try and load the layout, if impossible, load HTTP code instead. - $factory = Factory::getInstance(); - try { - $factory->layout->reset(); - $factory->layout->assign('httpErrorMessage', $message); - $factory->layout->display($layout); - } catch (LayoutException $exception) { - // No error page could be found, just echo the result - $factory->output->set_output("

$errno

" . $http_codes[$errno] . '

' . $message . '

'); - } - + echo "

$errno

" . $http_codes[$errno] . '

' . $message . '

'; return true; } diff --git a/src/FuzeWorks/ModelAbstract.php b/src/FuzeWorks/ModelAbstract.php deleted file mode 100644 index 5bd43fb..0000000 --- a/src/FuzeWorks/ModelAbstract.php +++ /dev/null @@ -1,46 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Abstract class ModelAbstract. - * - * Extends all models to use the Factory. - * Factory should in the future be replaced with a DI container - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -abstract class ModelAbstract extends Factory -{ -} \ No newline at end of file diff --git a/src/FuzeWorks/Models.php b/src/FuzeWorks/Models.php deleted file mode 100644 index 87fb938..0000000 --- a/src/FuzeWorks/Models.php +++ /dev/null @@ -1,200 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\Exception\ModelException; - -/** - * Models Class. - * - * Simple loader class for MVC Models. - * Typically loads models from Application/Models unless otherwise specified. - * - * If a model is not found, it will load a DatabaseModel type which will - * analyze the database and can directly be used. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class Models -{ - - /** - * Paths where Models can be found. - * - * Models will only be loaded if either a directory is supplied or it is in one of the modelPaths - * - * @var array Array of paths where models can be found - */ - protected $modelPaths = array(); - - public function __construct() - { - $this->modelPaths[] = Core::$appDir . DS . 'Models'; - } - - /** - * Get a model. - * - * Supply the name and the model will be loaded from the supplied directory, - * or from one of the modelPaths (which you can add). - * - * @param string $modelName Name of the model - * @param string|null $directory Directory to load the model from, will ignore $modelPaths - * @return ModelAbstract|bool The Model object - */ - public function get($modelName, $directory = null) - { - if (empty($modelName)) - { - throw new ModelException("Could not load model. No name provided", 1); - } - - // First get the directories where the model can be located - $directories = (is_null($directory) ? $this->modelPaths : array($directory)); - - // Fire a model load event - $event = Events::fireEvent('modelLoadEvent', $modelName, $directories); - $directories = $event->directories; - $modelName = $event->modelName; - - // If the event is cancelled, stop loading - if ($event->isCancelled()) - { - return false; - } - - // And attempt to load the model - return $this->loadModel($modelName, $directories); - } - - /** - * Load and return a model. - * - * Supply the name and the model will be loaded from one of the supplied directories - * - * @param string $modelName Name of the model - * @param array $directories Directories to try and load the model from - * @return ModelAbstract The Model object - */ - protected function loadModel($modelName, $directories): ModelAbstract - { - if (empty($directories)) - { - throw new ModelException("Could not load model. No directories provided", 1); - } - - // Now figure out the className and subdir - $class = trim($modelName, '/'); - if (($last_slash = strrpos($class, '/')) !== FALSE) - { - // Extract the path - $subdir = substr($class, 0, ++$last_slash); - - // Get the filename from the path - $class = substr($class, $last_slash); - } - else - { - $subdir = ''; - } - - $class = ucfirst($class); - - // Search for the model file - foreach ($directories as $directory) { - - // Determine the file - $file = $directory . DS . $subdir . "model." . strtolower($class) . '.php'; - $className = '\Application\Model\\'.$class; - - // If the class already exists, return a new instance directly - if (class_exists($className, false)) - { - return new $className(); - } - - // If it doesn't, try and load the file - if (file_exists($file)) - { - include_once($file); - return new $className(); - } - } - - // Maybe it's in a subdirectory with the same name as the class - if ($subdir === '') - { - return $this->loadModel($class."/".$class, $directories); - } - - throw new ModelException("Could not load model. Model was not found", 1); - } - - /** - * Add a path where models can be found - * - * @param string $directory The directory - * @return void - */ - public function addModelPath($directory) - { - if (!in_array($directory, $this->ModelPaths)) - { - $this->modelPaths[] = $directory; - } - } - - /** - * Remove a path where models can be found - * - * @param string $directory The directory - * @return void - */ - public function removeModelPath($directory) - { - if (($key = array_search($directory, $this->modelPaths)) !== false) - { - unset($this->modelPaths[$key]); - } - } - - /** - * Get a list of all current ModelPaths - * - * @return array Array of paths where models can be found - */ - public function getModelPaths(): array - { - return $this->modelPaths; - } -} \ No newline at end of file diff --git a/src/FuzeWorks/Output.php b/src/FuzeWorks/Output.php deleted file mode 100644 index ded2bd3..0000000 --- a/src/FuzeWorks/Output.php +++ /dev/null @@ -1,791 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Output Class - * - * Responsible for sending final output to the browser. - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Output { - - /** - * Final output string - * - * @var string - */ - public $final_output; - - /** - * Cache expiration time - * - * @var int - */ - public $cache_expiration = 0; - - /** - * List of server headers - * - * @var array - */ - public $headers = array(); - - /** - * List of mime types - * - * @var array - */ - public $mimes = array(); - - /** - * Mime-type for the current page - * - * @var string - */ - protected $mime_type = 'text/html'; - - /** - * Enable Profiler flag - * - * @var bool - */ - public $enable_profiler = FALSE; - - /** - * php.ini zlib.output_compression flag - * - * @var bool - */ - protected $_zlib_oc = FALSE; - - /** - * CI output compression flag - * - * @var bool - */ - protected $_compress_output = FALSE; - - /** - * List of profiler sections - * - * @var array - */ - protected $_profiler_sections = array(); - - /** - * Parse markers flag - * - * Whether or not to parse variables like {elapsed_time} and {memory_usage}. - * - * @var bool - */ - public $parse_exec_vars = TRUE; - - /** - * Factory Object - * @var Factory - */ - protected $factory; - protected $config; - protected $uri; - protected $router; - - /** - * Class constructor - * - * Determines whether zLib output compression will be used. - * - * @return void - */ - public function __construct() - { - $this->factory = Factory::getInstance(); - $this->config = $this->factory->config; - $this->uri = $this->factory->uri; - - $this->_zlib_oc = (bool) ini_get('zlib.output_compression'); - $this->_compress_output = ( - $this->_zlib_oc === FALSE - && $this->config->main->compress_output === TRUE - && extension_loaded('zlib') - ); - - // Get mime types for later - $this->mimes = $this->config->mimes->toArray(); - } - - // -------------------------------------------------------------------- - - /** - * Get Output - * - * Returns the current output string. - * - * @return string - */ - public function get_output(): string - { - return $this->final_output; - } - - // -------------------------------------------------------------------- - - /** - * Set Output - * - * Sets the output string. - * - * @param string $output Output data - * @return self - */ - public function set_output($output): self - { - $this->final_output = $output; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Append Output - * - * Appends data onto the output string. - * - * @param string $output Data to append - * @return self - */ - public function append_output($output): self - { - $this->final_output .= $output; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Header - * - * Lets you set a server header which will be sent with the final output. - * - * Note: If a file is cached, headers will not be sent. - * @todo We need to figure out how to permit headers to be cached. - * - * @param string $header Header - * @param bool $replace Whether to replace the old header value, if already set - * @return self - */ - public function set_header($header, $replace = TRUE): self - { - // If zlib.output_compression is enabled it will compress the output, - // but it will not modify the content-length header to compensate for - // the reduction, causing the browser to hang waiting for more data. - // We'll just skip content-length in those cases. - if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0) - { - return $this; - } - - $this->headers[] = array($header, $replace); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Content-Type Header - * - * @param string $mime_type Extension of the file we're outputting - * @param string $charset Character set (default: NULL) - * @return self - */ - public function set_content_type($mime_type, $charset = NULL): self - { - if (strpos($mime_type, '/') === FALSE) - { - $extension = ltrim($mime_type, '.'); - - // Is this extension supported? - if (isset($this->mimes[$extension])) - { - $mime_type =& $this->mimes[$extension]; - - if (is_array($mime_type)) - { - $mime_type = current($mime_type); - } - } - } - - $this->mime_type = $mime_type; - - if (empty($charset)) - { - $charset = Config::get('main')->charset; - } - - $header = 'Content-Type: '.$mime_type - .(empty($charset) ? '' : '; charset='.$charset); - - $this->headers[] = array($header, TRUE); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Current Content-Type Header - * - * @return string 'text/html', if not already set - */ - public function get_content_type(): string - { - for ($i = 0, $c = count($this->headers); $i < $c; $i++) - { - if (sscanf($this->headers[$i][0], 'Content-Type: %[^;]', $content_type) === 1) - { - return $content_type; - } - } - - return 'text/html'; - } - - // -------------------------------------------------------------------- - - /** - * Get Header - * - * @param string $header_name - * @return string|null - */ - public function get_header($header) - { - // Combine headers already sent with our batched headers - $headers = array_merge( - // We only need [x][0] from our multi-dimensional array - array_map('array_shift', $this->headers), - headers_list() - ); - - if (empty($headers) OR empty($header)) - { - return NULL; - } - - for ($i = 0, $c = count($headers); $i < $c; $i++) - { - if (strncasecmp($header, $headers[$i], $l = strlen($header)) === 0) - { - return trim(substr($headers[$i], $l+1)); - } - } - - return NULL; - } - - // -------------------------------------------------------------------- - - /** - * Set HTTP Status Header - * - * As of version 1.7.2, this is an alias for common function - * set_status_header(). - * - * @param int $code Status code (default: 200) - * @param string $text Optional message - * @return self - */ - public function set_status_header($code = 200, $text = ''): self - { - Core::setStatusHeader($code, $text); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Enable/disable Profiler - * - * @param bool $val TRUE to enable or FALSE to disable - * @return self - */ - public function enable_profiler($val = TRUE): self - { - $this->enable_profiler = is_bool($val) ? $val : TRUE; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Profiler Sections - * - * Allows override of default/config settings for - * Profiler section display. - * - * @param array $sections Profiler sections - * @return self - */ - public function set_profiler_sections($sections): self - { - if (isset($sections['query_toggle_count'])) - { - $this->_profiler_sections['query_toggle_count'] = (int) $sections['query_toggle_count']; - unset($sections['query_toggle_count']); - } - - foreach ($sections as $section => $enable) - { - $this->_profiler_sections[$section] = ($enable !== FALSE); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Cache - * - * @param int $time Cache expiration time in minutes - * @return self - */ - public function cache($time): self - { - $this->cache_expiration = is_numeric($time) ? $time : 0; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Display Output - * - * Processes and sends finalized output data to the browser along - * with any server headers and profile data. It also stops benchmark - * timers so the page rendering speed and memory usage can be shown. - * - * Note: All "layout" data is automatically put into $this->final_output - * by controller class. - * - * @uses Output::$final_output - * @param string $output Output data override - * @return void - */ - public function _display($output = '') - { - $router = $this->factory->router; - // Grab the super object if we can. - if ($router->getCallable() === null) - { - $use_cache = true; - } - else - { - $use_cache = false; - } - - // -------------------------------------------------------------------- - - // Set the output data - if ($output === '') - { - $output =& $this->final_output; - } - - // -------------------------------------------------------------------- - - // Do we need to write a cache file? Only if the controller does not have its - // own _output() method and we are not dealing with a cache file, which we - // can determine by the existence of the $CI object above - if ($this->cache_expiration > 0 && $use_cache === false) - { - $this->_write_cache($output); - } - - // -------------------------------------------------------------------- - - if ($this->parse_exec_vars === TRUE) - { - $memory = round(memory_get_usage() / 1024 / 1024, 2).'MB'; - $output = str_replace(array('{memory_usage}'), array($memory), $output); - } - - // -------------------------------------------------------------------- - - // Is compression requested? - if ($use_cache === false // This means that we're not serving a cache file, if we were, it would already be compressed - && $this->_compress_output === TRUE - && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) - { - ob_start('ob_gzhandler'); - } - - // -------------------------------------------------------------------- - - // Are there any server headers to send? - if (count($this->headers) > 0) - { - foreach ($this->headers as $header) - { - @header($header[0], $header[1]); - } - } - - // -------------------------------------------------------------------- - - if ( $use_cache === true) - { - if ($this->_compress_output === TRUE) - { - if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) - { - header('Content-Encoding: gzip'); - header('Content-Length: '.strlen($output)); - } - else - { - // User agent doesn't support gzip compression, - // so we'll have to decompress our cache - $output = gzinflate(substr($output, 10, -8)); - } - } - - echo $output; - Logger::log('Final output sent to browser'); - return; - } - - // -------------------------------------------------------------------- - - // Do we need to generate profile data? - // If so, load the Profile class and run it. - if ($this->enable_profiler === TRUE) - { - Logger::logWarning("Profiler not yet implemented"); - return; - - $CI->load->library('profiler'); - if ( ! empty($this->_profiler_sections)) - { - $CI->profiler->set_sections($this->_profiler_sections); - } - - // If the output data contains closing and tags - // we will remove them and add them back after we insert the profile data - $output = preg_replace('|.*?|is', '', $output, -1, $count).$CI->profiler->run(); - if ($count > 0) - { - $output .= ''; - } - } - - echo $output; - - Logger::log('Output sent to browser'); - } - - // -------------------------------------------------------------------- - - /** - * Write Cache - * - * @param string $output Output data to cache - * @return void - */ - public function _write_cache($output) - { - $cache_path = Core::$tempDir . DS . 'Output' . DS; - - // First try and see if the directory exists - if ( ! is_dir($cache_path)) - { - // Then try and create the directory - if (!mkdir($cache_path, 0777, false)) - { - Logger::logError('Unable to write cache file: \''.$cache_path.'\' Cannot create directory'); - return; - } - } - - if (! Core::isReallyWritable($cache_path)) - { - Logger::logError('Unable to write cache file: \''.$cache_path.'\' Directory not writeable'); - return; - } - - $uri = $this->config->main->base_url - .$this->config->main->index_page - .$this->uri->uri_string(); - - if (($cache_query_string = $this->config->cache->cache_query_string) && ! empty($_SERVER['QUERY_STRING'])) - { - if (is_array($cache_query_string)) - { - $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); - } - else - { - $uri .= '?'.$_SERVER['QUERY_STRING']; - } - } - - $cache_path .= md5($uri); - - if ( ! $fp = @fopen($cache_path, 'w+b')) - { - Logger::logError('Unable to write cache file: \''.$cache_path.'\' Directory not writeable'); - return; - } - - if (flock($fp, LOCK_EX)) - { - // If output compression is enabled, compress the cache - // itself, so that we don't have to do that each time - // we're serving it - if ($this->_compress_output === TRUE) - { - $output = gzencode($output); - - if ($this->get_header('content-type') === NULL) - { - $this->set_content_type($this->mime_type); - } - } - - $expire = time() + ($this->cache_expiration * 60); - - // Put together our serialized info. - $cache_info = serialize(array( - 'expire' => $expire, - 'headers' => $this->headers - )); - - $output = $cache_info.'ENDCI--->'.$output; - - for ($written = 0, $length = strlen($output); $written < $length; $written += $result) - { - if (($result = fwrite($fp, substr($output, $written))) === FALSE) - { - break; - } - } - - flock($fp, LOCK_UN); - } - else - { - Logger::logError('Unable to secure a file lock for file at: '.$cache_path); - return; - } - - fclose($fp); - - if (is_int($result)) - { - chmod($cache_path, 0640); - Logger::logDebug('Cache file written: '.$cache_path); - - // Send HTTP cache-control headers to browser to match file cache settings. - $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); - } - else - { - @unlink($cache_path); - Logger::logError('Unable to write the complete cache content at: '.$cache_path); - } - } - - // -------------------------------------------------------------------- - - /** - * Update/serve cached output - * - * @uses Config - * @uses URI - * - * @return bool TRUE on success or FALSE on failure - */ - public function _display_cache(): bool - { - $cache_path = Core::$tempDir . DS . 'Output' . DS; - - // Build the file path. The file name is an MD5 hash of the full URI - $main = $this->config->main; - $uri = $main->base_url.$main->index_page.$this->uri->uri_string; - - if (($cache_query_string = $this->config->cache->cache_query_string) && ! empty($_SERVER['QUERY_STRING'])) - { - if (is_array($cache_query_string)) - { - $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); - } - else - { - $uri .= '?'.$_SERVER['QUERY_STRING']; - } - } - - $filepath = $cache_path.md5($uri); - - if ( ! file_exists($filepath) OR ! $fp = @fopen($filepath, 'rb')) - { - Logger::logDebug("No cache file for $uri found"); - return FALSE; - } - - flock($fp, LOCK_SH); - - $cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : ''; - - flock($fp, LOCK_UN); - fclose($fp); - - // Look for embedded serialized file info. - if ( ! preg_match('/^(.*)ENDCI--->/', $cache, $match)) - { - return FALSE; - } - - $cache_info = unserialize($match[1]); - $expire = $cache_info['expire']; - - $last_modified = filemtime($filepath); - - // Has the file expired? - if ($_SERVER['REQUEST_TIME'] >= $expire && Core::isReallyWritable($cache_path)) - { - // If so we'll delete it. - @unlink($filepath); - Logger::logDebug('Cache file has expired. File deleted.'); - return FALSE; - } - else - { - // Or else send the HTTP cache control headers. - $this->set_cache_header($last_modified, $expire); - } - - // Add headers from cache file. - foreach ($cache_info['headers'] as $header) - { - $this->set_header($header[0], $header[1]); - } - - // Display the cache - $this->_display(substr($cache, strlen($match[0]))); - Logger::logDebug('Cache file is current. Sending it to browser.'); - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Delete cache - * - * @param string $uri URI string - * @return bool - */ - public function delete_cache($uri = ''): bool - { - $cache_path = Core::$tempDir . DS . 'Output' . DS; - - if ( ! is_dir($cache_path)) - { - Logger::logError('Unable to find cache path: '.$cache_path); - return FALSE; - } - - if (empty($uri)) - { - $uri = $this->uri->uri_string(); - - if (($cache_query_string = $this->config->cache->cache_query_string) && ! empty($_SERVER['QUERY_STRING'])) - { - if (is_array($cache_query_string)) - { - $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); - } - else - { - $uri .= '?'.$_SERVER['QUERY_STRING']; - } - } - } - - $cache_path .= md5($this->config->mainbase_url.$this->config->main->index_page.ltrim($uri, '/')); - - if ( ! @unlink($cache_path)) - { - Logger::logError('Unable to delete cache file for '.$uri); - return FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Set Cache Header - * - * Set the HTTP headers to match the server-side file cache settings - * in order to reduce bandwidth. - * - * @param int $last_modified Timestamp of when the page was last modified - * @param int $expiration Timestamp of when should the requested page expire from cache - * @return void - */ - public function set_cache_header($last_modified, $expiration) - { - $max_age = $expiration - $_SERVER['REQUEST_TIME']; - - if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $last_modified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) - { - $this->set_status_header(304); - exit; - } - else - { - header('Pragma: public'); - header('Cache-Control: max-age='.$max_age.', public'); - header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); - header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); - } - } - -} diff --git a/src/FuzeWorks/Plugins.php b/src/FuzeWorks/Plugins.php index 6790823..53168ba 100644 --- a/src/FuzeWorks/Plugins.php +++ b/src/FuzeWorks/Plugins.php @@ -93,8 +93,8 @@ class Plugins */ public function __construct() { - $this->pluginPaths[] = Core::$appDir . DS . 'Plugins'; $this->cfg = Factory::getInstance()->config->plugins; + $this->pluginPaths = Core::$appDirs; } /** diff --git a/src/FuzeWorks/Router.php b/src/FuzeWorks/Router.php deleted file mode 100644 index dc32428..0000000 --- a/src/FuzeWorks/Router.php +++ /dev/null @@ -1,588 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Class Router. - * - * This class handles the framework's routing. The router determines which system should be loaded and called. - * The overall structure of the routing is as follows: - * - * The routes-array will hold a list of RegEx-strings. When the route-method is called, the framework will try - * to match the current path found in the URI class against all the RegEx's. When a RegEx matches, - * it will try and load what the route is related to. This can be a callable or a translator. A translator will - * convert the values of a route into a callable. In the end a callable will always be loaded. - * - * Every module can register routes and add their own callables. By default, two callables are available: - * The defaultCallable and the moduleCallable of which the last one is found in the Modules class. - * - * The defaultCallable is a traditional MVC controller loader. Loading an URL when no route matches works as follows: - * - * Let's say the visitor requests /A/B/C - * - * A would be the 'controller' (default: standard) - * B would be the function to be called in the 'controller' (default: index) - * C would be the first parameter - * - * All controllers are to be placed in the /Application/Controller - directory. - * - * This is the default behaviour by adding routes to the config.routes.php. It is also possible to load Modules using routes. - * To load a Module using a route, add the route to the moduleInfo.php in a routes array. - * When this route is matched, a moduleCallable gets loaded which loads the module and loads either a controller file, or a routing function. - * - * But because of this RegEx-table, modules can easily listen on completely different paths. You can, for example, make - * a module that only triggers when /admin///.. is accessed. Or even complexer structure are - * available, e.g: /webshop/product-/view/. - * - * BE AWARE: - * - * Callables are NO controllers!! By default, the 'defaultCallable' will load the correct controller from - * the default controller directory. When you make custom routes, the callable will need to call your own - * controllers. This means that the one callable you provide with your RegEx will be called for EVERYTHING - * the RegEx matches. Only the regex matches will be provided to the callable, - * if no names groups are available; you will need to extract them yourself from the path. - * - * After the core has been loaded, the URI class will generate the URI which is currently being used. - * The index file will then call the route-method, which will call the right controller and it's associated method. - * - * @see Router::route - * @see Router::addRoute - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * - * @todo Implement Query Strings - */ -class Router -{ - /** - * @var array Routes - */ - protected $routes = array(); - - /** - * @var null|mixed The callable - */ - protected $callable = null; - - /** - * @var null|array The extracted matches from the regex - */ - protected $matches = null; - - /** - * Directory from which to load the controllers - * - * @var string Controller directory - */ - protected $controller_directory; - - /** - * The Config class used to get configurations - * - * @var Config FuzeWorks config class - */ - protected $config; - - /** - * The Uri class used to get paths - * - * @var Uri FuzeWorks uri class - */ - protected $uri; - - /** - * The Logger class used to log information - * - * @var Logger FuzeWorks logger class - */ - protected $logger; - - /** - * The Events class used to fire events - * - * @var Events FuzeWorks events class - */ - protected $events; - - /** - * The Output class used to parse cache data - * - * @var Output FuzeWorks output class - */ - protected $output; - - /** - * Constructor of the Router - * - * Loads all required classes and adds all the routes to the routingTable - * - * @return void - */ - public function __construct() - { - // Load related classes - $factory = Factory::getInstance(); - $this->config = $factory->config; - $this->uri = $factory->uri; - $this->logger = $factory->logger; - $this->events = $factory->events; - $this->output = $factory->output; - $this->controller_directory = Core::$appDir . DS . 'Controller'; - - // Start parsing the routing - $this->parseRouting(); - } - - /** - * Route Parser - * - * This method parses all the routes in the routes table config file - * and adds them to the Router. It converts some routes which use wildcards - * - * @return void - */ - protected function parseRouting() - { - // Get routing routes - $routes = $this->config->routes; - $routing = $this->config->routing; - - // If no query strings are used, we will add all routes in the config.routes.php file. - // We modify these routes to be an array of a regex string and a callable - $http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli'; - - foreach ($routes as $route => $value) - { - // Check if the route format is using HTTP verbs - if (is_int($route)) - { - $route = $value; - $value = array($this, 'defaultCallable'); - } - elseif (is_array($value)) - { - $value = array_change_key_case($value, CASE_LOWER); - if (isset($value[$http_verb])) - { - $value = $value[$http_verb]; - } - else - { - continue; - } - } - - // Convert wildcards to Regex - $route = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $route); - - $this->addRoute($route, $value, false); - } - } - - /** - * Returns the directory from which all controllers shall be loaded - * - * @return string - */ - public function getControllerDirectory(): string - { - return $this->controller_directory; - } - - /** - * Sets the directory from which all controllers shall be loaded - * - * @param string Controller directory - */ - public function setControllerDirectory($directory) - { - $this->controller_directory = $directory; - } - - /** - * Returns an array with all the routes. - * - * @return array - */ - public function getRoutes(): array - { - return $this->routes; - } - - /** - * Returns the currently loaded or selected callable. - * - * @return null|callable - */ - public function getCallable() - { - return $this->callable; - } - - /** - * Returns all the matches with the RegEx route. - * - * @return null|array - */ - public function getMatches() - { - return $this->matches; - } - - /** - * Add a route to the Router's routing table - * - * The route consists of 2 parts: the route and data. - * - * The route is a regex string which will later be matched upon Router::route(). - * - * The data can be multiple things. First it can be a string, which will later be processed and turned into - * a callable. If the string is like 'controller/method' then the contoller 'Controller' will be loaded and the - * method 'method' will be called. The data can also be a callable. That callable will be called with all the regex - * that match the route. The callable is expected to return a string just like above. You can also provide an array. - * If you have an array like this: array('callable' => array('Class', 'method')) then your callable shall be used - * instead of the defaultCallabele. - * - * @param string $route This is a RegEx of the route, Every capture group will be a match, passed on to a callable - * @param mixed $data Can be multiple things. See description above - * @param bool $prepend Whether or not to insert at the beginning of the routing table - * @return void - */ - public function addRoute($route, $callable, $prepend = true) - { - if ($prepend) { - $this->routes = array($route => $callable) + $this->routes; - } else { - $this->routes[$route] = $callable; - } - - $this->logger->log('Route added at '.($prepend ? 'top' : 'bottom').': "'.$route.'"'); - } - - /** - * Removes a route from the array based on the given route. - * - * @param $route string The route to remove - */ - public function removeRoute($route) - { - unset($this->routes[$route]); - - $this->logger->log('Route removed: '.$route); - } - - /** - * Extracts the routing path from the URL using the routing table. - * - * Determines what should be loaded and what data matches the route regex. - * - * @param bool $performLoading Immediate process the route after it has been determined - */ - public function route($performLoading = true): bool - { - // Turn the segment array into a URI string - $uri = implode('/', $this->uri->segments); - - // Fire the event to notify our modules - $event = Events::fireEvent('routerRouteEvent', $this->routes, $performLoading, $uri); - - // The event has been cancelled - if ($event->isCancelled()) - { - return false; - } - - // Assign everything to the object to make it accessible, but let modules check it first - $routes = $event->routes; - $performLoading = $event->performLoading; - - // If a cached page should be loaded, do so and stop loading a routed page - if ($performLoading === true && $event->cacheOverride === false && $this->output->_display_cache() === true) - { - return true; - } - - // Check the custom routes - foreach ($routes as $route => $value) - { - // Match the path against the routes - if (preg_match('#^'.$route.'$#', $event->path, $matches)) - { - $this->logger->log('Route matched: '.$route); - // Save the matches - $this->matches = $matches; - - // Are we using callbacks or another method? - if ( is_array($value)) - { - // Maybe there is a real callable which should be called in the future - if ( isset($value['callable']) ) - { - $this->callable = $value['callable']; - } - - // If the callable is satisfied, break away - if (!$performLoading || $this->loadCallable($matches, $route)) - { - return true; - } - - // Otherwise try other routes - continue; - } - elseif ( is_callable($value) ) - { - // Prepare the callable - array_shift($matches); - - // Retrieve the path that should be loaded - $value = call_user_func_array($value, $matches); - } - elseif (strpos($value, '$') !== FALSE && strpos($route, '(') !== FALSE) - { - $value = preg_replace('#^'.$route.'$#', $value, $event->path); - } - - if ($performLoading === true) - { - // Now run the defaultRouter for when something is not a callable - $this->routeDefault(explode('/', $value), $route); - return true; - } - - return false; - } - } - - // If we got this far it means we didn't encounter a - // matching route so we'll set the site default route - $this->matches = array(); - if ($performLoading === true) - { - $this->routeDefault(array_values($this->uri->segments), '.*$'); - return true; - } - - return false; - } - - /** - * Converts a routing string into parameters for the defaultCallable. - * - * @param array $segments Segments of the controller,method,parameters to open - * @param string @route The route which was matched - * @return void - */ - protected function routeDefault($segments = array(), $route) - { - // If we don't have any segments left - try the default controller; - // WARNING: Directories get shifted out of the segments array! - if (empty($segments)) - { - $segments[0] = $this->config->routing->default_controller; - } - - if ($this->config->routing->translate_uri_dashes === true) - { - $segments[0] = str_replace('-', '_', $segments[0]); - if (isset($segments[1])) - { - $segments[1] = str_replace('-', '_', $segments[1]); - } - } - - // Prepare the values for loading - $controller = $segments[0]; - $function = (isset($segments[1]) ? $segments[1] : $this->config->routing->default_function); - - // And prepare the Router URI - array_unshift($segments, null); - unset($segments[0]); - $this->uri->rsegments = $segments; - - // Now create a matches array - $matches = array( - 'controller' => $controller, - 'function' => $function, - 'parameters' => array_slice($this->uri->rsegments, 2) - ); - - // And finally load the callable - $this->callable = array('\FuzeWorks\Router', 'defaultCallable'); - $this->loadCallable($matches, $route); - } - - /** - * Load the callable to which the route matched. - * - * First it checks if it is possible to call the callable. If not, the default callable gets selected and a controller, function and parameters get selected. - * - * Then the arguments get prepared and finally the callable is called. - * - * @param array Preg matches with the routing path - * @param string The route that matched - * - * @return bool Whether or not the callable was satisfied - */ - public function loadCallable($matches = array(), $route): bool - { - $this->logger->newLevel('Loading callable'); - - // Fire the event to notify our modules - $event = Events::fireEvent('routerLoadCallableEvent', $this->callable, $matches, $route); - - // The event has been cancelled - if ($event->isCancelled()) { - return false; - } - - // Prepare the arguments and add the route - $args = $event->matches; - $args['route'] = $event->route; - - if (!is_callable($event->callable)) { - if (isset($event->callable['controller'])) { - // Reset the arguments and fetch from custom callable - $args = array(); - $args['controller'] = isset($event->callable['controller']) ? $event->callable['controller'] : (isset($matches['controller']) ? $matches['controller'] : null); - $args['function'] = isset($event->callable['function']) ? $event->callable['function'] : (isset($matches['function']) ? $matches['function'] : null); - $args['parameters'] = isset($event->callable['parameters']) ? $event->callable['parameters'] : (isset($matches['parameters']) ? explode('/', $matches['parameters']) : null); - - $this->callable = array('\FuzeWorks\Router', 'defaultCallable'); - } else { - $this->logger->log('The given callable is not callable!', E_ERROR); - $this->logger->http_error(500); - $this->logger->stopLevel(); - - return true; - } - } else { - $this->callable = $event->callable; - } - - // And log the input to the logger - $this->logger->newLevel('Calling callable'); - foreach ($args as $key => $value) { - $this->logger->log($key.': '.var_export($value, true).''); - } - $this->logger->stopLevel(); - - $skip = call_user_func_array($this->callable, array($args)) === true; - - if (!$skip) { - $this->logger->log('Callable not satisfied, skipping to next callable'); - } - - $this->logger->stopLevel(); - - return $skip; - } - - /** - * The default callable. - * - * This callable will do the 'old skool' routing. It will load the controllers from the controller-directory - * in the application-directory. - */ - public function defaultCallable($arguments = array()): bool - { - $this->logger->log('Default callable called!'); - - $controller = $arguments['controller']; - $function = $arguments['function']; - $parameters = empty($arguments['parameters']) ? null : $arguments['parameters']; - - // Construct file paths and classes - $class = '\Application\Controller\\'.ucfirst($controller); - $directory = $this->controller_directory; - $file = $directory . DS . strtolower('controller.'.$controller.'.php'); - - $event = Events::fireEvent('routerLoadControllerEvent', - $file, - $directory, - $class, - $controller, - $function, - $parameters - ); - - // Cancel if requested to do so - if ($event->isCancelled()) { - return false; - } - - // Check if the file exists - if (file_exists($event->file)) { - if (!class_exists($event->className)) { - $this->logger->log('Loading controller '.$event->className.' from file: '.$event->file); - require $event->file; - } - - // Get the path the controller should know about - $path = implode('/', $this->uri->rsegments); - - // And create the controller - $this->callable = new $event->className($path); - - // If the controller does not want a function to be loaded, provide a halt parameter. - if (isset($this->callable->halt)) { - return false; - } - - // Check if method exists or if there is a caller function - if (method_exists($this->callable, $event->function) || method_exists($this->callable, '__call')) { - // Run the routerCallMethodEvent - $methodEvent = Events::fireEvent('routerCallMethodEvent'); - if ($methodEvent->isCancelled()) - { - return false; - } - - // Execute the function on the controller - $this->output->append_output($this->callable->{$event->function}($event->parameters)); - return true; - } else { - // Function could not be found - $this->logger->log('Could not find function '.$event->function.' on controller '.$event->className); - $this->logger->http_error(404); - } - } else { - // Controller could not be found - $this->logger->log('Could not find controller '.$event->className); - $this->logger->http_error(404); - } - - return false; - } -} diff --git a/src/FuzeWorks/Security.php b/src/FuzeWorks/Security.php deleted file mode 100644 index d3b9e17..0000000 --- a/src/FuzeWorks/Security.php +++ /dev/null @@ -1,1054 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; -use FuzeWorks\ConfigORM\ConfigORM; -use FuzeWorks\Exception\{SecurityException,Exception}; - -/** - * Security Class - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Security { - - /** - * List of sanitize filename strings - * - * @var array - */ - public $filename_bad_chars = array( - '../', '', '<', '>', - "'", '"', '&', '$', '#', - '{', '}', '[', ']', '=', - ';', '?', '%20', '%22', - '%3c', // < - '%253c', // < - '%3e', // > - '%0e', // > - '%28', // ( - '%29', // ) - '%2528', // ( - '%26', // & - '%24', // $ - '%3f', // ? - '%3b', // ; - '%3d' // = - ); - - /** - * Character set - * - * Will be overridden by the constructor. - * - * @var string - */ - public $charset = 'UTF-8'; - - /** - * XSS Hash - * - * Random Hash for protecting URLs. - * - * @var string - */ - protected $_xss_hash; - - /** - * CSRF Hash - * - * Random hash for Cross Site Request Forgery protection cookie - * - * @var string - */ - protected $_csrf_hash; - - /** - * CSRF Expire time - * - * Expiration time for Cross Site Request Forgery protection cookie. - * Defaults to two hours (in seconds). - * - * @var int - */ - protected $_csrf_expire = 7200; - - /** - * CSRF Token name - * - * Token name for Cross Site Request Forgery protection cookie. - * - * @var string - */ - protected $_csrf_token_name = 'fw_csrf_token'; - - /** - * CSRF Cookie name - * - * Cookie name for Cross Site Request Forgery protection cookie. - * - * @var string - */ - protected $_csrf_cookie_name = 'fw_csrf_cookie'; - - /** - * List of never allowed strings - * - * @var array - */ - protected $_never_allowed_str = array( - 'document.cookie' => '[removed]', - 'document.write' => '[removed]', - '.parentNode' => '[removed]', - '.innerHTML' => '[removed]', - '-moz-binding' => '[removed]', - '' => '-->', - ' '<![CDATA[', - '' => '<comment>' - ); - - /** - * List of never allowed regex replacements - * - * @var array - */ - protected $_never_allowed_regex = array( - 'javascript\s*:', - '(document|(document\.)?window)\.(location|on\w*)', - 'expression\s*(\(|&\#40;)', // CSS and IE - 'vbscript\s*:', // IE, surprise! - 'wscript\s*:', // IE - 'jscript\s*:', // IE - 'vbs\s*:', // IE - 'Redirect\s+30\d', - "([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?" - ); - - /** - * Config of this class - * - * @var ConfigORM - */ - private $config; - - /** - * Class constructor - * - * @return void - */ - public function __construct() - { - $this->config = Factory::getInstance()->config->get('security'); - - // Is CSRF protection enabled? - if ($this->config->csrf_protection) - { - // CSRF config - foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key) - { - if (NULL !== ($val = $this->config->$key)) - { - $this->{'_'.$key} = $val; - } - } - - // Append application specific cookie prefix - if ($cookie_prefix = Factory::getInstance()->config->get('main')->cookie_prefix) - { - $this->_csrf_cookie_name = $cookie_prefix.$this->_csrf_cookie_name; - } - - // Set the CSRF hash - $this->_csrf_set_hash(); - } - - $this->charset = strtoupper(Factory::getInstance()->config->get('main')->charset); - } - - // -------------------------------------------------------------------- - - /** - * CSRF Verify - * - * @return self - */ - public function csrf_verify(): self - { - // If it's not a POST request we will set the CSRF cookie - if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') - { - return $this->csrf_set_cookie(); - } - - // Check if URI has been whitelisted from CSRF checks - if ($exclude_uris = $this->config->csrf_exclude_uris) - { - foreach ($exclude_uris as $excluded) - { - if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), URI::uri_string())) - { - return $this; - } - } - } - - // Do the tokens exist in both the _POST and _COOKIE arrays? - if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) - OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match? - { - $this->csrf_show_error(); - } - - // We kill this since we're done and we don't want to polute the _POST array - unset($_POST[$this->_csrf_token_name]); - - // Regenerate on every submission? - if ($this->config->csrf_regenerate) - { - // Nothing should last forever - unset($_COOKIE[$this->_csrf_cookie_name]); - $this->_csrf_hash = NULL; - } - - $this->_csrf_set_hash(); - $this->csrf_set_cookie(); - - Logger::log('CSRF token verified'); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * CSRF Set Cookie - * - * @codeCoverageIgnore - * @return self - */ - public function csrf_set_cookie() - { - $expire = time() + $this->_csrf_expire; - $cfg = Factory::getInstance()->config->get('main'); - $secure_cookie = (bool) $cfg->cookie_secure; - - if ($secure_cookie && ! Core::isHttps()) - { - return $this; - } - - setcookie( - $this->_csrf_cookie_name, - $this->_csrf_hash, - $expire, - $cfg->cookie_path, - $cfg->cookie_domain, - $secure_cookie, - $cfg->cookie_httponly - ); - Logger::log('CSRF cookie sent'); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Show CSRF Error - * - * @return void - */ - public function csrf_show_error() - { - throw new SecurityException('The action you have requested is not allowed.', 1); - } - - // -------------------------------------------------------------------- - - /** - * Get CSRF Hash - * - * @see Security::$_csrf_hash - * @return string CSRF hash - */ - public function get_csrf_hash(): string - { - return $this->_csrf_hash; - } - - // -------------------------------------------------------------------- - - /** - * Get CSRF Token Name - * - * @see Security::$_csrf_token_name - * @return string CSRF token name - */ - public function get_csrf_token_name(): string - { - return $this->_csrf_token_name; - } - - // -------------------------------------------------------------------- - - /** - * XSS Clean - * - * Sanitizes data so that Cross Site Scripting Hacks can be - * prevented. This method does a fair amount of work but - * it is extremely thorough, designed to prevent even the - * most obscure XSS attempts. Nothing is ever 100% foolproof, - * of course, but I haven't been able to get anything passed - * the filter. - * - * Note: Should only be used to deal with data upon submission. - * It's not something that should be used for general - * runtime processing. - * - * @link http://channel.bitflux.ch/wiki/XSS_Prevention - * Based in part on some code and ideas from Bitflux. - * - * @link http://ha.ckers.org/xss.html - * To help develop this script I used this great list of - * vulnerabilities along with a few other hacks I've - * harvested from examining vulnerabilities in other programs. - * - * @param string|string[] $str Input data - * @param bool $is_image Whether the input is an image - * @return string|array - */ - public function xss_clean($str, $is_image = FALSE) - { - // Is the string an array? - if (is_array($str)) - { - while (list($key) = each($str)) - { - $str[$key] = $this->xss_clean($str[$key]); - } - - return $str; - } - - // Remove Invisible Characters - $str = UTF8::remove_invisible_characters($str); - - /* - * URL Decode - * - * Just in case stuff like this is submitted: - * - * Google - * - * Note: Use rawurldecode() so it does not remove plus signs - */ - do - { - $str = rawurldecode($str); - } - while (preg_match('/%[0-9a-f]{2,}/i', $str)); - - /* - * Convert character entities to ASCII - * - * This permits our tests below to work reliably. - * We only convert entities that are within tags since - * these are the ones that will pose security problems. - */ - $str = preg_replace_callback("/[^a-z0-9>]+[a-z0-9]+=([\'\"]).*?\\1/si", array('FuzeWorks\Security', '_convert_attribute'), $str); - $str = preg_replace_callback('/<\w+.*/si', array('FuzeWorks\Security', '_decode_entity'), $str); - - // Remove Invisible Characters Again! - $str = UTF8::remove_invisible_characters($str); - - /* - * Convert all tabs to spaces - * - * This prevents strings like this: ja vascript - * NOTE: we deal with spaces between characters later. - * NOTE: preg_replace was found to be amazingly slow here on - * large blocks of data, so we use str_replace. - */ - $str = str_replace("\t", ' ', $str); - - // Capture converted string for later comparison - $converted_string = $str; - - // Remove Strings that are never allowed - $str = $this->_do_never_allowed($str); - - /* - * Makes PHP tags safe - * - * Note: XML tags are inadvertently replaced too: - * - * '), array('<?', '?>'), $str); - } - - /* - * Compact any exploded words - * - * This corrects words like: j a v a s c r i p t - * These words are compacted back to their correct state. - */ - $words = array( - 'javascript', 'expression', 'vbscript', 'jscript', 'wscript', - 'vbs', 'script', 'base64', 'applet', 'alert', 'document', - 'write', 'cookie', 'window', 'confirm', 'prompt', 'eval' - ); - - foreach ($words as $word) - { - $word = implode('\s*', str_split($word)).'\s*'; - - // We only want to do this when it is followed by a non-word character - // That way valid stuff like "dealer to" does not become "dealerto" - $str = preg_replace_callback('#('.substr($word, 0, -3).')(\W)#is', array('FuzeWorks\Security', '_compact_exploded_words'), $str); - } - - /* - * Remove disallowed Javascript in links or img tags - * We used to do some version comparisons and use of stripos(), - * but it is dog slow compared to these simplified non-capturing - * preg_match(), especially if the pattern exists in the string - * - * Note: It was reported that not only space characters, but all in - * the following pattern can be parsed as separators between a tag name - * and its attributes: [\d\s"\'`;,\/\=\(\x00\x0B\x09\x0C] - * ... however, remove_invisible_characters() above already strips the - * hex-encoded ones, so we'll skip them below. - */ - do - { - $original = $str; - - if (preg_match('/]+([^>]*?)(?:>|$)#si', array('FuzeWorks\Security', '_js_link_removal'), $str); - } - - if (preg_match('/]*?)(?:\s?/?>|$)#si', array('FuzeWorks\Security', '_js_img_removal'), $str); - } - - if (preg_match('/script|xss/i', $str)) - { - $str = preg_replace('##si', '[removed]', $str); - } - } - while ($original !== $str); - unset($original); - - /* - * Sanitize naughty HTML elements - * - * If a tag containing any of the words in the list - * below is found, the tag gets converted to entities. - * - * So this: - * Becomes: <blink> - */ - $pattern = '#' - .'<((?/*\s*)(?[a-z0-9]+)(?=[^a-z0-9]|$)' // tag start and name, followed by a non-tag character - .'[^\s\042\047a-z0-9>/=]*' // a valid attribute character immediately after the tag would count as a separator - // optional attributes - .'(?(?:[\s\042\047/=]*' // non-attribute characters, excluding > (tag close) for obvious reasons - .'[^\s\042\047>/=]+' // attribute characters - // optional attribute-value - .'(?:\s*=' // attribute-value separator - .'(?:[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*))' // single, double or non-quoted value - .')?' // end optional attribute-value group - .')*)' // end optional attributes group - .'[^>]*)(?\>)?#isS'; - - // Note: It would be nice to optimize this for speed, BUT - // only matching the naughty elements here results in - // false positives and in turn - vulnerabilities! - do - { - $old_str = $str; - $str = preg_replace_callback($pattern, array('FuzeWorks\Security', '_sanitize_naughty_html'), $str); - } - while ($old_str !== $str); - unset($old_str); - - /* - * Sanitize naughty scripting elements - * - * Similar to above, only instead of looking for - * tags it looks for PHP and JavaScript commands - * that are disallowed. Rather than removing the - * code, it simply converts the parenthesis to entities - * rendering the code un-executable. - * - * For example: eval('some code') - * Becomes: eval('some code') - */ - $str = preg_replace( - '#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', - '\\1\\2(\\3)', - $str - ); - - // Final clean up - // This adds a bit of extra precaution in case - // something got through the above filters - $str = $this->_do_never_allowed($str); - - /* - * Images are Handled in a Special Way - * - Essentially, we want to know that after all of the character - * conversion is done whether any unwanted, likely XSS, code was found. - * If not, we return TRUE, as the image is clean. - * However, if the string post-conversion does not matched the - * string post-removal of XSS, then it fails, as there was unwanted XSS - * code found and removed/changed during processing. - */ - if ($is_image === TRUE) - { - return ($str === $converted_string); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * XSS Hash - * - * Generates the XSS hash if needed and returns it. - * - * @see Security::$_xss_hash - * @return string XSS hash - */ - public function xss_hash(): string - { - if ($this->_xss_hash === NULL) - { - $rand = $this->get_random_bytes(16); - $this->_xss_hash = ($rand === FALSE) - ? md5(uniqid(mt_rand(), TRUE)) - : bin2hex($rand); - } - - return $this->_xss_hash; - } - - // -------------------------------------------------------------------- - - /** - * Get random bytes - * - * @param int $length Output length - * @return string - */ - public function get_random_bytes($length): string - { - if (empty($length) OR ! ctype_digit((string) $length)) - { - return FALSE; - } - - if (function_exists('random_bytes')) - { - try - { - // The cast is required to avoid TypeError - return random_bytes((int) $length); - } - catch (Exception $e) - { - // If random_bytes() can't do the job, we can't either ... - // There's no point in using fallbacks. - Logger::logError($e->getMessage()); - return FALSE; - } - } - - // Unfortunately, none of the following PRNGs is guaranteed to exist ... - if (defined('MCRYPT_DEV_URANDOM') && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== FALSE) - { - return $output; - } - - - if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== FALSE) - { - // Try not to waste entropy ... - Core::isPHP('5.4') && stream_set_chunk_size($fp, $length); - $output = fread($fp, $length); - fclose($fp); - if ($output !== FALSE) - { - return $output; - } - } - - if (function_exists('openssl_random_pseudo_bytes')) - { - return openssl_random_pseudo_bytes($length); - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * HTML Entities Decode - * - * A replacement for html_entity_decode() - * - * The reason we are not using html_entity_decode() by itself is because - * while it is not technically correct to leave out the semicolon - * at the end of an entity most browsers will still interpret the entity - * correctly. html_entity_decode() does not convert entities without - * semicolons, so we are left with our own little solution here. Bummer. - * - * @link http://php.net/html-entity-decode - * - * @param string $str Input - * @param string $charset Character set - * @return string - */ - public function entity_decode($str, $charset = NULL): string - { - if (strpos($str, '&') === FALSE) - { - return $str; - } - - static $_entities; - - isset($charset) OR $charset = $this->charset; - $flag = Core::isPHP('5.4') - ? ENT_COMPAT | ENT_HTML5 - : ENT_COMPAT; - - do - { - $str_compare = $str; - - // Decode standard entities, avoiding false positives - if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) - { - if ( ! isset($_entities)) - { - $_entities = array_map( - 'strtolower', - Core::isPHP('5.3.4') - ? get_html_translation_table(HTML_ENTITIES, $flag, $charset) - : get_html_translation_table(HTML_ENTITIES, $flag) - ); - - // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 - // entities to the array manually - if ($flag === ENT_COMPAT) - { - $_entities[':'] = ':'; - $_entities['('] = '('; - $_entities[')'] = ')'; - $_entities["\n"] = '&newline;'; - $_entities["\t"] = '&tab;'; - } - } - - $replace = array(); - $matches = array_unique(array_map('strtolower', $matches[0])); - foreach ($matches as &$match) - { - if (($char = array_search($match.';', $_entities, TRUE)) !== FALSE) - { - $replace[$match] = $char; - } - } - - $str = str_ireplace(array_keys($replace), array_values($replace), $str); - } - - // Decode numeric & UTF16 two byte entities - $str = html_entity_decode( - preg_replace('/(&#(?:x0*[0-9a-f]{2,5}(?![0-9a-f;])|(?:0*\d{2,4}(?![0-9;]))))/iS', '$1;', $str), - $flag, - $charset - ); - } - while ($str_compare !== $str); - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Filename - * - * @param string $str Input file name - * @param bool $relative_path Whether to preserve paths - * @return string - */ - public function sanitize_filename($str, $relative_path = FALSE): string - { - $bad = $this->filename_bad_chars; - - if ( ! $relative_path) - { - $bad[] = './'; - $bad[] = '/'; - } - - $str = UTF8::remove_invisible_characters($str, FALSE); - - do - { - $old = $str; - $str = str_replace($bad, '', $str); - } - while ($old !== $str); - - return stripslashes($str); - } - - // ---------------------------------------------------------------- - - /** - * Strip Image Tags - * - * @param string $str - * @return string - */ - public function strip_image_tags($str): string - { - return preg_replace( - array( - '##i', - '#`]+)).*?\>#i' - ), - '\\2', - $str - ); - } - - // ---------------------------------------------------------------- - - /** - * Compact Exploded Words - * - * Callback method for xss_clean() to remove whitespace from - * things like 'j a v a s c r i p t'. - * - * @used-by Security::xss_clean() - * @param array $matches - * @return string - */ - protected function _compact_exploded_words($matches): string - { - return preg_replace('/\s+/s', '', $matches[1]).$matches[2]; - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Naughty HTML - * - * Callback method for xss_clean() to remove naughty HTML elements. - * - * @used-by Security::xss_clean() - * @param array $matches - * @return string - */ - protected function _sanitize_naughty_html($matches): string - { - static $naughty_tags = array( - 'alert', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound', - 'blink', 'body', 'embed', 'expression', 'form', 'frameset', 'frame', 'head', 'html', 'ilayer', - 'iframe', 'input', 'button', 'select', 'isindex', 'layer', 'link', 'meta', 'keygen', 'object', - 'plaintext', 'style', 'script', 'textarea', 'title', 'math', 'video', 'svg', 'xml', 'xss' - ); - - static $evil_attributes = array( - 'on\w+', 'style', 'xmlns', 'formaction', 'form', 'xlink:href', 'FSCommand', 'seekSegmentTime' - ); - - // First, escape unclosed tags - if (empty($matches['closeTag'])) - { - return '<'.$matches[1]; - } - // Is the element that we caught naughty? If so, escape it - elseif (in_array(strtolower($matches['tagName']), $naughty_tags, TRUE)) - { - return '<'.$matches[1].'>'; - } - // For other tags, see if their attributes are "evil" and strip those - elseif (isset($matches['attributes'])) - { - // We'll store the already fitlered attributes here - $attributes = array(); - - // Attribute-catching pattern - $attributes_pattern = '#' - .'(?[^\s\042\047>/=]+)' // attribute characters - // optional attribute-value - .'(?:\s*=(?[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*)))' // attribute-value separator - .'#i'; - - // Blacklist pattern for evil attribute names - $is_evil_pattern = '#^('.implode('|', $evil_attributes).')$#i'; - - // Each iteration filters a single attribute - do - { - // Strip any non-alpha characters that may preceed an attribute. - // Browsers often parse these incorrectly and that has been a - // of numerous XSS issues we've had. - $matches['attributes'] = preg_replace('#^[^a-z]+#i', '', $matches['attributes']); - - if ( ! preg_match($attributes_pattern, $matches['attributes'], $attribute, PREG_OFFSET_CAPTURE)) - { - // No (valid) attribute found? Discard everything else inside the tag - break; - } - - if ( - // Is it indeed an "evil" attribute? - preg_match($is_evil_pattern, $attribute['name'][0]) - // Or does it have an equals sign, but no value and not quoted? Strip that too! - OR (trim($attribute['value'][0]) === '') - ) - { - $attributes[] = 'xss=removed'; - } - else - { - $attributes[] = $attribute[0][0]; - } - - $matches['attributes'] = substr($matches['attributes'], $attribute[0][1] + strlen($attribute[0][0])); - } - while ($matches['attributes'] !== ''); - - $attributes = empty($attributes) - ? '' - : ' '.implode(' ', $attributes); - return '<'.$matches['slash'].$matches['tagName'].$attributes.'>'; - } - - return $matches[0]; - } - - // -------------------------------------------------------------------- - - /** - * JS Link Removal - * - * Callback method for xss_clean() to sanitize links. - * - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on link-heavy strings. - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _js_link_removal($match): string - { - return str_replace( - $match[1], - preg_replace( - '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) - ), - $match[0] - ); - } - - // -------------------------------------------------------------------- - - /** - * JS Image Removal - * - * Callback method for xss_clean() to sanitize image tags. - * - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on image tag heavy strings. - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _js_img_removal($match): string - { - return str_replace( - $match[1], - preg_replace( - '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) - ), - $match[0] - ); - } - - // -------------------------------------------------------------------- - - /** - * Attribute Conversion - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _convert_attribute($match): string - { - return str_replace(array('>', '<', '\\'), array('>', '<', '\\\\'), $match[0]); - } - - // -------------------------------------------------------------------- - - /** - * Filter Attributes - * - * Filters tag attributes for consistency and safety. - * - * @used-by Security::_js_img_removal() - * @used-by Security::_js_link_removal() - * @param string $str - * @return string - */ - protected function _filter_attributes($str): string - { - $out = ''; - if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches)) - { - foreach ($matches[0] as $match) - { - $out .= preg_replace('#/\*.*?\*/#s', '', $match); - } - } - - return $out; - } - - // -------------------------------------------------------------------- - - /** - * HTML Entity Decode Callback - * - * @used-by Security::xss_clean() - * @param array $match - * @return string - */ - protected function _decode_entity($match): string - { - // Protect GET variables in URLs - // 901119URL5918AMP18930PROTECT8198 - $match = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-/]+)|i', $this->xss_hash().'\\1=\\2', $match[0]); - - // Decode, then un-protect URL GET vars - return str_replace( - $this->xss_hash(), - '&', - $this->entity_decode($match, $this->charset) - ); - } - - // -------------------------------------------------------------------- - - /** - * Do Never Allowed - * - * @used-by Security::xss_clean() - * @param string - * @return string - */ - protected function _do_never_allowed($str): string - { - $str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str); - - foreach ($this->_never_allowed_regex as $regex) - { - $str = preg_replace('#'.$regex.'#is', '[removed]', $str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Set CSRF Hash and Cookie - * - * @return string - */ - protected function _csrf_set_hash(): string - { - if ($this->_csrf_hash === NULL) - { - // If the cookie exists we will use its value. - // We don't necessarily want to regenerate it with - // each page load since a page could contain embedded - // sub-pages causing this feature to fail - if (isset($_COOKIE[$this->_csrf_cookie_name]) && is_string($_COOKIE[$this->_csrf_cookie_name]) - && preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->_csrf_cookie_name]) === 1) - { - return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name]; - } - - $rand = $this->get_random_bytes(16); - $this->_csrf_hash = ($rand === FALSE) - ? md5(uniqid(mt_rand(), TRUE)) - : bin2hex($rand); - } - - return $this->_csrf_hash; - } - -} diff --git a/src/FuzeWorks/TemplateEngine/JsonEngine.php b/src/FuzeWorks/TemplateEngine/JsonEngine.php deleted file mode 100644 index 8424d0a..0000000 --- a/src/FuzeWorks/TemplateEngine/JsonEngine.php +++ /dev/null @@ -1,113 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -/** - * Template Engine that exports all assigned variables as JSON. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class JsonEngine implements TemplateEngine -{ - /** - * All the currently assigned variables. - * - * @var array - */ - protected $assigned_variables = array(); - - /** - * Whether the JSON data should be parsed or left as is. - * - * @var bool true if to be parsed - */ - protected static $string_return = true; - - /** - * Whether the JSON data should be parsed or left as is. - * - * @param true if to be parsed - */ - public static function returnAsString($boolean = true) - { - self::$string_return = $boolean; - } - - public function setDirectory($directory) - { - return true; - } - - public function get($file, $assigned_variables) - { - // First set all the variables - $this->assigned_variables = $assigned_variables; - - // First set up the JSON array - $json = array(); - - // Look up if a file is provided - if (!is_null($file)) { - // Retrieve a file - $string = file_get_contents($file); - $json = json_decode($string, true); - } - - // Then assign all variables - $json['data'] = $this->assigned_variables; - - // And return it - if (self::$string_return) { - return json_encode($json); - } - - return $json; - } - - public function getFileExtensions() - { - return array('json'); - } - - public function reset() - { - $this->assigned_variables = array(); - self::$string_return = true; - } - - public function test($param1, $param2, $param3) - { - return array($param1, $param2, $param3); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/LatteEngine.php b/src/FuzeWorks/TemplateEngine/LatteEngine.php deleted file mode 100644 index f224724..0000000 --- a/src/FuzeWorks/TemplateEngine/LatteEngine.php +++ /dev/null @@ -1,105 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -use FuzeWorks\Exception\LayoutException; -use FuzeWorks\Core; -use Latte\Engine as Latte; - -/** - * Wrapper for the Latte Engine from Nette Framework. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class LatteEngine implements TemplateEngine -{ - - /** - * Instance of the Latte Engine - * - * @var Latte\Engine The Latte Engine to be used - */ - protected $latte; - - /** - * Set the directory of the current template. - * - * @param string $directory Template Directory - */ - public function setDirectory($directory) - { - if (class_exists('\Latte\Engine', true)) - { - // If possible, load Latte\Engine - $this->latte = new Latte; - $this->latte->setTempDirectory(realpath(Core::$tempDir . DS . 'Latte')); - } - else - { - throw new LayoutException("Could not load LatteEngine. Is it installed or Composer not loaded?", 1); - } - } - - /** - * Handle and retrieve a template file. - * - * @param string $file Template File - * @param array $assigned_variables All the variables used in this layout - * - * @return string Output of the template - */ - public function get($file, $assigned_variables) - { - return $this->latte->renderToString($file, $assigned_variables); - } - - /** - * Retrieve the file extensions that this template engine uses. - * - * @return array All used extensions. eg: array('php') - */ - public function getFileExtensions() - { - return array('latte'); - } - - /** - * Reset the template engine to its default state, so it can be used again clean. - */ - public function reset() - { - // If possible, load Latte\Engine - $this->latte = null; - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/PHPEngine.php b/src/FuzeWorks/TemplateEngine/PHPEngine.php deleted file mode 100644 index 1fcc4a4..0000000 --- a/src/FuzeWorks/TemplateEngine/PHPEngine.php +++ /dev/null @@ -1,88 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -/** - * Simple Template Engine that allows for PHP templates. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class PHPEngine implements TemplateEngine -{ - /** - * The currently used directory by the template. - * - * @var string - */ - protected $directory; - - /** - * All the currently assigned variables. - * - * @var array - */ - protected $assigned_variables = array(); - - public function setDirectory($directory) - { - $this->directory = $directory; - } - - public function get($file, $assigned_variables) - { - // First set all the variables - $this->assigned_variables = $assigned_variables; - $vars = $this->assigned_variables; - $directory = $this->directory; - - // Then run the file - if (!is_null($file)) { - ob_start(); - include $file; - - return ob_get_clean(); - } - } - - public function getFileExtensions() - { - return array('php'); - } - - public function reset() - { - $this->directory = null; - $this->assigned_variables = array(); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/SmartyEngine.php b/src/FuzeWorks/TemplateEngine/SmartyEngine.php deleted file mode 100644 index 1709600..0000000 --- a/src/FuzeWorks/TemplateEngine/SmartyEngine.php +++ /dev/null @@ -1,166 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -use FuzeWorks\Core; -use Smarty; - -/** - * Wrapper for the Smarty Template Engine. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -class SmartyEngine implements TemplateEngine -{ - /** - * The currently used directory by the template. - * - * @var string - */ - protected $directory; - - /** - * All the currently assigned variables. - * - * @var array - */ - protected $assigned_variables = array(); - - /** - * Instance of the Smarty Template Engine. - * - * @var \Smarty - */ - protected $smartyInstance; - - public function setDirectory($directory) - { - $this->directory = $directory; - } - - public function get($file, $assigned_variables) - { - // First set all the variables - $this->assigned_variables = $assigned_variables; - - // Load Smarty - $this->loadSmarty(); - - // Set the directory - $this->smartyInstance->setTemplateDir($this->directory); - - // Then assign all variables - foreach ($this->assigned_variables as $key => $value) { - $this->smartyInstance->assign($key, $value); - } - - // And finally, load the template - return $this->smartyInstance->fetch($file); - } - - /** - * Loads a Smarty instance if it is not already loaded. - */ - private function loadSmarty() - { - if (is_null($this->smartyInstance)) { - $this->smartyInstance = new Smarty(); - - // Then prepare all variables - $this->smartyInstance->setCompileDir(Core::$tempDir . DS . 'Smarty' . DS . 'Compile'); - $this->smartyInstance->setCacheDir(Core::$tempDir . DS . 'Smarty'); - } - } - - public function getFileExtensions() - { - return array('tpl'); - } - - public function reset() - { - $this->smartyInstance = null; - $this->directory = null; - $this->assigned_variables = array(); - } - - /** - * Retrieve a value from Smarty. - * - * @param string $name Variable name - * - * @return mixed Variable Value - * - * @throws \FuzeWorks\LayoutException on error - */ - public function __get($name) - { - // First load Smarty - $this->loadSmarty(); - - return $this->smartyInstance->$name; - } - - /** - * Set a variable in Smarty. - * - * @param string $name Variable Name - * @param mixed $value Variable Value - * - * @throws \FuzeWorks\LayoutException on error - */ - public function __set($name, $value) - { - // First load Smarty - $this->loadSmarty(); - - $this->smartyInstance->$name = $value; - } - - /** - * Calls a function in Smarty. - * - * @param string $name Name of the function to be called - * @param Paramaters $params Parameters to be used - * - * @return mixed Function output - */ - public function __call($name, $params) - { - // First load Smarty - $this->loadSmarty(); - - return call_user_func_array(array($this->smartyInstance, $name), $params); - } -} \ No newline at end of file diff --git a/src/FuzeWorks/TemplateEngine/TemplateEngine.php b/src/FuzeWorks/TemplateEngine/TemplateEngine.php deleted file mode 100644 index 58e140e..0000000 --- a/src/FuzeWorks/TemplateEngine/TemplateEngine.php +++ /dev/null @@ -1,71 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\TemplateEngine; - -/** - * Interface that all Template Engines must follow. - * - * @author Abel Hoogeveen - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - */ -interface TemplateEngine -{ - /** - * Set the directory of the current template. - * - * @param string $directory Template Directory - */ - public function setDirectory($directory); - - /** - * Handle and retrieve a template file. - * - * @param string $file Template File - * @param array $assigned_variables All the variables used in this layout - * - * @return string Output of the template - */ - public function get($file, $assigned_variables); - - /** - * Retrieve the file extensions that this template engine uses. - * - * @return array All used extensions. eg: array('php') - */ - public function getFileExtensions(); - - /** - * Reset the template engine to its default state, so it can be used again clean. - */ - public function reset(); -} \ No newline at end of file diff --git a/src/FuzeWorks/URI.php b/src/FuzeWorks/URI.php deleted file mode 100644 index 13328d5..0000000 --- a/src/FuzeWorks/URI.php +++ /dev/null @@ -1,672 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.1.1 - */ - -namespace FuzeWorks; -use FuzeWorks\ConfigORM\ConfigORM; -use FuzeWorks\Exception\UriException; - -/** - * URI Class - * - * Parses URIs and determines routing - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class URI { - - /** - * List of cached URI segments - * - * @var array - */ - public $keyval = array(); - - /** - * Current URI string - * - * @var string - */ - public $uri_string = ''; - - /** - * List of URI segments - * - * Starts at 1 instead of 0. - * - * @var array - */ - public $segments = array(); - - /** - * List of routed URI segments - * - * Starts at 1 instead of 0. - * - * @var array - */ - public $rsegments = array(); - - /** - * Permitted URI chars - * - * PCRE character group allowed in URI segments - * - * @var string - */ - protected $_permitted_uri_chars; - - /** - * The configuration of this class - * - * @var ConfigORM - */ - private $config; - - /** - * Class constructor - * - * @return void - */ - public function __construct() - { - $this->config = Factory::getInstance()->config->get('routing'); - - // Determine the base_url - if (empty(Factory::getInstance()->config->get('main')->base_url)) - { - if (isset($_SERVER['SERVER_ADDR'])) - { - if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE) - { - $server_addr = '['.$_SERVER['SERVER_ADDR'].']'; - } - else - { - $server_addr = $_SERVER['SERVER_ADDR']; - } - - $base_url = (Core::isHttps() ? 'https' : 'http').'://'.$server_addr - .substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME']))); - } - else - { - $base_url = 'http://localhost/'; - } - - Factory::getInstance()->config->get('main')->base_url = $base_url; - } - - // If it's a CLI request, ignore the configuration - if (Core::isCli()) - { - $this->_set_uri_string($this->_parse_argv(), TRUE); - } - // If query strings are enabled, we don't need to parse any segments. - elseif ($this->config->enable_query_strings !== TRUE) - { - $this->_permitted_uri_chars = $this->config->permitted_uri_chars; - $protocol = $this->config->uri_protocol; - empty($protocol) && $protocol = 'REQUEST_URI'; - - switch ($protocol) - { - case 'AUTO': // For BC purposes only - case 'REQUEST_URI': - $uri = $this->_parse_request_uri(); - break; - case 'QUERY_STRING': - $uri = $this->_parse_query_string(); - break; - case 'PATH_INFO': - $uri = isset($_SERVER[$protocol]) - ? $_SERVER[$protocol] - : $this->_parse_request_uri(); - break; - } - - $this->_set_uri_string($uri, FALSE); - } - } - - // -------------------------------------------------------------------- - - /** - * Set URI String - * - * @param string $str - * @return void - */ - protected function _set_uri_string($str, $is_cli = FALSE) - { - if ($is_cli) - { - if (($this->uri_string = trim($str, '/')) === '') - { - return; - } - - $this->segments[0] = NULL; - foreach (explode('/', $this->uri_string) as $segment) - { - if (($segment = trim($segment)) !== '') - { - $this->segments[] = $segment; - } - } - - unset($this->segments[0]); - return; - } - - // Filter out control characters and trim slashes - $this->uri_string = trim(Utf8::remove_invisible_characters($str, FALSE), '/'); - - if ($this->uri_string === '') - { - return; - } - - // Remove the URL suffix, if present - if (($suffix = (string) $this->config->url_suffix) !== '') - { - $slen = strlen($suffix); - - if (substr($this->uri_string, -$slen) === $suffix) - { - $this->uri_string = substr($this->uri_string, 0, -$slen); - } - } - - $this->segments[0] = NULL; - foreach (explode('/', trim($this->uri_string, '/')) as $segment) - { - $segment = trim($segment); - // Filter segments for security - $this->filter_uri($segment); - - if ($segment !== '') - { - $this->segments[] = $segment; - } - } - - unset($this->segments[0]); - } - - // -------------------------------------------------------------------- - - /** - * Parse REQUEST_URI - * - * Will parse REQUEST_URI and automatically detect the URI from it, - * while fixing the query string if necessary. - * - * @return string - */ - protected function _parse_request_uri(): string - { - if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME'])) - { - return ''; - } - - // parse_url() returns false if no host is present, but the path or query string - // contains a colon followed by a number - $uri = parse_url('http://dummy'.$_SERVER['REQUEST_URI']); - $query = isset($uri['query']) ? $uri['query'] : ''; - $uri = isset($uri['path']) ? $uri['path'] : ''; - - if (isset($_SERVER['SCRIPT_NAME'][0])) - { - if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) - { - $uri = (string) substr($uri, strlen($_SERVER['SCRIPT_NAME'])); - } - elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) - { - $uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); - } - } - - // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct - // URI is found, and also fixes the QUERY_STRING server var and $_GET array. - if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0) - { - $query = explode('?', $query, 2); - $uri = $query[0]; - $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : ''; - } - else - { - $_SERVER['QUERY_STRING'] = $query; - } - - parse_str($_SERVER['QUERY_STRING'], $_GET); - - if ($uri === '/' OR $uri === '') - { - return '/'; - } - - // Do some final cleaning of the URI and return it - return $this->_remove_relative_directory($uri); - } - - // -------------------------------------------------------------------- - - /** - * Parse QUERY_STRING - * - * Will parse QUERY_STRING and automatically detect the URI from it. - * - * @return string - */ - protected function _parse_query_string(): string - { - $uri = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); - - if (trim($uri, '/') === '') - { - return ''; - } - elseif (strncmp($uri, '/', 1) === 0) - { - $uri = explode('?', $uri, 2); - $_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : ''; - $uri = $uri[0]; - } - - parse_str($_SERVER['QUERY_STRING'], $_GET); - - return $this->_remove_relative_directory($uri); - } - - // -------------------------------------------------------------------- - - /** - * Parse CLI arguments - * - * Take each command line argument and assume it is a URI segment. - * - * @return string - */ - protected function _parse_argv(): string - { - $args = array_slice($_SERVER['argv'], 1); - return $args ? implode('/', $args) : ''; - } - - // -------------------------------------------------------------------- - - /** - * Remove relative directory (../) and multi slashes (///) - * - * Do some final cleaning of the URI and return it, currently only used in $this->_parse_request_uri() - * - * @param string $uri - * @return string - */ - protected function _remove_relative_directory($uri): string - { - $uris = array(); - $tok = strtok($uri, '/'); - while ($tok !== FALSE) - { - if (( ! empty($tok) OR $tok === '0') && $tok !== '..') - { - $uris[] = $tok; - } - $tok = strtok('/'); - } - - return implode('/', $uris); - } - - // -------------------------------------------------------------------- - - /** - * Filter URI - * - * Filters segments for malicious characters. - * - * @param string $str - * @return bool - */ - public function filter_uri(&$str): bool - { - if ( ! empty($str) && ! empty($this->_permitted_uri_chars) && ! preg_match('/^['.$this->_permitted_uri_chars.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $str)) - { - throw new UriException('The URI you submitted has disallowed characters.', 1); - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Fetch URI Segment - * - * @see URI::$segments - * @param int $n Index - * @param mixed $no_result What to return if the segment index is not found - * @return mixed - */ - public function segment($n, $no_result = NULL) - { - return isset($this->segments[$n]) ? $this->segments[$n] : $no_result; - } - - // -------------------------------------------------------------------- - - /** - * Fetch URI "routed" Segment - * - * Returns the re-routed URI segment (assuming routing rules are used) - * based on the index provided. If there is no routing, will return - * the same result as URI::segment(). - * - * @see URI::$rsegments - * @see URI::segment() - * @param int $n Index - * @param mixed $no_result What to return if the segment index is not found - * @return mixed - */ - public function rsegment($n, $no_result = NULL) - { - return isset($this->rsegments[$n]) ? $this->rsegments[$n] : $no_result; - } - - // -------------------------------------------------------------------- - - /** - * URI to assoc - * - * Generates an associative array of URI data starting at the supplied - * segment index. For example, if this is your URI: - * - * example.com/user/search/name/joe/location/UK/gender/male - * - * You can use this method to generate an array with this prototype: - * - * array ( - * name => joe - * location => UK - * gender => male - * ) - * - * @param int $n Index (default: 3) - * @param array $default Default values - * @return array - */ - public function uri_to_assoc($n = 3, $default = array()): array - { - return $this->_uri_to_assoc($n, $default, 'segment'); - } - - // -------------------------------------------------------------------- - - /** - * Routed URI to assoc - * - * Identical to URI::uri_to_assoc(), only it uses the re-routed - * segment array. - * - * @see URI::uri_to_assoc() - * @param int $n Index (default: 3) - * @param array $default Default values - * @return array - */ - public function ruri_to_assoc($n = 3, $default = array()): array - { - return $this->_uri_to_assoc($n, $default, 'rsegment'); - } - - // -------------------------------------------------------------------- - - /** - * Internal URI-to-assoc - * - * Generates a key/value pair from the URI string or re-routed URI string. - * - * @used-by URI::uri_to_assoc() - * @used-by URI::ruri_to_assoc() - * @param int $n Index (default: 3) - * @param array $default Default values - * @param string $which Array name ('segment' or 'rsegment') - * @return array - */ - protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment'): array - { - if ( ! is_numeric($n)) - { - return $default; - } - - if (isset($this->keyval[$which], $this->keyval[$which][$n])) - { - return $this->keyval[$which][$n]; - } - - $total_segments = "total_{$which}s"; - $segment_array = "{$which}_array"; - - if ($this->$total_segments() < $n) - { - return (count($default) === 0) - ? array() - : array_fill_keys($default, NULL); - } - - $segments = array_slice($this->$segment_array(), ($n - 1)); - $i = 0; - $lastval = ''; - $retval = array(); - foreach ($segments as $seg) - { - if ($i % 2) - { - $retval[$lastval] = $seg; - } - else - { - $retval[$seg] = NULL; - $lastval = $seg; - } - - $i++; - } - - if (count($default) > 0) - { - foreach ($default as $val) - { - if ( ! array_key_exists($val, $retval)) - { - $retval[$val] = NULL; - } - } - } - - // Cache the array for reuse - isset($this->keyval[$which]) OR $this->keyval[$which] = array(); - $this->keyval[$which][$n] = $retval; - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Assoc to URI - * - * Generates a URI string from an associative array. - * - * @param array $array Input array of key/value pairs - * @return string URI string - */ - public function assoc_to_uri($array): string - { - $temp = array(); - foreach ((array) $array as $key => $val) - { - $temp[] = $key; - $temp[] = $val; - } - - return implode('/', $temp); - } - - // -------------------------------------------------------------------- - - /** - * Slash segment - * - * Fetches an URI segment with a slash. - * - * @param int $n Index - * @param string $where Where to add the slash ('trailing' or 'leading') - * @return string - */ - public function slash_segment($n, $where = 'trailing'): string - { - return $this->_slash_segment($n, $where, 'segment'); - } - - // -------------------------------------------------------------------- - - /** - * Slash routed segment - * - * Fetches an URI routed segment with a slash. - * - * @param int $n Index - * @param string $where Where to add the slash ('trailing' or 'leading') - * @return string - */ - public function slash_rsegment($n, $where = 'trailing'): string - { - return $this->_slash_segment($n, $where, 'rsegment'); - } - - // -------------------------------------------------------------------- - - /** - * Internal Slash segment - * - * Fetches an URI Segment and adds a slash to it. - * - * @used-by URI::slash_segment() - * @used-by URI::slash_rsegment() - * - * @param int $n Index - * @param string $where Where to add the slash ('trailing' or 'leading') - * @param string $which Array name ('segment' or 'rsegment') - * @return string - */ - protected function _slash_segment($n, $where = 'trailing', $which = 'segment'): string - { - $leading = $trailing = '/'; - - if ($where === 'trailing') - { - $leading = ''; - } - elseif ($where === 'leading') - { - $trailing = ''; - } - - return $leading.$this->$which($n).$trailing; - } - - // -------------------------------------------------------------------- - - /** - * Segment Array - * - * @return array URI::$segments - */ - public function segment_array(): array - { - return $this->segments; - } - - // -------------------------------------------------------------------- - - /** - * Routed Segment Array - * - * @return array URI::$rsegments - */ - public function rsegment_array(): array - { - return $this->rsegments; - } - - // -------------------------------------------------------------------- - - /** - * Total number of segments - * - * @return int - */ - public function total_segments(): int - { - return count($this->segments); - } - - // -------------------------------------------------------------------- - - /** - * Total number of routed segments - * - * @return int - */ - public function total_rsegments(): int - { - return count($this->rsegments); - } - - // -------------------------------------------------------------------- - - /** - * Fetch URI string - * - * @return string URI::$uri_string - */ - public function uri_string(): string - { - return $this->uri_string; - } -} diff --git a/src/FuzeWorks/Utf8.php b/src/FuzeWorks/Utf8.php deleted file mode 100644 index 91052f2..0000000 --- a/src/FuzeWorks/Utf8.php +++ /dev/null @@ -1,245 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks; - -/** - * Utf8 Class - * - * Provides support for UTF-8 environments - * - * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) - */ -class Utf8 { - - /** - * Class constructor - * - * Determines if UTF-8 support is to be enabled. - * - * @return void - */ - public function __construct() - { - $charset = strtoupper(Factory::getInstance()->config->get('main')->charset); - ini_set('default_charset', $charset); - - /* - * Configure mbstring and/or iconv if they are enabled - * and set MB_ENABLED and ICONV_ENABLED constants, so - * that we don't repeatedly do extension_loaded() or - * function_exists() calls. - */ - if (extension_loaded('mbstring')) - { - define('MB_ENABLED', TRUE); - // mbstring.internal_encoding is deprecated starting with PHP 5.6 - // and it's usage triggers E_DEPRECATED messages. - if (! Core::isPHP('5.6')) - { - @ini_set('mbstring.internal_encoding', $charset); - } - else - { - mb_internal_encoding($charset); - } - // This is required for mb_convert_encoding() to strip invalid characters. - // That's utilized by Utf8, but it's also done for consistency with iconv. - mb_substitute_character('none'); - } - else - { - define('MB_ENABLED', FALSE); - } - - // There's an ICONV_IMPL constant, but the PHP manual says that using - // iconv's predefined constants is "strongly discouraged". - if (extension_loaded('iconv')) - { - define('ICONV_ENABLED', TRUE); - // iconv.internal_encoding is deprecated starting with PHP 5.6 - // and it's usage triggers E_DEPRECATED messages. - if ( ! Core::isPHP(5.6) ) - { - @ini_set('iconv.internal_encoding', $charset); - } - else - { - ini_set('default_encoding', $charset); - } - } - else - { - define('ICONV_ENABLED', FALSE); - } - - if (Core::isPHP('5.6')) - { - ini_set('php.internal_encoding', $charset); - } - - if ( - defined('PREG_BAD_UTF8_ERROR') // PCRE must support UTF-8 - && (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) // iconv or mbstring must be installed - && strtoupper($charset) === 'UTF-8' // Application charset must be UTF-8 - ) - { - define('UTF8_ENABLED', TRUE); - Logger::log('UTF-8 Support Enabled'); - } - else - { - define('UTF8_ENABLED', FALSE); - Logger::log('UTF-8 Support Disabled'); - } - } - - // -------------------------------------------------------------------- - - /** - * Clean UTF-8 strings - * - * Ensures strings contain only valid UTF-8 characters. - * - * @param string $str String to clean - * @return string - */ - public function clean_string($str): string - { - if ($this->is_ascii($str) === FALSE) - { - if (MB_ENABLED) - { - $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); - } - elseif (ICONV_ENABLED) - { - $str = @iconv('UTF-8', 'UTF-8//IGNORE', $str); - } - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Remove ASCII control characters - * - * Removes all ASCII control characters except horizontal tabs, - * line feeds, and carriage returns, as all others can cause - * problems in XML. - * - * @param string $str String to clean - * @return string - */ - public function safe_ascii_for_xml($str): string - { - return $this->remove_invisible_characters($str, FALSE); - } - - // -------------------------------------------------------------------- - - /** - * Convert to UTF-8 - * - * Attempts to convert a string to UTF-8. - * - * @param string $str Input string - * @param string $encoding Input encoding - * @return string $str encoded in UTF-8 or FALSE on failure - */ - public function convert_to_utf8($str, $encoding): string - { - if (MB_ENABLED) - { - return mb_convert_encoding($str, 'UTF-8', $encoding); - } - elseif (ICONV_ENABLED) - { - return @iconv($encoding, 'UTF-8', $str); - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Is ASCII? - * - * Tests if a string is standard 7-bit ASCII or not. - * - * @param string $str String to check - * @return bool - */ - public function is_ascii($str): bool - { - return (preg_match('/[^\x00-\x7F]/S', $str) === 0); - } - - /** - * Remove Invisible Characters - * - * This prevents sandwiching null characters - * between ascii characters, like Java\0script. - * - * @param string - * @param bool - * @return string - */ - public static function remove_invisible_characters($str, $url_encoded = TRUE): string - { - $non_displayables = array(); - - // every control character except newline (dec 10), - // carriage return (dec 13) and horizontal tab (dec 09) - if ($url_encoded) - { - $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 - $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31 - } - - $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 - - do - { - $str = preg_replace($non_displayables, '', $str, -1, $count); - } - while ($count); - - return $str; - } - -} diff --git a/src/Helpers/array_helper.php b/src/Helpers/array_helper.php deleted file mode 100644 index c745543..0000000 --- a/src/Helpers/array_helper.php +++ /dev/null @@ -1,111 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks Array Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/array_helper.html - * @license http://opensource.org/licenses/MIT MIT License - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('element')) -{ - /** - * Element - * - * Lets you determine whether an array index is set and whether it has a value. - * If the element is empty it returns NULL (or whatever you specify as the default value.) - * - * @param string - * @param array - * @param mixed - * @return mixed depends on what the array contains - */ - function element($item, array $array, $default = NULL) - { - return array_key_exists($item, $array) ? $array[$item] : $default; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('random_element')) -{ - /** - * Random Element - Takes an array as input and returns a random element - * - * @param array - * @return mixed depends on what the array contains - */ - function random_element($array) - { - return is_array($array) ? $array[array_rand($array)] : $array; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('elements')) -{ - /** - * Elements - * - * Returns only the array items specified. Will return a default value if - * it is not set. - * - * @param array - * @param array - * @param mixed - * @return mixed depends on what the array contains - */ - function elements($items, array $array, $default = NULL) - { - $return = array(); - - is_array($items) OR $items = array($items); - - foreach ($items as $item) - { - $return[$item] = array_key_exists($item, $array) ? $array[$item] : $default; - } - - return $return; - } -} diff --git a/src/Helpers/common_helper.php b/src/Helpers/common_helper.php deleted file mode 100644 index 3af8f5f..0000000 --- a/src/Helpers/common_helper.php +++ /dev/null @@ -1,164 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Logger; - -/** - * FuzeWorks Common Functions - * - * Converted from CodeIgniter. - * - * Loads the base classes and executes the request. - * - * @package FuzeWorks - * @subpackage FuzeWorks - * @category Common Functions - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/ - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_php')) -{ - /** - * Determines if the current version of PHP is equal to or greater than the supplied value - * - * @param string - * @return bool TRUE if the current version is $version or higher - */ - function is_php($version) - { - static $_is_php; - $version = (string) $version; - - if ( ! isset($_is_php[$version])) - { - $_is_php[$version] = version_compare(PHP_VERSION, $version, '>='); - } - - return $_is_php[$version]; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('get_mimes')) -{ - /** - * Returns the MIME types array from config/mimes.php - * - * @return array - */ - function &get_mimes() - { - static $_mimes; - - if (empty($_mimes)) - { - $_mimes = FuzeWorks\Factory::getInstance()->config->get('mimes'); - } - - return $_mimes; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('html_escape')) -{ - /** - * Returns HTML escaped variable. - * - * @param mixed $var The input string or array of strings to be escaped. - * @param bool $double_encode $double_encode set to FALSE prevents escaping twice. - * @return mixed The escaped string or array of strings as a result. - */ - function html_escape($var, $double_encode = TRUE) - { - if (empty($var)) - { - return $var; - } - - if (is_array($var)) - { - foreach (array_keys($var) as $key) - { - $var[$key] = html_escape($var[$key], $double_encode); - } - - return $var; - } - - return htmlspecialchars($var, ENT_QUOTES, FuzeWorks\Factory::getInstance()->config->get('main')->charset, $double_encode); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('_stringify_attributes')) -{ - /** - * Stringify attributes for use in HTML tags. - * - * Helper function used to convert a string, array, or object - * of attributes to a string. - * - * @param mixed string, array, object - * @param bool - * @return string - */ - function _stringify_attributes($attributes, $js = FALSE) - { - $atts = NULL; - - if (empty($attributes)) - { - return $atts; - } - - if (is_string($attributes)) - { - return ' '.$attributes; - } - - $attributes = (array) $attributes; - - foreach ($attributes as $key => $val) - { - $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"'; - } - - return rtrim($atts, ','); - } -} \ No newline at end of file diff --git a/src/Helpers/download_helper.php b/src/Helpers/download_helper.php deleted file mode 100644 index 71b81f6..0000000 --- a/src/Helpers/download_helper.php +++ /dev/null @@ -1,155 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks Download Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/download_helper.html - */ - -// ------------------------------------------------------------------------ - -use FuzeWorks\Factory; - -if ( ! function_exists('force_download')) -{ - /** - * Force Download - * - * Generates headers that force a download to happen - * - * @param string filename - * @param mixed the data to be downloaded - * @param bool whether to try and send the actual file MIME type - * @return void - */ - function force_download($filename = '', $data = '', $set_mime = FALSE) - { - if ($filename === '' OR $data === '') - { - return; - } - elseif ($data === NULL) - { - if ( ! @is_file($filename) OR ($filesize = @filesize($filename)) === FALSE) - { - return; - } - - $filepath = $filename; - $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename)); - $filename = end($filename); - } - else - { - $filesize = strlen($data); - } - - // Set the default MIME type to send - $mime = 'application/octet-stream'; - - $x = explode('.', $filename); - $extension = end($x); - - if ($set_mime === TRUE) - { - if (count($x) === 1 OR $extension === '') - { - /* If we're going to detect the MIME type, - * we'll need a file extension. - */ - return; - } - - // Load the mime types - $mimes = Factory::getInstance()->config->get('mimes')->toArray(); - - // Only change the default MIME if we can find one - if (isset($mimes[$extension])) - { - $mime = is_array($mimes[$extension]) ? $mimes[$extension][0] : $mimes[$extension]; - } - } - - /* It was reported that browsers on Android 2.1 (and possibly older as well) - * need to have the filename extension upper-cased in order to be able to - * download it. - * - * Reference: http://digiblog.de/2011/04/19/android-and-the-download-file-headers/ - */ - if (count($x) !== 1 && isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/Android\s(1|2\.[01])/', $_SERVER['HTTP_USER_AGENT'])) - { - $x[count($x) - 1] = strtoupper($extension); - $filename = implode('.', $x); - } - - if ($data === NULL && ($fp = @fopen($filepath, 'rb')) === FALSE) - { - return; - } - - // Clean output buffer - if (ob_get_level() !== 0 && @ob_end_clean() === FALSE) - { - @ob_clean(); - } - - // Generate the server headers - header('Content-Type: '.$mime); - header('Content-Disposition: attachment; filename="'.$filename.'"'); - header('Expires: 0'); - header('Content-Transfer-Encoding: binary'); - header('Content-Length: '.$filesize); - header('Cache-Control: private, no-transform, no-store, must-revalidate'); - - // If we have raw data - just dump it - if ($data !== NULL) - { - exit($data); - } - - // Flush 1MB chunks of data - while ( ! feof($fp) && ($data = fread($fp, 1048576)) !== FALSE) - { - echo $data; - } - - fclose($fp); - exit; - } -} diff --git a/src/Helpers/file_helper.php b/src/Helpers/file_helper.php deleted file mode 100644 index 36fd0bd..0000000 --- a/src/Helpers/file_helper.php +++ /dev/null @@ -1,497 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks File Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/file_helper.html - * @license http://opensource.org/licenses/MIT MIT License - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('read_file')) -{ - /** - * Read File - * - * Opens the file specified in the path and returns it as a string. - * - * @todo Remove in version 3.1+. - * @deprecated 3.0.0 It is now just an alias for PHP's native file_get_contents(). - * @param string $file Path to file - * @return string File contents - */ - function read_file($file) - { - return @file_get_contents($file); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('write_file')) -{ - /** - * Write File - * - * Writes data to the file specified in the path. - * Creates a new file if non-existent. - * - * @param string $path File path - * @param string $data Data to write - * @param string $mode fopen() mode (default: 'wb') - * @return bool - */ - function write_file($path, $data, $mode = 'wb') - { - if ( ! $fp = @fopen($path, $mode)) - { - return FALSE; - } - - flock($fp, LOCK_EX); - - for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result) - { - if (($result = fwrite($fp, substr($data, $written))) === FALSE) - { - break; - } - } - - flock($fp, LOCK_UN); - fclose($fp); - - return is_int($result); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('delete_files')) -{ - /** - * Delete Files - * - * Deletes all files contained in the supplied directory path. - * Files must be writable or owned by the system in order to be deleted. - * If the second parameter is set to TRUE, any directories contained - * within the supplied base directory will be nuked as well. - * - * @param string $path File path - * @param bool $del_dir Whether to delete any directories found in the path - * @param bool $htdocs Whether to skip deleting .htaccess and index page files - * @param int $_level Current directory depth level (default: 0; internal use only) - * @return bool - */ - function delete_files($path, $del_dir = FALSE, $htdocs = FALSE, $_level = 0) - { - // Trim the trailing slash - $path = rtrim($path, '/\\'); - - if ( ! $current_dir = @opendir($path)) - { - return FALSE; - } - - while (FALSE !== ($filename = @readdir($current_dir))) - { - if ($filename !== '.' && $filename !== '..') - { - if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.') - { - delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $htdocs, $_level + 1); - } - elseif ($htdocs !== TRUE OR ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) - { - @unlink($path.DIRECTORY_SEPARATOR.$filename); - } - } - } - - closedir($current_dir); - - return ($del_dir === TRUE && $_level > 0) - ? @rmdir($path) - : TRUE; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('get_filenames')) -{ - /** - * Get Filenames - * - * Reads the specified directory and builds an array containing the filenames. - * Any sub-folders contained within the specified path are read as well. - * - * @param string path to source - * @param bool whether to include the path as part of the filename - * @param bool internal variable to determine recursion status - do not use in calls - * @return array - */ - function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE) - { - static $_filedata = array(); - - if ($fp = @opendir($source_dir)) - { - // reset the array and make sure $source_dir has a trailing slash on the initial call - if ($_recursion === FALSE) - { - $_filedata = array(); - $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; - } - - while (FALSE !== ($file = readdir($fp))) - { - if (is_dir($source_dir.$file) && $file[0] !== '.') - { - get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE); - } - elseif ($file[0] !== '.') - { - $_filedata[] = ($include_path === TRUE) ? $source_dir.$file : $file; - } - } - - closedir($fp); - return $_filedata; - } - - return FALSE; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('get_dir_file_info')) -{ - /** - * Get Directory File Information - * - * Reads the specified directory and builds an array containing the filenames, - * filesize, dates, and permissions - * - * Any sub-folders contained within the specified path are read as well. - * - * @param string path to source - * @param bool Look only at the top level directory specified? - * @param bool internal variable to determine recursion status - do not use in calls - * @return array - */ - function get_dir_file_info($source_dir, $top_level_only = TRUE, $_recursion = FALSE) - { - static $_filedata = array(); - $relative_path = $source_dir; - - if ($fp = @opendir($source_dir)) - { - // reset the array and make sure $source_dir has a trailing slash on the initial call - if ($_recursion === FALSE) - { - $_filedata = array(); - $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; - } - - // Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast - while (FALSE !== ($file = readdir($fp))) - { - if (is_dir($source_dir.$file) && $file[0] !== '.' && $top_level_only === FALSE) - { - get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, TRUE); - } - elseif ($file[0] !== '.') - { - $_filedata[$file] = get_file_info($source_dir.$file); - $_filedata[$file]['relative_path'] = $relative_path; - } - } - - closedir($fp); - return $_filedata; - } - - return FALSE; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('get_file_info')) -{ - /** - * Get File Info - * - * Given a file and path, returns the name, path, size, date modified - * Second parameter allows you to explicitly declare what information you want returned - * Options are: name, server_path, size, date, readable, writable, executable, fileperms - * Returns FALSE if the file cannot be found. - * - * @param string path to file - * @param mixed array or comma separated string of information returned - * @return array - */ - function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date')) - { - if ( ! file_exists($file)) - { - return FALSE; - } - - if (is_string($returned_values)) - { - $returned_values = explode(',', $returned_values); - } - - foreach ($returned_values as $key) - { - switch ($key) - { - case 'name': - $fileinfo['name'] = basename($file); - break; - case 'server_path': - $fileinfo['server_path'] = $file; - break; - case 'size': - $fileinfo['size'] = filesize($file); - break; - case 'date': - $fileinfo['date'] = filemtime($file); - break; - case 'readable': - $fileinfo['readable'] = is_readable($file); - break; - case 'writable': - $fileinfo['writable'] = is_really_writable($file); - break; - case 'executable': - $fileinfo['executable'] = is_executable($file); - break; - case 'fileperms': - $fileinfo['fileperms'] = fileperms($file); - break; - } - } - - return $fileinfo; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('get_mime_by_extension')) -{ - /** - * Get Mime by Extension - * - * Translates a file extension into a mime type based on config/mimes.php. - * Returns FALSE if it can't determine the type, or open the mime config file - * - * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience - * It should NOT be trusted, and should certainly NOT be used for security - * - * @param string $filename File name - * @return string - */ - function get_mime_by_extension($filename) - { - static $mimes; - - if ( ! is_array($mimes)) - { - $factory = FuzeWorks\Factory::getInstance(); - $mimes = $factory->config->get('mimes')->toArray(); - - if (empty($mimes)) - { - return FALSE; - } - } - - $extension = strtolower(substr(strrchr($filename, '.'), 1)); - - if (isset($mimes[$extension])) - { - return is_array($mimes[$extension]) - ? current($mimes[$extension]) // Multiple mime types, just give the first one - : $mimes[$extension]; - } - - return FALSE; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('symbolic_permissions')) -{ - /** - * Symbolic Permissions - * - * Takes a numeric value representing a file's permissions and returns - * standard symbolic notation representing that value - * - * @param int $perms Permissions - * @return string - */ - function symbolic_permissions($perms) - { - if (($perms & 0xC000) === 0xC000) - { - $symbolic = 's'; // Socket - } - elseif (($perms & 0xA000) === 0xA000) - { - $symbolic = 'l'; // Symbolic Link - } - elseif (($perms & 0x8000) === 0x8000) - { - $symbolic = '-'; // Regular - } - elseif (($perms & 0x6000) === 0x6000) - { - $symbolic = 'b'; // Block special - } - elseif (($perms & 0x4000) === 0x4000) - { - $symbolic = 'd'; // Directory - } - elseif (($perms & 0x2000) === 0x2000) - { - $symbolic = 'c'; // Character special - } - elseif (($perms & 0x1000) === 0x1000) - { - $symbolic = 'p'; // FIFO pipe - } - else - { - $symbolic = 'u'; // Unknown - } - - // Owner - $symbolic .= (($perms & 0x0100) ? 'r' : '-') - .(($perms & 0x0080) ? 'w' : '-') - .(($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); - - // Group - $symbolic .= (($perms & 0x0020) ? 'r' : '-') - .(($perms & 0x0010) ? 'w' : '-') - .(($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); - - // World - $symbolic .= (($perms & 0x0004) ? 'r' : '-') - .(($perms & 0x0002) ? 'w' : '-') - .(($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); - - return $symbolic; - } -} - -// -------------------------------------------------------------------- - -if ( ! function_exists('octal_permissions')) -{ - /** - * Octal Permissions - * - * Takes a numeric value representing a file's permissions and returns - * a three character string representing the file's octal permissions - * - * @param int $perms Permissions - * @return string - */ - function octal_permissions($perms) - { - return substr(sprintf('%o', $perms), -3); - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('is_really_writable')) -{ - /** - * Tests for file writability - * - * is_writable() returns TRUE on Windows servers when you really can't write to - * the file, based on the read-only attribute. is_writable() is also unreliable - * on Unix servers if safe_mode is on. - * - * @link https://bugs.php.net/bug.php?id=54709 - * @param string - * @return bool - */ - function is_really_writable($file) - { - // If we're on a Unix server with safe_mode off we call is_writable - if (DIRECTORY_SEPARATOR === '/' && (FuzeWorks\Core::isPHP('5.4') OR ! ini_get('safe_mode'))) - { - return is_writable($file); - } - - /* For Windows servers and safe_mode "on" installations we'll actually - * write a file then read it. Bah... - */ - if (is_dir($file)) - { - $file = rtrim($file, '/').'/'.md5(mt_rand()); - if (($fp = @fopen($file, 'ab')) === FALSE) - { - return FALSE; - } - - fclose($fp); - @chmod($file, 0777); - @unlink($file); - return TRUE; - } - elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE) - { - return FALSE; - } - - fclose($fp); - return TRUE; - } -} \ No newline at end of file diff --git a/src/Helpers/xml_helper.php b/src/Helpers/xml_helper.php deleted file mode 100644 index d7a5340..0000000 --- a/src/Helpers/xml_helper.php +++ /dev/null @@ -1,86 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -/** - * FuzeWorks XML Helpers - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Helpers - * @category Helpers - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/xml_helper.html - * @license http://opensource.org/licenses/MIT MIT License - */ - -// ------------------------------------------------------------------------ - -if ( ! function_exists('xml_convert')) -{ - /** - * Convert Reserved XML characters to Entities - * - * @param string - * @param bool - * @return string - */ - function xml_convert($str, $protect_all = FALSE) - { - $temp = '__TEMP_AMPERSANDS__'; - - // Replace entities to temporary markers so that - // ampersands won't get messed up - $str = preg_replace('/&#(\d+);/', $temp.'\\1;', $str); - - if ($protect_all === TRUE) - { - $str = preg_replace('/&(\w+);/', $temp.'\\1;', $str); - } - - $str = str_replace( - array('&', '<', '>', '"', "'", '-'), - array('&', '<', '>', '"', ''', '-'), - $str - ); - - // Decode the temp markers back to entities - $str = preg_replace('/'.$temp.'(\d+);/', '&#\\1;', $str); - - if ($protect_all === TRUE) - { - return preg_replace('/'.$temp.'(\w+);/', '&\\1;', $str); - } - - return $str; - } -} diff --git a/src/Language/english/db_lang.php b/src/Language/english/db_lang.php deleted file mode 100644 index c1a6e99..0000000 --- a/src/Language/english/db_lang.php +++ /dev/null @@ -1,60 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -return array( - - 'db_invalid_connection_str' => 'Unable to determine the database settings based on the connection string you submitted.', - 'db_unable_to_connect' => 'Unable to connect to your database server using the provided settings.', - 'db_unable_to_select' => 'Unable to select the specified database: %s', - 'db_unable_to_create' => 'Unable to create the specified database: %s', - 'db_invalid_query' => 'The query you submitted is not valid.', - 'db_must_set_table' => 'You must set the database table to be used with your query.', - 'db_must_use_set' => 'You must use the "set" method to update an entry.', - 'db_must_use_index' => 'You must specify an index to match on for batch updates.', - 'db_batch_missing_index' => 'One or more rows submitted for batch updating is missing the specified index.', - 'db_must_use_where' => 'Updates are not allowed unless they contain a "where" clause.', - 'db_del_must_use_where' => 'Deletes are not allowed unless they contain a "where" or "like" clause.', - 'db_field_param_missing' => 'To fetch fields requires the name of the table as a parameter.', - 'db_unsupported_function' => 'This feature is not available for the database you are using.', - 'db_transaction_failure' => 'Transaction failure: Rollback performed.', - 'db_unable_to_drop' => 'Unable to drop the specified database.', - 'db_unsupported_feature' => 'Unsupported feature of the database platform you are using.', - 'db_unsupported_compression' => 'The file compression format you chose is not supported by your server.', - 'db_filepath_error' => 'Unable to write data to the file path you have submitted.', - 'db_invalid_cache_path' => 'The cache path you submitted is not valid or writable.', - 'db_table_name_required' => 'A table name is required for that operation.', - 'db_column_name_required' => 'A column name is required for that operation.', - 'db_column_definition_required' => 'A column definition is required for that operation.', - 'db_unable_to_set_charset' => 'Unable to set client connection character set: %s', - 'db_error_heading' => 'A Database Error Occurred', - -); \ No newline at end of file diff --git a/src/Language/english/email_lang.php b/src/Language/english/email_lang.php deleted file mode 100644 index c722c4f..0000000 --- a/src/Language/english/email_lang.php +++ /dev/null @@ -1,55 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -return array ( - - 'email_must_be_array' => 'The email validation method must be passed an array.', - 'email_invalid_address' => 'Invalid email address: %s', - 'email_attachment_missing' => 'Unable to locate the following email attachment: %s', - 'email_attachment_unreadable' => 'Unable to open this attachment: %s', - 'email_no_from' => 'Cannot send mail with no "From" header.', - 'email_no_recipients' => 'You must include recipients: To, Cc, or Bcc', - 'email_send_failure_phpmail' => 'Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.', - 'email_send_failure_sendmail' => 'Unable to send email using PHP Sendmail. Your server might not be configured to send mail using this method.', - 'email_send_failure_smtp' => 'Unable to send email using PHP SMTP. Your server might not be configured to send mail using this method.', - 'email_sent' => 'Your message has been successfully sent using the following protocol: %s', - 'email_no_socket' => 'Unable to open a socket to Sendmail. Please check settings.', - 'email_no_hostname' => 'You did not specify a SMTP hostname.', - 'email_smtp_error' => 'The following SMTP error was encountered: %s', - 'email_no_smtp_unpw' => 'Error: You must assign a SMTP username and password.', - 'email_failed_smtp_login' => 'Failed to send AUTH LOGIN command. Error: %s', - 'email_smtp_auth_un' => 'Failed to authenticate username. Error: %s', - 'email_smtp_auth_pw' => 'Failed to authenticate password. Error: %s', - 'email_smtp_data_failure' => 'Unable to send data: %s', - 'email_exit_status' => 'Exit status code: %s' - -); diff --git a/src/Layout/layout.tracydatabasepanel.php b/src/Layout/layout.tracydatabasepanel.php deleted file mode 100644 index a263cd5..0000000 --- a/src/Layout/layout.tracydatabasepanel.php +++ /dev/null @@ -1,51 +0,0 @@ - - -

Queries:

- -
- - $queries): ?> - - - - - - - - - - - - - - -
Database:#
Time msSQL QueryRows
- - ERROR -
explain - -
- - - - - - - - - - -
CodeMessage
- -
-

...and more

- -
diff --git a/src/Layout/layout.tracydatabasetab.php b/src/Layout/layout.tracydatabasetab.php deleted file mode 100644 index 3a107cc..0000000 --- a/src/Layout/layout.tracydatabasetab.php +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Libraries/Cache/Cache.php b/src/Libraries/Cache/Cache.php deleted file mode 100644 index 58460b1..0000000 --- a/src/Libraries/Cache/Cache.php +++ /dev/null @@ -1,257 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.1.5 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Logger; - -/** - * FuzeWorks Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache extends FW_Driver_Library { - - /** - * Valid cache drivers - * - * @var array - */ - protected $valid_drivers = array( - 'array', - 'apc', - 'dummy', - 'file', - 'memcached', - 'redis', - 'wincache' - ); - - /** - * Path of cache files (if file-based cache) - * - * @var string - */ - protected $_cache_path = NULL; - - /** - * Reference to the driver - * - * @var mixed - */ - protected $_adapter = 'dummy'; - - /** - * Fallback driver - * - * @var string - */ - protected $_backup_driver = 'dummy'; - - /** - * Cache key prefix - * - * @var string - */ - public $key_prefix = ''; - - /** - * Constructor - * - * Initialize class properties based on the configuration array. - * - * @param array $config = array() - * @return void - */ - public function __construct($config = array()) - { - require_once('Cache_Interface.php'); - - isset($config['adapter']) && $this->_adapter = $config['adapter']; - isset($config['backup']) && $this->_backup_driver = $config['backup']; - isset($config['key_prefix']) && $this->key_prefix = $config['key_prefix']; - - // If the specified adapter isn't available, check the backup. - if ( ! $this->is_supported($this->_adapter)) - { - if ( ! $this->is_supported($this->_backup_driver)) - { - // Backup isn't supported either. Default to 'Dummy' driver. - Logger::logError('Cache adapter "'.$this->_adapter.'" and backup "'.$this->_backup_driver.'" are both unavailable. Cache is now using "Dummy" adapter.'); - $this->_adapter = 'dummy'; - } - else - { - // Backup is supported. Set it to primary. - Logger::logDebug('Cache adapter "'.$this->_adapter.'" is unavailable. Falling back to "'.$this->_backup_driver.'" backup adapter.'); - $this->_adapter = $this->_backup_driver; - } - } - } - - // ------------------------------------------------------------------------ - - /** - * Get - * - * Look for a value in the cache. If it exists, return the data - * if not, return FALSE - * - * @param string $id - * @return mixed value matching $id or FALSE on failure - */ - public function get($id) - { - return $this->{$this->_adapter}->get($this->key_prefix.$id); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttl Cache TTL (in seconds) - * @param bool $raw Whether to store the raw value - * @return bool TRUE on success, FALSE on failure - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - return $this->{$this->_adapter}->set($this->key_prefix.$id, $data, $ttl, $raw); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param string $id Cache ID - * @return bool TRUE on success, FALSE on failure - */ - public function remove($id) - { - return $this->{$this->_adapter}->remove($this->key_prefix.$id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return $this->{$this->_adapter}->increment($this->key_prefix.$id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return $this->{$this->_adapter}->decrement($this->key_prefix.$id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool TRUE on success, FALSE on failure - */ - public function clean() - { - return $this->{$this->_adapter}->clean(); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @param string $type = 'user' user/filehits - * @return mixed array containing cache info on success OR FALSE on failure - */ - public function cache_info($type = 'user') - { - return $this->{$this->_adapter}->cache_info($type); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param string $id key to get cache metadata on - * @return mixed cache item metadata - */ - public function get_metadata($id) - { - return $this->{$this->_adapter}->get_metadata($this->key_prefix.$id); - } - - // ------------------------------------------------------------------------ - - /** - * Is the requested driver supported in this environment? - * - * @param string $driver The driver to test - * @return array - */ - public function is_supported($driver) - { - static $support; - - if ( ! isset($support, $support[$driver])) - { - $support[$driver] = $this->{$driver}->is_supported(); - } - - return $support[$driver]; - } -} diff --git a/src/Libraries/Cache/Cache_Interface.php b/src/Libraries/Cache/Cache_Interface.php deleted file mode 100644 index d031fa4..0000000 --- a/src/Libraries/Cache/Cache_Interface.php +++ /dev/null @@ -1,109 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.5 - * - * @version Version 1.1.5 - */ - -namespace FuzeWorks\Library; - -interface CacheInterface -{ - - /** - * Retrieve an item from the cache, resolves with its value on - * success or null when no item can be found. - * - * @param string $key - * @return mixed - */ - public function get($key); - /** - * Store an item in the cache. - * - * @param string $key - * @param mixed $value - * @return void - */ - public function set($key, $value, $ttl = 60, $raw = FALSE); - /** - * Remove an item from the cache. - * - * @param string $key - * @return void - */ - public function remove($key); - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1); - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1); - - /** - * Clean the cache - * - * @return bool TRUE on success, FALSE on failure - */ - public function clean(); - - /** - * Cache Info - * - * @param string $type = 'user' user/filehits - * @return mixed array containing cache info on success OR FALSE on failure - */ - public function cache_info($type = 'user'); - - /** - * Get Cache Metadata - * - * @param string $id key to get cache metadata on - * @return mixed cache item metadata - */ - public function get_metadata($id); - - /** - * Is the requested driver supported in this environment? - * - * @return array - */ - public function is_supported(); -} diff --git a/src/Libraries/Cache/drivers/Cache_apc.php b/src/Libraries/Cache/drivers/Cache_apc.php deleted file mode 100644 index afb926d..0000000 --- a/src/Libraries/Cache/drivers/Cache_apc.php +++ /dev/null @@ -1,220 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Logger; - -/** - * FuzeWorks APC Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_apc extends FW_Driver implements CacheInterface { - - /** - * Class constructor - * - * Only present so that an error message is logged - * if APC is not available. - * - * @return void - */ - public function __construct() - { - if ( ! $this->is_supported()) - { - Logger::logError('Cache: Failed to initialize APC; extension not loaded/enabled?'); - } - } - - // ------------------------------------------------------------------------ - - /** - * Get - * - * Look for a value in the cache. If it exists, return the data - * if not, return FALSE - * - * @param string - * @return mixed value that is stored/FALSE on failure - */ - public function get($id) - { - $success = FALSE; - $data = apc_fetch($id, $success); - - if ($success === TRUE) - { - return is_array($data) - ? unserialize($data[0]) - : $data; - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttol Length of time (in seconds) to cache the data - * @param bool $raw Whether to store the raw value - * @return bool TRUE on success, FALSE on failure - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - $ttl = (int) $ttl; - - return apc_store( - $id, - ($raw === TRUE ? $data : array(serialize($data), time(), $ttl)), - $ttl - ); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of the item in the cache - * @return bool true on success/false on failure - */ - public function remove($id) - { - return apc_delete($id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return apc_inc($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return apc_dec($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return apc_clear_cache('user'); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @param string user/filehits - * @return mixed array on success, false on failure - */ - public function cache_info($type = NULL) - { - return apc_cache_info($type); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return mixed array on success/false on failure - */ - public function get_metadata($id) - { - $success = FALSE; - $stored = apc_fetch($id, $success); - - if ($success === FALSE OR count($stored) !== 3) - { - return FALSE; - } - - list($data, $time, $ttl) = $stored; - - return array( - 'expire' => $time + $ttl, - 'mtime' => $time, - 'data' => unserialize($data) - ); - } - - // ------------------------------------------------------------------------ - - /** - * is_supported() - * - * Check to see if APC is available on this system, bail if it isn't. - * - * @return bool - */ - public function is_supported() - { - return (extension_loaded('apc') && ini_get('apc.enabled')); - } -} diff --git a/src/Libraries/Cache/drivers/Cache_array.php b/src/Libraries/Cache/drivers/Cache_array.php deleted file mode 100644 index 0383a82..0000000 --- a/src/Libraries/Cache/drivers/Cache_array.php +++ /dev/null @@ -1,182 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.5 - * - * @version Version 1.1.5 - */ - -namespace FuzeWorks\Library; - -/** - * FuzeWorks Array Caching Class - * - * @author TechFuze - */ -class FW_Cache_array extends FW_Driver implements CacheInterface -{ - - private $data = array(); - - /** - * Cache Get - * - * Since this is the dummy class, it's always going to return FALSE. - * - * @param string - * @return bool FALSE - */ - public function get($id) - { - if (isset($this->data[$id])) - { - $expire = $this->data[$id]['expire']; - if (date('U') > $expire ) - { - unset($this->data[$id]); - } - - return $this->data[$id]['data']; - } - - return false; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string Unique Key - * @param mixed Data to store - * @param int Length of time (in seconds) to cache the data - * @param bool Whether to store the raw value - * @return bool TRUE, Simulating success - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - $this->data[$id] = array('data' => $data, 'expire' => date('U') + $ttl); - return true; - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of the item in the cache - * @return bool TRUE, simulating success - */ - public function remove($id) - { - if (isset($this->data[$id])) - unset($this->data[$id]); - - return false; - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool TRUE, simulating success - */ - public function clean() - { - $this->data = array(); - return true; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @param string user/filehits - * @return bool FALSE - */ - public function cache_info($type = NULL) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return bool FALSE - */ - public function get_metadata($id) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Is this caching driver supported on the system? - * Of course this one is. - * - * @return bool TRUE - */ - public function is_supported() - { - return TRUE; - } - -} diff --git a/src/Libraries/Cache/drivers/Cache_dummy.php b/src/Libraries/Cache/drivers/Cache_dummy.php deleted file mode 100644 index 53d67ea..0000000 --- a/src/Libraries/Cache/drivers/Cache_dummy.php +++ /dev/null @@ -1,170 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; - -/** - * FuzeWorks Dummy Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_dummy extends FW_Driver implements CacheInterface { - - /** - * Get - * - * Since this is the dummy class, it's always going to return FALSE. - * - * @param string - * @return bool FALSE - */ - public function get($id) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string Unique Key - * @param mixed Data to store - * @param int Length of time (in seconds) to cache the data - * @param bool Whether to store the raw value - * @return bool TRUE, Simulating success - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of the item in the cache - * @return bool TRUE, simulating success - */ - public function remove($id) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool TRUE, simulating success - */ - public function clean() - { - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @param string user/filehits - * @return bool FALSE - */ - public function cache_info($type = NULL) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return bool FALSE - */ - public function get_metadata($id) - { - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Is this caching driver supported on the system? - * Of course this one is. - * - * @return bool TRUE - */ - public function is_supported() - { - return TRUE; - } - -} diff --git a/src/Libraries/Cache/drivers/Cache_file.php b/src/Libraries/Cache/drivers/Cache_file.php deleted file mode 100644 index ca7269b..0000000 --- a/src/Libraries/Cache/drivers/Cache_file.php +++ /dev/null @@ -1,296 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.1.5 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Factory; -use FuzeWorks\Core; - -/** - * FuzeWorks File Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_file extends FW_Driver implements CacheInterface { - - /** - * Directory in which to save cache files - * - * @var string - */ - protected $_cache_path; - - /** - * Initialize file-based cache - * - * @return void - */ - public function __construct() - { - // Load the factory - $factory = Factory::getInstance(); - - // Load the required helpers - $factory->helpers->load('file'); - $this->_cache_path = Core::$tempDir . DS . 'CacheLibrary' . DS; - } - - // ------------------------------------------------------------------------ - - /** - * Fetch from cache - * - * @param string $id Cache ID - * @return mixed Data on success, FALSE on failure - */ - public function get($id) - { - $data = $this->_get($id); - return is_array($data) ? $data['data'] : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Save into cache - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttl Time to live in seconds - * @param bool $raw Whether to store the raw value (unused) - * @return bool TRUE on success, FALSE on failure - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - $contents = array( - 'time' => time(), - 'ttl' => $ttl, - 'data' => $data - ); - - if (write_file($this->_cache_path.$id, serialize($contents))) - { - chmod($this->_cache_path.$id, 0640); - return TRUE; - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of item in cache - * @return bool true on success/false on failure - */ - public function remove($id) - { - return file_exists($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return New value on success, FALSE on failure - */ - public function increment($id, $offset = 1) - { - $data = $this->_get($id); - - if ($data === FALSE) - { - $data = array('data' => 0, 'ttl' => 60); - } - elseif ( ! is_int($data['data'])) - { - return FALSE; - } - - $new_value = $data['data'] + $offset; - return $this->save($id, $new_value, $data['ttl']) - ? $new_value - : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return New value on success, FALSE on failure - */ - public function decrement($id, $offset = 1) - { - $data = $this->_get($id); - - if ($data === FALSE) - { - $data = array('data' => 0, 'ttl' => 60); - } - elseif ( ! is_int($data['data'])) - { - return FALSE; - } - - $new_value = $data['data'] - $offset; - return $this->save($id, $new_value, $data['ttl']) - ? $new_value - : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Clean the Cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return delete_files($this->_cache_path, FALSE, TRUE); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * Not supported by file-based caching - * - * @param string user/filehits - * @return mixed FALSE - */ - public function cache_info($type = NULL) - { - return get_dir_file_info($this->_cache_path); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return mixed FALSE on failure, array on success. - */ - public function get_metadata($id) - { - if ( ! file_exists($this->_cache_path.$id)) - { - return FALSE; - } - - $data = unserialize(file_get_contents($this->_cache_path.$id)); - - if (is_array($data)) - { - $mtime = filemtime($this->_cache_path.$id); - - if ( ! isset($data['ttl'])) - { - return FALSE; - } - - return array( - 'expire' => $mtime + $data['ttl'], - 'mtime' => $mtime - ); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Is supported - * - * In the file driver, check to see that the cache directory is indeed writable - * - * @return bool - */ - public function is_supported() - { - if ( ! is_dir($this->_cache_path)) - { - if (!mkdir($this->_cache_path, 0777, false)) - { - return false; - } - } - - return is_really_writable($this->_cache_path); - } - - // ------------------------------------------------------------------------ - - /** - * Get all data - * - * Internal method to get all the relevant data about a cache item - * - * @param string $id Cache ID - * @return mixed Data array on success or FALSE on failure - */ - protected function _get($id) - { - if ( ! is_file($this->_cache_path.$id)) - { - return FALSE; - } - - $data = unserialize(file_get_contents($this->_cache_path.$id)); - - if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl']) - { - unlink($this->_cache_path.$id); - return FALSE; - } - - return $data; - } - -} diff --git a/src/Libraries/Cache/drivers/Cache_memcached.php b/src/Libraries/Cache/drivers/Cache_memcached.php deleted file mode 100644 index 8a44954..0000000 --- a/src/Libraries/Cache/drivers/Cache_memcached.php +++ /dev/null @@ -1,301 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Factory; -use FuzeWorks\Logger; -use Memcached; -use Memcache; - -/** - * FuzeWorks Memcached Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author EllisLab Dev Team - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_memcached extends FW_Driver implements CacheInterface { - - /** - * Holds the memcached object - * - * @var object - */ - protected $_memcached; - - /** - * Memcached configuration - * - * @var array - */ - protected $_config = array( - 'default' => array( - 'host' => '127.0.0.1', - 'port' => 11211, - 'weight' => 1 - ) - ); - - // ------------------------------------------------------------------------ - - /** - * Class constructor - * - * Setup Memcache(d) - * - * @return void - */ - public function __construct() - { - // Try to load memcached server info from the config file. - $defaults = $this->_config['default']; - - $this->_config = Factory::getInstance()->config->get('cache')->memcached; - - if (class_exists('Memcached', FALSE)) - { - $this->_memcached = new Memcached(); - } - elseif (class_exists('Memcache', FALSE)) - { - $this->_memcached = new Memcache(); - } - else - { - Logger::logError('Cache: Failed to create Memcache(d) object; extension not loaded?'); - return; - } - - foreach ($this->_config as $cache_server) - { - isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host']; - isset($cache_server['port']) OR $cache_server['port'] = $defaults['port']; - isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight']; - - if ($this->_memcached instanceof Memcache) - { - // Third parameter is persistance and defaults to TRUE. - $this->_memcached->addServer( - $cache_server['hostname'], - $cache_server['port'], - TRUE, - $cache_server['weight'] - ); - } - elseif ($this->_memcached instanceof Memcached) - { - $this->_memcached->addServer( - $cache_server['hostname'], - $cache_server['port'], - $cache_server['weight'] - ); - } - } - } - - // ------------------------------------------------------------------------ - - /** - * Fetch from cache - * - * @param string $id Cache ID - * @return mixed Data on success, FALSE on failure - */ - public function get($id) - { - $data = $this->_memcached->get($id); - - return is_array($data) ? $data[0] : $data; - } - - // ------------------------------------------------------------------------ - - /** - * Save - * - * @param string $id Cache ID - * @param mixed $data Data being cached - * @param int $ttl Time to live - * @param bool $raw Whether to store the raw value - * @return bool TRUE on success, FALSE on failure - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - if ($raw !== TRUE) - { - $data = array($data, time(), $ttl); - } - - if ($this->_memcached instanceof Memcached) - { - return $this->_memcached->set($id, $data, $ttl); - } - elseif ($this->_memcached instanceof Memcache) - { - return $this->_memcached->set($id, $data, 0, $ttl); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed $id key to be deleted. - * @return bool true on success, false on failure - */ - public function remove($id) - { - return $this->_memcached->delete($id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return $this->_memcached->increment($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return $this->_memcached->decrement($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean the Cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return $this->_memcached->flush(); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @return mixed array on success, false on failure - */ - public function cache_info() - { - return $this->_memcached->getStats(); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed $id key to get cache metadata on - * @return mixed FALSE on failure, array on success. - */ - public function get_metadata($id) - { - $stored = $this->_memcached->get($id); - - if (count($stored) !== 3) - { - return FALSE; - } - - list($data, $time, $ttl) = $stored; - - return array( - 'expire' => $time + $ttl, - 'mtime' => $time, - 'data' => $data - ); - } - - // ------------------------------------------------------------------------ - - /** - * Is supported - * - * Returns FALSE if memcached is not supported on the system. - * If it is, we setup the memcached object & return TRUE - * - * @return bool - */ - public function is_supported() - { - return (extension_loaded('memcached') OR extension_loaded('memcache')); - } - - // ------------------------------------------------------------------------ - - /** - * Class destructor - * - * Closes the connection to Memcache(d) if present. - * - * @return void - */ - public function __destruct() - { - if ($this->_memcached instanceof Memcache) - { - $this->_memcached->close(); - } - elseif ($this->_memcached instanceof Memcached) - { - $this->_memcached->quit(); - } - } -} diff --git a/src/Libraries/Cache/drivers/Cache_redis.php b/src/Libraries/Cache/drivers/Cache_redis.php deleted file mode 100644 index a97b9d8..0000000 --- a/src/Libraries/Cache/drivers/Cache_redis.php +++ /dev/null @@ -1,321 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Factory; -use FuzeWorks\Logger; -use Redis; -use RedisException; - -/** - * FuzeWorks Redis Caching Class - * - * Converted from CodeIgniter. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author Anton Lindqvist - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_redis extends FW_Driver implements CacheInterface -{ - /** - * Default config - * - * @static - * @var array - */ - protected static $_default_config = array( - 'socket_type' => 'tcp', - 'host' => '127.0.0.1', - 'password' => NULL, - 'port' => 6379, - 'timeout' => 0 - ); - - /** - * Redis connection - * - * @var Redis - */ - protected $_redis; - - /** - * An internal cache for storing keys of serialized values. - * - * @var array - */ - protected $_serialized = array(); - - // ------------------------------------------------------------------------ - - /** - * Class constructor - * - * Setup Redis - * - * Loads Redis config file if present. Will halt execution - * if a Redis connection can't be established. - * - * @return void - * @see Redis::connect() - */ - public function __construct() - { - if ( ! $this->is_supported()) - { - Logger::logError('Cache: Failed to create Redis object; extension not loaded?'); - return; - } - - $config = array_merge(self::$_default_config, Factory::getInstance()->config->get('cache')->redis); - - $this->_redis = new Redis(); - - try - { - if ($config['socket_type'] === 'unix') - { - $success = $this->_redis->connect($config['socket']); - } - else // tcp socket - { - $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']); - } - - if ( ! $success) - { - Logger::logError('Cache: Redis connection failed. Check your configuration.'); - } - - if (isset($config['password']) && ! $this->_redis->auth($config['password'])) - { - Logger::logError('Cache: Redis authentication failed.'); - } - } - catch (RedisException $e) - { - Logger::logError('Cache: Redis connection refused ('.$e->getMessage().')'); - } - - // Initialize the index of serialized values. - $serialized = $this->_redis->sMembers('_ci_redis_serialized'); - empty($serialized) OR $this->_serialized = array_flip($serialized); - } - - // ------------------------------------------------------------------------ - - /** - * Get cache - * - * @param string $key Cache ID - * @return mixed - */ - public function get($key) - { - $value = $this->_redis->get($key); - - if ($value !== FALSE && isset($this->_serialized[$key])) - { - return unserialize($value); - } - - return $value; - } - - // ------------------------------------------------------------------------ - - /** - * Save cache - * - * @param string $id Cache ID - * @param mixed $data Data to save - * @param int $ttl Time to live in seconds - * @param bool $raw Whether to store the raw value (unused) - * @return bool TRUE on success, FALSE on failure - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - if (is_array($data) OR is_object($data)) - { - if ( ! $this->_redis->sIsMember('_ci_redis_serialized', $id) && ! $this->_redis->sAdd('_ci_redis_serialized', $id)) - { - return FALSE; - } - - isset($this->_serialized[$id]) OR $this->_serialized[$id] = TRUE; - $data = serialize($data); - } - elseif (isset($this->_serialized[$id])) - { - $this->_serialized[$id] = NULL; - $this->_redis->sRemove('_ci_redis_serialized', $id); - } - - return $this->_redis->set($id, $data, $ttl); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from cache - * - * @param string $key Cache key - * @return bool - */ - public function remove($key) - { - if ($this->_redis->delete($key) !== 1) - { - return FALSE; - } - - if (isset($this->_serialized[$key])) - { - $this->_serialized[$key] = NULL; - $this->_redis->sRemove('_ci_redis_serialized', $key); - } - - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - return $this->_redis->incr($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - return $this->_redis->decr($id, $offset); - } - - // ------------------------------------------------------------------------ - - /** - * Clean cache - * - * @return bool - * @see Redis::flushDB() - */ - public function clean() - { - return $this->_redis->flushDB(); - } - - // ------------------------------------------------------------------------ - - /** - * Get cache driver info - * - * @param string $type Not supported in Redis. - * Only included in order to offer a - * consistent cache API. - * @return array - * @see Redis::info() - */ - public function cache_info($type = NULL) - { - return $this->_redis->info(); - } - - // ------------------------------------------------------------------------ - - /** - * Get cache metadata - * - * @param string $key Cache key - * @return array - */ - public function get_metadata($key) - { - $value = $this->get($key); - - if ($value !== FALSE) - { - return array( - 'expire' => time() + $this->_redis->ttl($key), - 'data' => $value - ); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Check if Redis driver is supported - * - * @return bool - */ - public function is_supported() - { - return extension_loaded('redis'); - } - - // ------------------------------------------------------------------------ - - /** - * Class destructor - * - * Closes the connection to Redis if present. - * - * @return void - */ - public function __destruct() - { - if ($this->_redis) - { - $this->_redis->close(); - } - } -} diff --git a/src/Libraries/Cache/drivers/Cache_wincache.php b/src/Libraries/Cache/drivers/Cache_wincache.php deleted file mode 100644 index 27decb5..0000000 --- a/src/Libraries/Cache/drivers/Cache_wincache.php +++ /dev/null @@ -1,216 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Logger; - -/** - * FuzeWorks Wincache Caching Class - * - * Converted from CodeIgniter. - * - * Read more about Wincache functions here: - * http://www.php.net/manual/en/ref.wincache.php - * - * @package FuzeWorks - * @subpackage Libraries - * @category Core - * @author Mike Murkovic - * @link - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Cache_wincache extends FW_Driver implements CacheInterface { - - /** - * Class constructor - * - * Only present so that an error message is logged - * if APC is not available. - * - * @return void - */ - public function __construct() - { - if ( ! $this->is_supported()) - { - Logger::logError('Cache: Failed to initialize Wincache; extension not loaded/enabled?'); - } - } - - // ------------------------------------------------------------------------ - - /** - * Get - * - * Look for a value in the cache. If it exists, return the data, - * if not, return FALSE - * - * @param string $id Cache Ide - * @return mixed Value that is stored/FALSE on failure - */ - public function get($id) - { - $success = FALSE; - $data = wincache_ucache_get($id, $success); - - // Success returned by reference from wincache_ucache_get() - return ($success) ? $data : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Cache Save - * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttl Time to live (in seconds) - * @param bool $raw Whether to store the raw value (unused) - * @return bool true on success/false on failure - */ - public function set($id, $data, $ttl = 60, $raw = FALSE) - { - return wincache_ucache_set($id, $data, $ttl); - } - - // ------------------------------------------------------------------------ - - /** - * Delete from Cache - * - * @param mixed unique identifier of the item in the cache - * @return bool true on success/false on failure - */ - public function remove($id) - { - return wincache_ucache_delete($id); - } - - // ------------------------------------------------------------------------ - - /** - * Increment a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to add - * @return mixed New value on success or FALSE on failure - */ - public function increment($id, $offset = 1) - { - $success = FALSE; - $value = wincache_ucache_inc($id, $offset, $success); - - return ($success === TRUE) ? $value : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Decrement a raw value - * - * @param string $id Cache ID - * @param int $offset Step/value to reduce by - * @return mixed New value on success or FALSE on failure - */ - public function decrement($id, $offset = 1) - { - $success = FALSE; - $value = wincache_ucache_dec($id, $offset, $success); - - return ($success === TRUE) ? $value : FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * Clean the cache - * - * @return bool false on failure/true on success - */ - public function clean() - { - return wincache_ucache_clear(); - } - - // ------------------------------------------------------------------------ - - /** - * Cache Info - * - * @return mixed array on success, false on failure - */ - public function cache_info() - { - return wincache_ucache_info(TRUE); - } - - // ------------------------------------------------------------------------ - - /** - * Get Cache Metadata - * - * @param mixed key to get cache metadata on - * @return mixed array on success/false on failure - */ - public function get_metadata($id) - { - if ($stored = wincache_ucache_info(FALSE, $id)) - { - $age = $stored['ucache_entries'][1]['age_seconds']; - $ttl = $stored['ucache_entries'][1]['ttl_seconds']; - $hitcount = $stored['ucache_entries'][1]['hitcount']; - - return array( - 'expire' => $ttl - $age, - 'hitcount' => $hitcount, - 'age' => $age, - 'ttl' => $ttl - ); - } - - return FALSE; - } - - // ------------------------------------------------------------------------ - - /** - * is_supported() - * - * Check to see if WinCache is available on this system, bail if it isn't. - * - * @return bool - */ - public function is_supported() - { - return (extension_loaded('wincache') && ini_get('wincache.ucenabled')); - } -} diff --git a/src/Libraries/Email.php b/src/Libraries/Email.php deleted file mode 100644 index 178e3f7..0000000 --- a/src/Libraries/Email.php +++ /dev/null @@ -1,2346 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -namespace FuzeWorks\Library; -use FuzeWorks\Core; -use FuzeWorks\Factory; -use FuzeWorks\Logger; -use FuzeWorks\Language; - -/** - * FuzeWorks Email Class. - * - * Converted from CodeIgniter. - * - * Permits email to be sent using Mail, Sendmail, or SMTP. - * - * @package FuzeWorks - * @subpackage Libraries - * @category Libraries - * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/email.html - * @license http://opensource.org/licenses/MIT MIT License - */ -class FW_Email { - - /** - * Used as the User-Agent and X-Mailer headers' value. - * - * @var string - */ - public $useragent = 'FuzeWorks'; - - /** - * Path to the Sendmail binary. - * - * @var string - */ - public $mailpath = '/usr/sbin/sendmail'; // Sendmail path - - /** - * Which method to use for sending e-mails. - * - * @var string 'mail', 'sendmail' or 'smtp' - */ - public $protocol = 'mail'; // mail/sendmail/smtp - - /** - * STMP Server host - * - * @var string - */ - public $smtp_host = ''; - - /** - * SMTP Username - * - * @var string - */ - public $smtp_user = ''; - - /** - * SMTP Password - * - * @var string - */ - public $smtp_pass = ''; - - /** - * SMTP Server port - * - * @var int - */ - public $smtp_port = 25; - - /** - * SMTP connection timeout in seconds - * - * @var int - */ - public $smtp_timeout = 5; - - /** - * SMTP persistent connection - * - * @var bool - */ - public $smtp_keepalive = FALSE; - - /** - * SMTP Encryption - * - * @var string empty, 'tls' or 'ssl' - */ - public $smtp_crypto = ''; - - /** - * Whether to apply word-wrapping to the message body. - * - * @var bool - */ - public $wordwrap = TRUE; - - /** - * Number of characters to wrap at. - * - * @see Email::$wordwrap - * @var int - */ - public $wrapchars = 76; - - /** - * Message format. - * - * @var string 'text' or 'html' - */ - public $mailtype = 'text'; - - /** - * Character set (default: utf-8) - * - * @var string - */ - public $charset = 'utf-8'; - - /** - * Multipart message - * - * @var string 'mixed' (in the body) or 'related' (separate) - */ - public $multipart = 'mixed'; // "mixed" (in the body) or "related" (separate) - - /** - * Alternative message (for HTML messages only) - * - * @var string - */ - public $alt_message = ''; - - /** - * Whether to validate e-mail addresses. - * - * @var bool - */ - public $validate = FALSE; - - /** - * X-Priority header value. - * - * @var int 1-5 - */ - public $priority = 3; // Default priority (1 - 5) - - /** - * Newline character sequence. - * Use "\r\n" to comply with RFC 822. - * - * @link http://www.ietf.org/rfc/rfc822.txt - * @var string "\r\n" or "\n" - */ - public $newline = "\n"; // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822) - - /** - * CRLF character sequence - * - * RFC 2045 specifies that for 'quoted-printable' encoding, - * "\r\n" must be used. However, it appears that some servers - * (even on the receiving end) don't handle it properly and - * switching to "\n", while improper, is the only solution - * that seems to work for all environments. - * - * @link http://www.ietf.org/rfc/rfc822.txt - * @var string - */ - public $crlf = "\n"; - - /** - * Whether to use Delivery Status Notification. - * - * @var bool - */ - public $dsn = FALSE; - - /** - * Whether to send multipart alternatives. - * Yahoo! doesn't seem to like these. - * - * @var bool - */ - public $send_multipart = TRUE; - - /** - * Whether to send messages to BCC recipients in batches. - * - * @var bool - */ - public $bcc_batch_mode = FALSE; - - /** - * BCC Batch max number size. - * - * @see Email::$bcc_batch_mode - * @var int - */ - public $bcc_batch_size = 200; - - // -------------------------------------------------------------------- - - /** - * Whether PHP is running in safe mode. Initialized by the class constructor. - * - * @var bool - */ - protected $_safe_mode = FALSE; - - /** - * Subject header - * - * @var string - */ - protected $_subject = ''; - - /** - * Message body - * - * @var string - */ - protected $_body = ''; - - /** - * Final message body to be sent. - * - * @var string - */ - protected $_finalbody = ''; - - /** - * multipart/alternative boundary - * - * @var string - */ - protected $_alt_boundary = ''; - - /** - * Attachment boundary - * - * @var string - */ - protected $_atc_boundary = ''; - - /** - * Final headers to send - * - * @var string - */ - protected $_header_str = ''; - - /** - * SMTP Connection socket placeholder - * - * @var resource - */ - protected $_smtp_connect = ''; - - /** - * Mail encoding - * - * @var string '8bit' or '7bit' - */ - protected $_encoding = '8bit'; - - /** - * Whether to perform SMTP authentication - * - * @var bool - */ - protected $_smtp_auth = FALSE; - - /** - * Whether to send a Reply-To header - * - * @var bool - */ - protected $_replyto_flag = FALSE; - - /** - * Debug messages - * - * @see Email::print_debugger() - * @var string - */ - protected $_debug_msg = array(); - - /** - * Recipients - * - * @var string[] - */ - protected $_recipients = array(); - - /** - * CC Recipients - * - * @var string[] - */ - protected $_cc_array = array(); - - /** - * BCC Recipients - * - * @var string[] - */ - protected $_bcc_array = array(); - - /** - * Message headers - * - * @var string[] - */ - protected $_headers = array(); - - /** - * Attachment data - * - * @var array - */ - protected $_attachments = array(); - - /** - * Valid $protocol values - * - * @see Email::$protocol - * @var string[] - */ - protected $_protocols = array('mail', 'sendmail', 'smtp'); - - /** - * Base charsets - * - * Character sets valid for 7-bit encoding, - * excluding language suffix. - * - * @var string[] - */ - protected $_base_charsets = array('us-ascii', 'iso-2022-'); - - /** - * Bit depths - * - * Valid mail encodings - * - * @see Email::$_encoding - * @var string[] - */ - protected $_bit_depths = array('7bit', '8bit'); - - /** - * $priority translations - * - * Actual values to send with the X-Priority header - * - * @var string[] - */ - protected $_priorities = array( - 1 => '1 (Highest)', - 2 => '2 (High)', - 3 => '3 (Normal)', - 4 => '4 (Low)', - 5 => '5 (Lowest)' - ); - - // -------------------------------------------------------------------- - - /** - * Constructor - Sets Email Preferences - * - * The constructor can be passed an array of config values - * - * @param array $config = array() - * @return void - */ - public function __construct(array $config = array()) - { - $this->charset = Factory::getInstance()->config->get('main')->charset; - - if (count($config) > 0) - { - $this->initialize($config); - } - else - { - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - } - - $this->_safe_mode = ( ! Core::isPHP('5.4') && ini_get('safe_mode')); - $this->charset = strtoupper($this->charset); - - Logger::log('Email Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Destructor - Releases Resources - * - * @return void - */ - public function __destruct() - { - if (is_resource($this->_smtp_connect)) - { - $this->_send_command('quit'); - } - } - - // -------------------------------------------------------------------- - - /** - * Initialize preferences - * - * @param array - * @return Email - */ - public function initialize($config = array()) - { - foreach ($config as $key => $val) - { - if (isset($this->$key)) - { - $method = 'set_'.$key; - - if (method_exists($this, $method)) - { - $this->$method($val); - } - else - { - $this->$key = $val; - } - } - } - $this->clear(); - - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Initialize the Email Data - * - * @param bool - * @return Email - */ - public function clear($clear_attachments = FALSE) - { - $this->_subject = ''; - $this->_body = ''; - $this->_finalbody = ''; - $this->_header_str = ''; - $this->_replyto_flag = FALSE; - $this->_recipients = array(); - $this->_cc_array = array(); - $this->_bcc_array = array(); - $this->_headers = array(); - $this->_debug_msg = array(); - - $this->set_header('User-Agent', $this->useragent); - $this->set_header('Date', $this->_set_date()); - - if ($clear_attachments !== FALSE) - { - $this->_attachments = array(); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set FROM - * - * @param string $from - * @param string $name - * @param string $return_path = NULL Return-Path - * @return Email - */ - public function from($from, $name = '', $return_path = NULL) - { - if (preg_match('/\<(.*)\>/', $from, $match)) - { - $from = $match[1]; - } - - if ($this->validate) - { - $this->validate_email($this->_str_to_array($from)); - if ($return_path) - { - $this->validate_email($this->_str_to_array($return_path)); - } - } - - // prepare the display name - if ($name !== '') - { - // only use Q encoding if there are characters that would require it - if ( ! preg_match('/[\200-\377]/', $name)) - { - // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes - $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"'; - } - else - { - $name = $this->_prep_q_encoding($name); - } - } - - $this->set_header('From', $name.' <'.$from.'>'); - - isset($return_path) OR $return_path = $from; - $this->set_header('Return-Path', '<'.$return_path.'>'); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Reply-to - * - * @param string - * @param string - * @return Email - */ - public function reply_to($replyto, $name = '') - { - if (preg_match('/\<(.*)\>/', $replyto, $match)) - { - $replyto = $match[1]; - } - - if ($this->validate) - { - $this->validate_email($this->_str_to_array($replyto)); - } - - if ($name !== '') - { - // only use Q encoding if there are characters that would require it - if ( ! preg_match('/[\200-\377]/', $name)) - { - // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes - $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"'; - } - else - { - $name = $this->_prep_q_encoding($name); - } - } - - $this->set_header('Reply-To', $name.' <'.$replyto.'>'); - $this->_replyto_flag = TRUE; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Recipients - * - * @param string - * @return Email - */ - public function to($to) - { - $to = $this->_str_to_array($to); - $to = $this->clean_email($to); - - if ($this->validate) - { - $this->validate_email($to); - } - - if ($this->_get_protocol() !== 'mail') - { - $this->set_header('To', implode(', ', $to)); - } - - $this->_recipients = $to; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set CC - * - * @param string - * @return Email - */ - public function cc($cc) - { - $cc = $this->clean_email($this->_str_to_array($cc)); - - if ($this->validate) - { - $this->validate_email($cc); - } - - $this->set_header('Cc', implode(', ', $cc)); - - if ($this->_get_protocol() === 'smtp') - { - $this->_cc_array = $cc; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set BCC - * - * @param string - * @param string - * @return Email - */ - public function bcc($bcc, $limit = '') - { - if ($limit !== '' && is_numeric($limit)) - { - $this->bcc_batch_mode = TRUE; - $this->bcc_batch_size = $limit; - } - - $bcc = $this->clean_email($this->_str_to_array($bcc)); - - if ($this->validate) - { - $this->validate_email($bcc); - } - - if ($this->_get_protocol() === 'smtp' OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size)) - { - $this->_bcc_array = $bcc; - } - else - { - $this->set_header('Bcc', implode(', ', $bcc)); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Email Subject - * - * @param string - * @return Email - */ - public function subject($subject) - { - $subject = $this->_prep_q_encoding($subject); - $this->set_header('Subject', $subject); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Body - * - * @param string - * @return Email - */ - public function message($body) - { - $this->_body = rtrim(str_replace("\r", '', $body)); - - /* strip slashes only if magic quotes is ON - if we do it with magic quotes OFF, it strips real, user-inputted chars. - - NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and - it will probably not exist in future versions at all. - */ - if ( ! Core::isPHP('5.4') && get_magic_quotes_gpc()) - { - $this->_body = stripslashes($this->_body); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Assign file attachments - * - * @param string $file Can be local path, URL or buffered content - * @param string $disposition = 'attachment' - * @param string $newname = NULL - * @param string $mime = '' - * @return Email - */ - public function attach($file, $disposition = '', $newname = NULL, $mime = '') - { - if ($mime === '') - { - if (strpos($file, '://') === FALSE && ! file_exists($file)) - { - $this->_set_error_message('lang:email_attachment_missing', $file); - return FALSE; - } - - if ( ! $fp = @fopen($file, 'rb')) - { - $this->_set_error_message('lang:email_attachment_unreadable', $file); - return FALSE; - } - - $file_content = stream_get_contents($fp); - $mime = $this->_mime_types(pathinfo($file, PATHINFO_EXTENSION)); - fclose($fp); - } - else - { - $file_content =& $file; // buffered file - } - - $this->_attachments[] = array( - 'name' => array($file, $newname), - 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters - 'type' => $mime, - 'content' => chunk_split(base64_encode($file_content)) - ); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set and return attachment Content-ID - * - * Useful for attached inline pictures - * - * @param string $filename - * @return string - */ - public function attachment_cid($filename) - { - if ($this->multipart !== 'related') - { - $this->multipart = 'related'; // Thunderbird need this for inline images - } - - for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) - { - if ($this->_attachments[$i]['name'][0] === $filename) - { - $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); - return $this->_attachments[$i]['cid']; - } - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Add a Header Item - * - * @param string - * @param string - * @return Email - */ - public function set_header($header, $value) - { - $this->_headers[$header] = str_replace(array("\n", "\r"), '', $value); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Convert a String to an Array - * - * @param string - * @return array - */ - protected function _str_to_array($email) - { - if ( ! is_array($email)) - { - return (strpos($email, ',') !== FALSE) - ? preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY) - : (array) trim($email); - } - - return $email; - } - - // -------------------------------------------------------------------- - - /** - * Set Multipart Value - * - * @param string - * @return Email - */ - public function set_alt_message($str) - { - $this->alt_message = (string) $str; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Mailtype - * - * @param string - * @return Email - */ - public function set_mailtype($type = 'text') - { - $this->mailtype = ($type === 'html') ? 'html' : 'text'; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Wordwrap - * - * @param bool - * @return Email - */ - public function set_wordwrap($wordwrap = TRUE) - { - $this->wordwrap = (bool) $wordwrap; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Protocol - * - * @param string - * @return Email - */ - public function set_protocol($protocol = 'mail') - { - $this->protocol = in_array($protocol, $this->_protocols, TRUE) ? strtolower($protocol) : 'mail'; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Priority - * - * @param int - * @return Email - */ - public function set_priority($n = 3) - { - $this->priority = preg_match('/^[1-5]$/', $n) ? (int) $n : 3; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Newline Character - * - * @param string - * @return Email - */ - public function set_newline($newline = "\n") - { - $this->newline = in_array($newline, array("\n", "\r\n", "\r")) ? $newline : "\n"; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set CRLF - * - * @param string - * @return Email - */ - public function set_crlf($crlf = "\n") - { - $this->crlf = ($crlf !== "\n" && $crlf !== "\r\n" && $crlf !== "\r") ? "\n" : $crlf; - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Set Message Boundary - * - * @return void - */ - protected function _set_boundaries() - { - $this->_alt_boundary = 'B_ALT_'.uniqid(''); // multipart/alternative - $this->_atc_boundary = 'B_ATC_'.uniqid(''); // attachment boundary - } - - // -------------------------------------------------------------------- - - /** - * Get the Message ID - * - * @return string - */ - protected function _get_message_id() - { - $from = str_replace(array('>', '<'), '', $this->_headers['Return-Path']); - return '<'.uniqid('').strstr($from, '@').'>'; - } - - // -------------------------------------------------------------------- - - /** - * Get Mail Protocol - * - * @param bool - * @return mixed - */ - protected function _get_protocol($return = TRUE) - { - $this->protocol = strtolower($this->protocol); - in_array($this->protocol, $this->_protocols, TRUE) OR $this->protocol = 'mail'; - - if ($return === TRUE) - { - return $this->protocol; - } - } - - // -------------------------------------------------------------------- - - /** - * Get Mail Encoding - * - * @param bool - * @return string - */ - protected function _get_encoding($return = TRUE) - { - in_array($this->_encoding, $this->_bit_depths) OR $this->_encoding = '8bit'; - - foreach ($this->_base_charsets as $charset) - { - if (strpos($charset, $this->charset) === 0) - { - $this->_encoding = '7bit'; - } - } - - if ($return === TRUE) - { - return $this->_encoding; - } - } - - // -------------------------------------------------------------------- - - /** - * Get content type (text/html/attachment) - * - * @return string - */ - protected function _get_content_type() - { - if ($this->mailtype === 'html') - { - return (count($this->_attachments) === 0) ? 'html' : 'html-attach'; - } - elseif ($this->mailtype === 'text' && count($this->_attachments) > 0) - { - return 'plain-attach'; - } - else - { - return 'plain'; - } - } - - // -------------------------------------------------------------------- - - /** - * Set RFC 822 Date - * - * @return string - */ - protected function _set_date() - { - $timezone = date('Z'); - $operator = ($timezone[0] === '-') ? '-' : '+'; - $timezone = abs($timezone); - $timezone = floor($timezone/3600) * 100 + ($timezone % 3600) / 60; - - return sprintf('%s %s%04d', date('D, j M Y H:i:s'), $operator, $timezone); - } - - // -------------------------------------------------------------------- - - /** - * Mime message - * - * @return string - */ - protected function _get_mime_message() - { - return 'This is a multi-part message in MIME format.'.$this->newline.'Your email application may not support this format.'; - } - - // -------------------------------------------------------------------- - - /** - * Validate Email Address - * - * @param string - * @return bool - */ - public function validate_email($email) - { - if ( ! is_array($email)) - { - $this->_set_error_message('lang:email_must_be_array'); - return FALSE; - } - - foreach ($email as $val) - { - if ( ! $this->valid_email($val)) - { - $this->_set_error_message('lang:email_invalid_address', $val); - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Email Validation - * - * @param string - * @return bool - */ - public function valid_email($email) - { - if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@')) - { - $email = substr($email, 0, ++$atpos).idn_to_ascii(substr($email, $atpos)); - } - - return (bool) filter_var($email, FILTER_VALIDATE_EMAIL); - } - - // -------------------------------------------------------------------- - - /** - * Clean Extended Email Address: Joe Smith - * - * @param string - * @return string - */ - public function clean_email($email) - { - if ( ! is_array($email)) - { - return preg_match('/\<(.*)\>/', $email, $match) ? $match[1] : $email; - } - - $clean_email = array(); - - foreach ($email as $addy) - { - $clean_email[] = preg_match('/\<(.*)\>/', $addy, $match) ? $match[1] : $addy; - } - - return $clean_email; - } - - // -------------------------------------------------------------------- - - /** - * Build alternative plain text message - * - * Provides the raw message for use in plain-text headers of - * HTML-formatted emails. - * If the user hasn't specified his own alternative message - * it creates one by stripping the HTML - * - * @return string - */ - protected function _get_alt_message() - { - if ( ! empty($this->alt_message)) - { - return ($this->wordwrap) - ? $this->word_wrap($this->alt_message, 76) - : $this->alt_message; - } - - $body = preg_match('/\(.*)\<\/body\>/si', $this->_body, $match) ? $match[1] : $this->_body; - $body = str_replace("\t", '', preg_replace('#\n"; - - $this->assertEquals( - $this->_output_data.$append, - $this->output - ->set_output($this->_output_data) - ->append_output("\n") - ->get_output() - ); - } - - // -------------------------------------------------------------------- - - public function test_get_content_type() - { - $this->assertEquals('text/html', $this->output->get_content_type()); - } - - // -------------------------------------------------------------------- - - public function test_get_header() - { - $this->assertNull($this->output->get_header('Non-Existent-Header')); - - // TODO: Find a way to test header() values as well. Currently, - // PHPUnit prevents this by not using output buffering. - - $this->output->set_content_type('text/plain', 'WINDOWS-1251'); - $this->assertEquals( - 'text/plain; charset=WINDOWS-1251', - $this->output->get_header('content-type') - ); - } - -} diff --git a/tests/core/core_routerTest.php b/tests/core/core_routerTest.php deleted file mode 100644 index 702552a..0000000 --- a/tests/core/core_routerTest.php +++ /dev/null @@ -1,500 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.1.2 - * - * @version Version 1.1.2 - */ - -use FuzeWorks\Router; -use FuzeWorks\Factory; -use FuzeWorks\Core; -use FuzeWorks\Logger; - -/** - * Class RouterTest. - * - * Core testing suite, will test basic core functionality of the FuzeWorks Router - */ -class routerTest extends CoreTestAbstract -{ - - protected $router; - - public function setUp() - { - $this->router = new Router(); - $this->router->setControllerDirectory('tests'.DS.'controller'); - } - - public function testGetRouterClass() - { - $this->assertInstanceOf('FuzeWorks\Router', $this->router); - } - - public function testGetSetRouterDirectory() - { - $directory = 'tests' . DS . 'controller'; - $this->router->setControllerDirectory($directory); - $this->assertEquals($directory, $this->router->getControllerDirectory($directory)); - } - - /* Route Parsing ------------------------------------------------------ */ - - /** - * @depends testGetRouterClass - */ - public function testAddRoutes() - { - $this->router->addRoute('testRoute', function(){}); - $this->assertArrayHasKey('testRoute', $this->router->getRoutes()); - } - - /** - * @depends testAddRoutes - */ - public function testAppendRoutes() - { - $testRouteFunction = array(function(){}); - $testAppendRouteFunction = array(function(){}); - $this->router->addRoute('testRoute', $testRouteFunction); - $this->router->addRoute('testAppendRoute', $testAppendRouteFunction, false); - - // Test if the order is correct - $this->assertSame(array('testRoute' => $testRouteFunction, 'testAppendRoute' => $testAppendRouteFunction), $this->router->getRoutes()); - - // Test if the order is not incorrect - $this->assertNotSame(array('testAppendRoute' => $testAppendRouteFunction,'testRoute' => $testRouteFunction), $this->router->getRoutes()); - } - - /** - * @depends testAddRoutes - */ - public function testRemoveRoutes() - { - // First add - $this->router->addRoute('testRemoveRoute', function(){}); - $this->assertArrayHasKey('testRemoveRoute', $this->router->getRoutes()); - - // Then remove - $this->router->removeRoute('testRemoveRoute'); - $this->assertArrayNotHasKey('testRemoveRoute', $this->router->getRoutes()); - } - - /** - * @depends testAddRoutes - */ - public function testParseRouting() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $config->routes->{'testParseRouting'} = function(){}; - $this->router = new Router(); - - // Now verify whether the passing has gone correctly - $this->assertArrayHasKey('testParseRouting', $this->router->getRoutes()); - } - - /** - * @depends testParseRouting - */ - public function testVerbParsing() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $getFunction = function($get){}; - $postFunction = function($post){}; - $config->routes->{'testVerbPassing'} = array('GET' => $getFunction, 'POST' => $postFunction); - $this->router = new Router(); - - // Now verify whether the passing has gone correctly - $routes = $this->router->getRoutes(); - $this->assertArrayHasKey('testVerbPassing', $routes); - $this->assertSame($getFunction, $routes['testVerbPassing']); - $this->assertNotSame($postFunction, $routes['testVerbPassing']); - } - - /** - * @depends testVerbParsing - */ - public function testInvalidParsing() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $config->routes->{'testInvalidParsing'} = array('NOTGET' => function(){}); - $this->router = new Router(); - - // Now verify whether the route has been skipped - $this->assertArrayNotHasKey('testInvalidParsing', $this->router->getRoutes()); - } - - /** - * @depends testVerbParsing - */ - public function testWildcardsParsing() - { - // Prepare the routes so they can be parsed - $config = Factory::getInstance()->config; - $config->routes->{'testWildcardsParsing/:any/:num'} = function(){}; - $this->router = new Router(); - - // Now verify whether the route has been skipped - $this->assertArrayHasKey('testWildcardsParsing/[^/]+/[0-9]+', $this->router->getRoutes()); - } - - /* defaultCallable() -------------------------------------------------- */ - - /** - * @depends testGetRouterClass - */ - public function testDefaultCallable() - { - // First set the segments, callable and the route - $arguments = array('controller' => 'TestDefaultCallable', 'function' => 'index'); - - // Verify that the controller is found and loaded - $this->assertTrue($this->router->defaultCallable($arguments)); - $this->assertInstanceOf('\Application\Controller\TestDefaultCallable', $this->router->getCallable()); - } - - /** - * @depends testDefaultCallable - */ - public function testDefaultCallableMissingMethod() - { - // First set the arguments - $this->assertEquals(200, Core::$http_status_code); - $arguments = array('controller' => 'TestDefaultCallableMissingMethod', 'function' => 'missing'); - - // Verify that the method is not found - $this->assertFalse($this->router->defaultCallable($arguments)); - $this->assertEquals(404, Core::$http_status_code); - } - - /** - * @depends testDefaultCallable - */ - public function testDefaultCallableMissingController() - { - // First set the arguments - $this->assertEquals(200, Core::$http_status_code); - $arguments = array('controller' => 'TestDefaultCallableMissingController', 'function' => 'index'); - - // Verify that the controller is not found - $this->assertFalse($this->router->defaultCallable($arguments)); - $this->assertEquals(404, Core::$http_status_code); - } - - /** - * @depends testDefaultCallable - */ - public function testDefaultCallableHalt() - { - // First set the arguments - $this->assertEquals(200, Core::$http_status_code); - $arguments = array('controller' => 'TestDefaultCallableHalt', 'function' => 'index'); - - // Verify that the controller is halted - $this->assertFalse($this->router->defaultCallable($arguments)); - $this->assertEquals(200, Core::$http_status_code); - } - - /* -------------------------------------------------------------------- */ - - /* route() ------------------------------------------------------------ */ - - /** - * @depends testGetRouterClass - */ - public function testRoute() - { - // First set the segments and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testRoute'); - $this->router->addRoute('testRoute', function(){}); - - // Perform verification - $this->assertFalse($this->router->route(false)); - $this->assertContains('testRoute', $this->router->getMatches()); - } - - /** - * @depends testRoute - */ - public function testRouteDefaultRoute() - { - // First set the segments and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array(); - - // Perform verification - $this->assertFalse($this->router->route(false)); - $this->assertEmpty($this->router->getMatches()); - } - - /** - * @depends testRoute - */ - public function testArrayRoute() - { - // First set the segments and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testArrayRoute'); - $this->router->addRoute('testArrayRoute', array('callable' => function(){})); - - // Perform verification - $this->assertTrue($this->router->route(false)); - $this->assertContains('testArrayRoute', $this->router->getMatches()); - } - - /* -------------------------------------------------------------------- */ - - /* loadCallable() ----------------------------------------------------- */ - - /** - * @depends testArrayRoute - */ - public function testLoadCallable() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallable'); - $callable = function($arg){$this->assertEquals('testLoadCallable', $arg[0]);return true;}; - $this->router->addRoute('testLoadCallable', array('callable' => $callable)); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertSame($callable, $this->router->getCallable()); - } - - /** - * @depends testLoadCallable - */ - public function testLoadCallableNotCallable() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallableNotCallable'); - $this->router->addRoute('testLoadCallableNotCallable', array('callable' => 'notCallable')); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertSame('notCallable', $this->router->getCallable()); - $this->assertEquals(500, Core::$http_status_code); - } - - /** - * @depends testLoadCallable - */ - public function testLoadCallableToDefaultCallabe() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallableToDefaultCallable'); - $this->router->addRoute('testLoadCallableToDefaultCallable', array('callable' => array('controller' => 'TestLoadCallableToDefaultCallable', 'function' => 'index', 'parameters' => null))); - - // Perform verification - $this->assertTrue($this->router->route(true)); - } - - public function testLoadCallableUnsatisfiedCallable() - { - // First set the segments, callable and the route - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadCallableUnsatisfiedCallable'); - $this->router->addRoute('testLoadCallableUnsatisfiedCallable', array('callable' => function() {return false;} )); - - // Perform verification - $this->assertTrue($this->router->route(true)); - } - - /* -------------------------------------------------------------------- */ - - /* routeDefault() ----------------------------------------------------- */ - - /** - * @depends testLoadCallable - */ - public function testRouteDefault() - { - // First testing the default route without any segments - $uri = Factory::getInstance()->uri; - $uri->segments = array(); - - // Change the default controller so it is easier to test - $config = Factory::getInstance()->config; - $config->routing->default_controller = 'testRouteDefault'; - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testRouteDefault - */ - public function testRouteDefaultUriDashes() - { - // First testing the default route without any segments - $uri = Factory::getInstance()->uri; - - // Change the default controller so URI Dashes get translated - $config = Factory::getInstance()->config; - $config->routing->translate_uri_dashes = TRUE; - - // Perform verification, first test should fail - $uri->segments = array('test-Route-Default-Uri-Dashes-Fail'); - $this->assertTrue($this->router->route(true)); - $this->assertEquals(404, Core::$http_status_code); - - // Reset the HTTP status code - Core::$http_status_code = 200; - - // Next test should succeed - $uri->segments = array('test-Route-Default-Uri-Dashes-Succeed', 'dashed-method'); - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /* -------------------------------------------------------------------- */ - - /* Simulation tests --------------------------------------------------- */ - - /** - * @depends testLoadCallable - */ - public function testLoadController() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('testLoadController'); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testLoadController - */ - public function testLoadStandardController() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array(); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testLoadController - */ - public function testControllerNotFound() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('controllerNotFound'); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(404, Core::$http_status_code); - } - - /** - * @depends testLoadController - */ - public function testMatchingRoute() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('methodInFirstArgument', 'testMatchingRoute'); - - // Create a custom route - $this->router->addRoute('^(?P.*?)(|\/(?P.*?)(|\/(?P.*?)))$', array('callable' => array($this->router, 'defaultCallable'))); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testMatchingRoute - */ - public function testStaticRoute() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('staticKey'); - - // Create a static route - $this->router->addRoute('staticKey', 'standard/index'); - - // Perform verification - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testMatchingRoute - */ - public function testCustomCallable() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('customCallable'); - - // Create a custom callable - $this->router->addRoute('customCallable', array('callable' => function($arguments){ - return true; - } )); - - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /** - * @depends testMatchingRoute - */ - public function testCustomRewriteCallable() - { - // Adjust the URL - $uri = Factory::getInstance()->uri; - $uri->segments = array('customRewriteCallable'); - - // Create a custom callable - $this->router->addRoute('customRewriteCallable', function($arguments = array()){ - return 'standard/index'; - }); - - $this->assertTrue($this->router->route(true)); - $this->assertEquals(200, Core::$http_status_code); - } - - /* -------------------------------------------------------------------- */ -} diff --git a/tests/core/core_securityTest.php b/tests/core/core_securityTest.php deleted file mode 100644 index d535233..0000000 --- a/tests/core/core_securityTest.php +++ /dev/null @@ -1,386 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class SecurityTest. - * - * Core testing suite, will test security class functionality - */ -class securityTest extends CoreTestAbstract -{ - - public function setUp() - { - // Set cookie for security test - $_COOKIE['fw_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE)); - - // Set config for Security class - $config = Factory::getInstance()->config->getConfig('security'); - - $config->csrf_protection = true; - $config->csrf_token_name = 'fw_csrf_token'; - $config->csrf_cookie_name = 'fw_csrf_cookie'; - - $this->security = new Mock_Core_Security(); - } - - // -------------------------------------------------------------------- - - public function test_csrf_verify() - { - $_SERVER['REQUEST_METHOD'] = 'GET'; - - $this->assertInstanceOf('FuzeWorks\Security', $this->security->csrf_verify()); - } - - // -------------------------------------------------------------------- - - /** - * @expectedException FuzeWorks\Exception\SecurityException - */ - public function test_csrf_verify_invalid() - { - // Without issuing $_POST[csrf_token_name], this request will triggering CSRF error - $_SERVER['REQUEST_METHOD'] = 'POST'; - - $this->security->csrf_verify(); - } - - // -------------------------------------------------------------------- - - public function test_csrf_verify_valid() - { - $_SERVER['REQUEST_METHOD'] = 'POST'; - $_POST[$this->security->csrf_token_name] = $this->security->csrf_hash; - - $this->assertInstanceOf('FuzeWorks\Security', $this->security->csrf_verify()); - } - - // -------------------------------------------------------------------- - - public function test_get_csrf_hash() - { - $this->assertEquals($this->security->csrf_hash, $this->security->get_csrf_hash()); - } - - // -------------------------------------------------------------------- - - public function test_get_csrf_token_name() - { - $this->assertEquals('fw_csrf_token', $this->security->get_csrf_token_name()); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean() - { - $harm_string = "Hello, i try to your site"; - - $harmless_string = $this->security->xss_clean($harm_string); - - $this->assertEquals("Hello, i try to [removed]alert('Hack');[removed] your site", $harmless_string); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_string_array() - { - $harm_strings = array( - "Hello, i try to your site", - "Simple clean string", - "Hello, i try to your site" - ); - - $harmless_strings = $this->security->xss_clean($harm_strings); - - $this->assertEquals("Hello, i try to [removed]alert('Hack');[removed] your site", $harmless_strings[0]); - $this->assertEquals("Simple clean string", $harmless_strings[1]); - $this->assertEquals("Hello, i try to [removed]alert('Hack');[removed] your site", $harmless_strings[2]); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_image_valid() - { - $harm_string = ''; - - $xss_clean_return = $this->security->xss_clean($harm_string, TRUE); - - $this->assertTrue($xss_clean_return); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_image_invalid() - { - $harm_string = ''; - - $xss_clean_return = $this->security->xss_clean($harm_string, TRUE); - - $this->assertFalse($xss_clean_return); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_entity_double_encoded() - { - $input = '
Clickhere'; - $this->assertEquals('Clickhere', $this->security->xss_clean($input)); - } - - // -------------------------------------------------------------------- - - public function text_xss_clean_js_link_removal() - { - // This one is to prevent a false positive - $this->assertEquals( - "", - $this->security->xss_clean("") - ); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_js_img_removal() - { - $input = 'Clickhere'; - $this->assertEquals('', $this->security->xss_clean($input)); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_sanitize_naughty_html_tags() - { - $this->assertEquals('<unclosedTag', $this->security->xss_clean('assertEquals('<blink>', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - - $this->assertEquals( - ' src="x">', - $this->security->xss_clean(' src="x">') - ); - - $this->assertEquals( - 'on=">"x onerror="alert(1)">', - $this->security->xss_clean('on=">"x onerror="alert(1)">') - ); - } - - // -------------------------------------------------------------------- - - public function test_xss_clean_sanitize_naughty_html_attributes() - { - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('onOutsideOfTag=test', $this->security->xss_clean('onOutsideOfTag=test')); - $this->assertEquals('onNoTagAtAll = true', $this->security->xss_clean('onNoTagAtAll = true')); - $this->assertEquals('', $this->security->xss_clean('')); - $this->assertEquals('', $this->security->xss_clean('')); - - $this->assertEquals( - '\' xss=removed>', - $this->security->xss_clean('\' onAfterGreaterThan="quotes">') - ); - $this->assertEquals( - '\' xss=removed>', - $this->security->xss_clean('\' onAfterGreaterThan=noQuotes>') - ); - - $this->assertEquals( - ' on=<svg> onerror=alert(1)>', - $this->security->xss_clean(' on= onerror=alert(1)>') - ); - - $this->assertEquals( - '"<svg> onerror=alert(1) onmouseover=alert(1)>', - $this->security->xss_clean('" onerror=alert(1) onmouseover=alert(1)>') - ); - - $this->assertEquals( - ' on=\'x\' onerror=``,alert(1)>', - $this->security->xss_clean(' on=\'x\' onerror=``,alert(1)>') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - - $this->assertEquals( - ' on=\'x\' onerror=,xssm()>', - $this->security->xss_clean(' on=\'x\' onerror=,xssm()>') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - - $this->assertEquals( - '1">', - $this->security->xss_clean('') - ); - - $this->assertEquals( - '', - $this->security->xss_clean('') - ); - } - - // -------------------------------------------------------------------- - - /** - * @depends test_xss_clean_sanitize_naughty_html_tags - * @depends test_xss_clean_sanitize_naughty_html_attributes - */ - public function test_naughty_html_plus_evil_attributes() - { - $this->assertEquals( - '<svg', - $this->security->xss_clean(' src="x" onerror="location=/javascript/.source+/:alert/.source+/(1)/.source">') - ); - } - - // -------------------------------------------------------------------- - - public function test_xss_hash() - { - $this->assertEmpty($this->security->xss_hash); - - // Perform hash - $this->security->xss_hash(); - - $this->assertTrue(preg_match('#^[0-9a-f]{32}$#iS', $this->security->xss_hash) === 1); - } - - // -------------------------------------------------------------------- - - public function test_get_random_bytes() - { - $this->markTestSkipped("Fails to work in the current condition"); - $length = "invalid"; - $this->assertFalse($this->security->get_random_bytes($length)); - - $length = 10; - $this->assertNotEmpty($this->security->get_random_bytes($length)); - } - - // -------------------------------------------------------------------- - - public function test_entity_decode() - { - $encoded = '<div>Hello <b>Booya</b></div>'; - $decoded = $this->security->entity_decode($encoded); - - $this->assertEquals('
Hello Booya
', $decoded); - - // Issue #3057 (https://github.com/bcit-ci/CodeIgniter/issues/3057) - $this->assertEquals( - '&foo should not include a semicolon', - $this->security->entity_decode('&foo should not include a semicolon') - ); - } - - // -------------------------------------------------------------------- - - public function test_sanitize_filename() - { - $filename = './'; - $safe_filename = $this->security->sanitize_filename($filename); - - $this->assertEquals('foo', $safe_filename); - } - - // -------------------------------------------------------------------- - - public function test_strip_image_tags() - { - $imgtags = array( - 'Smiley face', - 'Smiley face', - '', - '', - 'MD Logo', - '', - '', - '', - '' - ); - - $urls = array( - 'smiley.gif', - 'smiley.gif', - 'http://www.w3schools.com/images/w3schools_green.jpg', - '/img/sunset.gif', - 'mdn-logo-sm.png', - '', - '', - '', - 'non-quoted.attribute' - ); - - for ($i = 0; $i < count($imgtags); $i++) - { - $this->assertEquals($urls[$i], $this->security->strip_image_tags($imgtags[$i])); - } - } - - // -------------------------------------------------------------------- - - public function test_csrf_set_hash() - { - // Set cookie for security test - $_COOKIE['fw_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE)); - - // Set config for Security class - $config = Factory::getInstance()->config->getConfig('security'); - - $config->csrf_protection = true; - $config->csrf_token_name = 'fw_csrf_token'; - - // leave csrf_cookie_name as blank to test _csrf_set_hash function - $config->csrf_cookie_name = ''; - - $this->security = new Mock_Core_Security(); - - $this->assertNotEmpty($this->security->get_csrf_hash()); - } -} diff --git a/tests/core/core_uriTest.php b/tests/core/core_uriTest.php deleted file mode 100644 index 320e0a0..0000000 --- a/tests/core/core_uriTest.php +++ /dev/null @@ -1,182 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class URITest. - * - * Core testing suite, will test URI class functionality - */ -class uriTest extends CoreTestAbstract { - - public function setUp() - { - $this->uri = new Mock_Core_URI(); - } - - // -------------------------------------------------------------------- - - public function test_filter_uri_passing() - { - $this->uri->_set_permitted_uri_chars('a-z 0-9~%.:_\-'); - - $str = 'abc01239~%.:_-'; - $this->assertTrue($this->uri->filter_uri($str)); - } - - // -------------------------------------------------------------------- - - /** - * @expectedException FuzeWorks\Exception\UriException - */ - public function test_filter_uri_throws_error() - { - $this->uri->config->routing->enable_query_strings = false; - $this->uri->_set_permitted_uri_chars('a-z 0-9~%.:_\-'); - $segment = '$this()'; // filter_uri() accepts by reference - $this->uri->filter_uri($segment); - } - - // -------------------------------------------------------------------- - - public function test_segment() - { - $this->uri->segments = array(1 => 'controller'); - $this->assertEquals($this->uri->segment(1), 'controller'); - $this->assertEquals($this->uri->segment(2, 'default'), 'default'); - } - - // -------------------------------------------------------------------- - - public function test_rsegment() - { - $this->uri->rsegments = array(1 => 'method'); - $this->assertEquals($this->uri->rsegment(1), 'method'); - $this->assertEquals($this->uri->rsegment(2, 'default'), 'default'); - } - - // -------------------------------------------------------------------- - - public function test_uri_to_assoc() - { - $this->uri->segments = array('a', '1', 'b', '2', 'c', '3'); - - $this->assertEquals( - array('a' => '1', 'b' => '2', 'c' => '3'), - $this->uri->uri_to_assoc(1) - ); - - $this->assertEquals( - array('b' => '2', 'c' => '3'), - $this->uri->uri_to_assoc(3) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->segments = array('a', '1', 'b', '2', 'c'); - - $this->assertEquals( - array('a' => '1', 'b' => '2', 'c' => FALSE), - $this->uri->uri_to_assoc(1) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->segments = array('a', '1'); - - // test default - $this->assertEquals( - array('a' => '1', 'b' => FALSE), - $this->uri->uri_to_assoc(1, array('a', 'b')) - ); - } - - // -------------------------------------------------------------------- - - public function test_ruri_to_assoc() - { - $this->uri->rsegments = array('x', '1', 'y', '2', 'z', '3'); - - $this->assertEquals( - array('x' => '1', 'y' => '2', 'z' => '3'), - $this->uri->ruri_to_assoc(1) - ); - - $this->assertEquals( - array('y' => '2', 'z' => '3'), - $this->uri->ruri_to_assoc(3) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->rsegments = array('x', '1', 'y', '2', 'z'); - - $this->assertEquals( - array('x' => '1', 'y' => '2', 'z' => FALSE), - $this->uri->ruri_to_assoc(1) - ); - - $this->uri->keyval = array(); // reset cache - $this->uri->rsegments = array('x', '1'); - - // test default - $this->assertEquals( - array('x' => '1', 'y' => FALSE), - $this->uri->ruri_to_assoc(1, array('x', 'y')) - ); - } - - // -------------------------------------------------------------------- - - public function test_assoc_to_uri() - { - //$this->uri->config->set_item('uri_string_slashes', 'none'); - $this->assertEquals('a/1/b/2', $this->uri->assoc_to_uri(array('a' => '1', 'b' => '2'))); - } - - // -------------------------------------------------------------------- - - public function test_slash_segment() - { - $this->uri->segments[1] = 'segment'; - $this->uri->rsegments[1] = 'segment'; - - $this->assertEquals('/segment/', $this->uri->slash_segment(1, 'both')); - $this->assertEquals('/segment/', $this->uri->slash_rsegment(1, 'both')); - - $a = '/segment'; - $this->assertEquals('/segment', $this->uri->slash_segment(1, 'leading')); - $this->assertEquals('/segment', $this->uri->slash_rsegment(1, 'leading')); - - $this->assertEquals('segment/', $this->uri->slash_segment(1, 'trailing')); - $this->assertEquals('segment/', $this->uri->slash_rsegment(1, 'trailing')); - } - -} diff --git a/tests/core/core_utf8Test.php b/tests/core/core_utf8Test.php deleted file mode 100644 index 2e608e0..0000000 --- a/tests/core/core_utf8Test.php +++ /dev/null @@ -1,132 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class Utf8Test. - * - * Core testing suite, will test UTF8 class functionality - */ -class utf8Test extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - $this->factory = Factory::getInstance(); - - $this->factory->config->getConfig('main')->charset = 'UTF-8'; - $this->utf8 = new Mock_Core_Utf8(); - } - - // -------------------------------------------------------------------- - - /** - * __construct() test - * - * @covers FuzeWorks\Utf8::__construct - */ - public function test___construct() - { - if (defined('PREG_BAD_UTF8_ERROR') && (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) && strtoupper($this->factory->config->getConfig('main')->charset) === 'UTF-8') - { - $this->assertTrue(UTF8_ENABLED); - } - else - { - $this->assertFalse(UTF8_ENABLED); - } - } - - // -------------------------------------------------------------------- - - /** - * is_ascii() test - * - * Note: DO NOT move this below test_clean_string() - */ - public function test_is_ascii() - { - $this->assertTrue($this->utf8->is_ascii('foo bar')); - $this->assertFalse($this->utf8->is_ascii('тест')); - } - - // -------------------------------------------------------------------- - - /** - * clean_string() test - * - * @depends test_is_ascii - * @covers FuzeWorks\Utf8::clean_string - */ - public function test_clean_string() - { - $this->assertEquals('foo bar', $this->utf8->clean_string('foo bar')); - - $illegal_utf8 = "\xc0тест"; - if (MB_ENABLED) - { - $this->assertEquals('тест', $this->utf8->clean_string($illegal_utf8)); - } - elseif (ICONV_ENABLED) - { - // This is a known issue, iconv doesn't always work with //IGNORE - $this->assertTrue(in_array($this->utf8->clean_string($illegal_utf8), array('тест', ''), TRUE)); - } - else - { - $this->assertEquals($illegal_utf8, $this->utf8->clean_string($illegal_utf8)); - } - } - - // -------------------------------------------------------------------- - - /** - * convert_to_utf8() test - * - * @covers FuzeWorks\Utf8::convert_to_utf8 - */ - public function test_convert_to_utf8() - { - $this->markTestSkipped("Fails to work in the current condition"); - if (MB_ENABLED OR ICONV_ENABLED) - { - $this->assertEquals('тест', $this->utf8->convert_to_utf8('����', 'WINDOWS-1251')); - } - else - { - $this->assertFalse($this->utf8->convert_to_utf8('����', 'WINDOWS-1251')); - } - } -} diff --git a/tests/database/database_databaseTest.php b/tests/database/database_databaseTest.php deleted file mode 100644 index 6a1ef2d..0000000 --- a/tests/database/database_databaseTest.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2017, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 1.0.4 - * - * @version Version 1.0.4 - */ - -use FuzeWorks\Factory; -use FuzeWorks\Exception\DatabaseException; - -/** - * Class databaseTest. - * - * Core testing suite. Will test databases, querybuilders and frequently used drivers. - */ -class databaseTest extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - $this->factory = Factory::getInstance(); - } - - /** - * @expectedException FuzeWorks\Exception\DatabaseException - */ - public function testInvalidDb() - { - $this->factory->database->get('unknown://unknown:password@unknown/database'); - } - -} diff --git a/tests/events/event_layoutLoadEventTest.php b/tests/events/event_layoutLoadEventTest.php deleted file mode 100644 index 08c99d2..0000000 --- a/tests/events/event_layoutLoadEventTest.php +++ /dev/null @@ -1,110 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ -use FuzeWorks\Events; -use FuzeWorks\Factory; -use FuzeWorks\EventPriority; - -/** - * Class LayoutLoadEventTest. - */ -class layoutLoadEventTest extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - // Load the factory first - $this->factory = Factory::getInstance(); - } - - /** - * Check if the event is fired when it should be. - */ - public function test_basic() - { - $mock = $this->getMockBuilder(MockLayoutEventTest::class)->setMethods(['mockMethod'])->getMock(); - $mock->expects($this->once())->method('mockMethod'); - - Events::addListener(array($mock, 'mockMethod'), 'layoutLoadEvent', EventPriority::NORMAL); - - // And run the test - $this->factory->layout->get('home'); - } - - /** - * Intercept and change the event. - * - * @expectedException FuzeWorks\Exception\LayoutException - */ - public function test_change() - { - Events::addListener(array($this, 'listener_change'), 'layoutLoadEvent', EventPriority::NORMAL); - $this->factory->layout->get('home'); - } - - // Change title from new to other - public function listener_change($event) - { - - // This controller should not exist - $this->assertTrue(strpos($event->file, 'application'.DS.'Layout'.DS.'layout.home.php') !== false); - $this->assertTrue(strpos($event->directory, 'application'.DS.'Layout'.DS) !== false); - - // It should exist now - $event->file = $event->directory . 'layout.test.not_found'; - - return $event; - } - - /** - * Cancel events. - */ - public function test_cancel() - { - - // Listen for the event and cancel it - Events::addListener(array($this, 'listener_cancel'), 'layoutLoadEvent', EventPriority::NORMAL); - $this->assertFalse($this->factory->layout->get('home') === true); - } - - // Cancel all calls - public function listener_cancel($event) - { - $event->setCancelled(true); - return $event; - } -} - -class MockLayoutEventTest { - public function MockMethod() {} -} diff --git a/tests/helpers/helper_arrayHelperTest.php b/tests/helpers/helper_arrayHelperTest.php deleted file mode 100644 index 16ab940..0000000 --- a/tests/helpers/helper_arrayHelperTest.php +++ /dev/null @@ -1,83 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class ArrayHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class arrayHelperTest extends CoreTestAbstract -{ - - public $my_array = array( - 'foo' => 'bar', - 'sally' => 'jim', - 'maggie' => 'bessie', - 'herb' => 'cook' - ); - - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('array'); - } - - // ------------------------------------------------------------------------ - - public function test_element_with_existing_item() - { - $this->assertEquals(FALSE, element('testing', $this->my_array)); - $this->assertEquals('not set', element('testing', $this->my_array, 'not set')); - $this->assertEquals('bar', element('foo', $this->my_array)); - } - - // ------------------------------------------------------------------------ - - public function test_random_element() - { - // Send a string, not an array to random_element - $this->assertEquals('my string', random_element('my string')); - - // Test sending an array - $this->assertEquals(TRUE, in_array(random_element($this->my_array), $this->my_array)); - } - - // ------------------------------------------------------------------------ - - public function test_elements() - { - $this->assertEquals(TRUE, is_array(elements('test', $this->my_array))); - $this->assertEquals(TRUE, is_array(elements('foo', $this->my_array))); - } -} diff --git a/tests/helpers/helper_commonHelperTest.php b/tests/helpers/helper_commonHelperTest.php deleted file mode 100644 index 71943db..0000000 --- a/tests/helpers/helper_commonHelperTest.php +++ /dev/null @@ -1,112 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class CommonHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class commonHelperTest extends CoreTestAbstract -{ - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('common'); - } - - public function test_stringify_attributes() - { - $this->assertEquals(' class="foo" id="bar"', _stringify_attributes(array('class' => 'foo', 'id' => 'bar'))); - - $atts = new stdClass; - $atts->class = 'foo'; - $atts->id = 'bar'; - $this->assertEquals(' class="foo" id="bar"', _stringify_attributes($atts)); - - $atts = new stdClass; - $this->assertEquals('', _stringify_attributes($atts)); - - $this->assertEquals(' class="foo" id="bar"', _stringify_attributes('class="foo" id="bar"')); - - $this->assertEquals('', _stringify_attributes(array())); - } - - // ------------------------------------------------------------------------ - - public function test_stringify_js_attributes() - { - $this->assertEquals('width=800,height=600', _stringify_attributes(array('width' => '800', 'height' => '600'), TRUE)); - - $atts = new stdClass; - $atts->width = 800; - $atts->height = 600; - $this->assertEquals('width=800,height=600', _stringify_attributes($atts, TRUE)); - } - - // ------------------------------------------------------------------------ - - public function test_html_escape() - { - $this->assertEquals( - html_escape('Here is a string containing "quoted" text.'), - 'Here is a string containing "quoted" text.' - ); - - $this->assertEquals( - html_escape(array('associative' => 'and', array('multi' => 'dimentional'))), - array('associative' => 'and', array('multi' => 'dimentional')) - ); - - $this->assertEquals( - html_escape(array()), - array() - ); - } - - // ------------------------------------------------------------------------ - - public function test_is_php() - { - $this->assertTrue(is_php('1.2.0')); - $this->assertFalse(is_php('9999.9.9')); - } - - // ------------------------------------------------------------------------ - - public function test_get_mimes() - { - $this->assertFalse(empty(get_mimes())); - } - -} diff --git a/tests/helpers/helper_fileHelperTest.php b/tests/helpers/helper_fileHelperTest.php deleted file mode 100644 index c58f4f7..0000000 --- a/tests/helpers/helper_fileHelperTest.php +++ /dev/null @@ -1,185 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class FileHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class fileHelperTest extends CoreTestAbstract -{ - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('file'); - - vfsStreamWrapper::register(); - vfsStreamWrapper::setRoot(new vfsStreamDirectory('testDir')); - - $this->_test_dir = vfsStreamWrapper::getRoot(); - } - - // -------------------------------------------------------------------- - - public function test_read_file() - { - $this->assertFalse(read_file('does_not_exist')); - - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt')->withContent($content)->at($this->_test_dir); - - $this->assertEquals($content, read_file(vfsStream::url('my_file.txt'))); - } - - // -------------------------------------------------------------------- - - public function test_octal_permissions() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertEquals('777', octal_permissions($file->getPermissions())); - } - - // -------------------------------------------------------------------- - - /** - * More tests should happen here, since I'm not hitting the whole function. - */ - public function test_symbolic_permissions() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertEquals('urwxrwxrwx', symbolic_permissions($file->getPermissions())); - } - - // -------------------------------------------------------------------- - - public function test_get_mime_by_extension() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertEquals('text/plain', get_mime_by_extension(vfsStream::url('my_file.txt'))); - - // Test a mime with an array, such as png - $file = vfsStream::newFile('foo.png')->at($this->_test_dir); - - $this->assertEquals('image/png', get_mime_by_extension(vfsStream::url('foo.png'))); - - // Test a file not in the mimes array - $file = vfsStream::newFile('foo.blarfengar')->at($this->_test_dir); - - $this->assertFalse(get_mime_by_extension(vfsStream::url('foo.blarfengar'))); - } - - // -------------------------------------------------------------------- - - public function test_get_file_info() - { - // Test Bad File - $this->assertFalse(get_file_info('i_am_bad_boo')); - - // Test the rest - - // First pass in an array - $vals = array( - 'name', 'server_path', 'size', 'date', - 'readable', 'writable', 'executable', 'fileperms' - ); - - $this->_test_get_file_info($vals); - - // Test passing in vals as a string. - $this->_test_get_file_info(implode(', ', $vals)); - } - - private function _test_get_file_info($vals) - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - $last_modified = time() - 86400; - - $file = vfsStream::newFile('my_file.txt', 0777) - ->withContent($content) - ->lastModified($last_modified) - ->at($this->_test_dir); - - $ret_values = array( - 'name' => 'my_file.txt', - 'server_path' => 'vfs://my_file.txt', - 'size' => 57, - 'date' => $last_modified, - 'readable' => TRUE, - 'writable' => TRUE, - 'executable' => TRUE, - 'fileperms' => 33279 - ); - - $info = get_file_info(vfsStream::url('my_file.txt'), $vals); - - foreach ($info as $k => $v) - { - $this->assertEquals($ret_values[$k], $v); - } - } - - // -------------------------------------------------------------------- - - public function test_write_file() - { - $content = 'Jack and Jill went up the mountain to fight a billy goat.'; - - $file = vfsStream::newFile('write.txt', 0777) - ->withContent('') - ->lastModified(time() - 86400) - ->at($this->_test_dir); - - $this->assertTrue(write_file(vfsStream::url('write.txt'), $content)); - } - -} diff --git a/tests/helpers/helper_xmlHelperTest.php b/tests/helpers/helper_xmlHelperTest.php deleted file mode 100644 index 6d25a2b..0000000 --- a/tests/helpers/helper_xmlHelperTest.php +++ /dev/null @@ -1,52 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class XmlHelperTest. - * - * Helpers testing suite, will test specific helper - */ -class xmlHelperTest extends CoreTestAbstract -{ - public function setUp() - { - // Load Helper - Factory::getInstance()->helpers->load('xml'); - } - - public function test_xml_convert() - { - $this->assertEquals('<tag>my & test - </tag>', xml_convert('my & test - ')); - } -} diff --git a/tests/layout/testCustomEngine/layout.test.test b/tests/layout/testCustomEngine/layout.test.test deleted file mode 100644 index e69de29..0000000 diff --git a/tests/layout/testEngineVariables/layout.json.json b/tests/layout/testEngineVariables/layout.json.json deleted file mode 100644 index e69de29..0000000 diff --git a/tests/layout/testEngineVariables/layout.php.php b/tests/layout/testEngineVariables/layout.php.php deleted file mode 100644 index 73714f0..0000000 --- a/tests/layout/testEngineVariables/layout.php.php +++ /dev/null @@ -1,2 +0,0 @@ -_get_params($params); - } - - // -------------------------------------------------------------------- - - /** - * get_key() - * - * Allows checking for key changes. - */ - public function get_key() - { - return $this->_key; - } - - // -------------------------------------------------------------------- - - /** - * __driver_get_handle() - * - * Allows checking for _mcrypt_get_handle(), _openssl_get_handle() - */ - public function __driver_get_handle($driver, $cipher, $mode) - { - return $this->{'_'.$driver.'_get_handle'}($cipher, $mode); - } - -} \ No newline at end of file diff --git a/tests/libraries/library_encryptionTest.php b/tests/libraries/library_encryptionTest.php deleted file mode 100644 index e561489..0000000 --- a/tests/libraries/library_encryptionTest.php +++ /dev/null @@ -1,423 +0,0 @@ -. - * - * @author TechFuze - * @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net) - * @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/) - * @license http://opensource.org/licenses/GPL-3.0 GPLv3 License - * - * @link http://techfuze.net/fuzeworks - * @since Version 0.0.1 - * - * @version Version 1.0.0 - */ - -use FuzeWorks\Factory; - -/** - * Class FactoryTest. - * - * Will test the FuzeWorks Factory. - */ -class encryptionTest extends CoreTestAbstract -{ - - protected $factory; - - public function setUp() - { - $this->factory = Factory::getInstance(); - $this->factory->libraries->get('encryption'); - require_once('encryption/mock_encryption.php'); - $this->encryption = new Mock_Libraries_Encryption(); - } - - // -------------------------------------------------------------------- - - /** - * __construct test - * - * Covers behavior with $config['encryption_key'] set or not - */ - public function test___construct() - { - // Assume no configuration from set_up() - $this->assertNull($this->encryption->get_key()); - - // Try with an empty value - $this->factory->config->getConfig('encryption')->encryption_key = ''; - $this->encrypt = new Mock_Libraries_Encryption(); - $this->assertNull($this->encrypt->get_key()); - - $this->factory->config->getConfig('encryption')->encryption_key = str_repeat("\x0", 16); - $this->encrypt = new Mock_Libraries_Encryption(); - $this->assertEquals(str_repeat("\x0", 16), $this->encrypt->get_key()); - } - - // -------------------------------------------------------------------- - - /** - * hkdf() test - * - * Applies test vectors described in Appendix A(1-3) RFC5869. - * Described vectors 4-7 SHA-1, which we don't support and are - * therefore excluded. - * - * Because our implementation is a single method instead of being - * split into hkdf_extract() and hkdf_expand(), we cannot test for - * the PRK value. As long as the OKM is correct though, it's fine. - * - * @link https://tools.ietf.org/rfc/rfc5869.txt - */ - public function test_hkdf() - { - $vectors = array( - // A.1: Basic test case with SHA-256 - array( - 'digest' => 'sha256', - 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - 'salt' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c", - 'length' => 42, - 'info' => "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9", - // 'prk' => "\x07\x77\x09\x36\x2c\x2e\x32\xdf\x0d\xdc\x3f\x0d\xc4\x7b\xba\x63\x90\xb6\xc7\x3b\xb5\x0f\x9c\x31\x22\xec\x84\x4a\xd7\xc2\xb3\xe5", - 'okm' => "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a\x90\x43\x4f\x64\xd0\x36\x2f\x2a\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf\x34\x00\x72\x08\xd5\xb8\x87\x18\x58\x65" - ), - // A.2: Test with SHA-256 and longer inputs/outputs - array( - 'digest' => 'sha256', - 'ikm' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", - 'salt' => "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", - 'length' => 82, - 'info' => "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", - // 'prk' => "\x06\xa6\xb8\x8c\x58\x53\x36\x1a\x06\x10\x4c\x9c\xeb\x35\xb4\x5c\xef\x76\x00\x14\x90\x46\x71\x01\x4a\x19\x3f\x40\xc1\x5f\xc2\x44", - 'okm' => "\xb1\x1e\x39\x8d\xc8\x03\x27\xa1\xc8\xe7\xf7\x8c\x59\x6a\x49\x34\x4f\x01\x2e\xda\x2d\x4e\xfa\xd8\xa0\x50\xcc\x4c\x19\xaf\xa9\x7c\x59\x04\x5a\x99\xca\xc7\x82\x72\x71\xcb\x41\xc6\x5e\x59\x0e\x09\xda\x32\x75\x60\x0c\x2f\x09\xb8\x36\x77\x93\xa9\xac\xa3\xdb\x71\xcc\x30\xc5\x81\x79\xec\x3e\x87\xc1\x4c\x01\xd5\xc1\xf3\x43\x4f\x1d\x87", - ), - // A.3: Test with SHA-256 and zero-length salt/info - array( - 'digest' => 'sha256', - 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - 'salt' => '', - 'length' => 42, - 'info' => '', - // 'prk' => "\x19\xef\x24\xa3\x2c\x71\x7b\x16\x7f\x33\xa9\x1d\x6f\x64\x8b\xdf\x96\x59\x67\x76\xaf\xdb\x63\x77\xac\x43\x4c\x1c\x29\x3c\xcb\x04", - 'okm' => "\x8d\xa4\xe7\x75\xa5\x63\xc1\x8f\x71\x5f\x80\x2a\x06\x3c\x5a\x31\xb8\xa1\x1f\x5c\x5e\xe1\x87\x9e\xc3\x45\x4e\x5f\x3c\x73\x8d\x2d\x9d\x20\x13\x95\xfa\xa4\xb6\x1a\x96\xc8", - ) - ); - - foreach ($vectors as $test) - { - $this->assertEquals( - $test['okm'], - $this->encryption->hkdf( - $test['ikm'], - $test['digest'], - $test['salt'], - $test['length'], - $test['info'] - ) - ); - } - - // Test default length, it must match the digest size - $this->assertEquals(64, strlen($this->encryption->hkdf('foobar', 'sha512'))); - - // Test maximum length (RFC5869 says that it must be up to 255 times the digest size) - $this->assertEquals(12240, strlen($this->encryption->hkdf('foobar', 'sha384', NULL, 48 * 255))); - $this->assertFalse($this->encryption->hkdf('foobar', 'sha224', NULL, 28 * 255 + 1)); - - // CI-specific test for an invalid digest - $this->assertFalse($this->encryption->hkdf('fobar', 'sha1')); - } - - // -------------------------------------------------------------------- - - /** - * _get_params() test - */ - public function test__get_params() - { - $key = str_repeat("\x0", 16); - - // Invalid custom parameters - $params = array( - // No cipher, mode or key - array('cipher' => 'aes-128', 'mode' => 'cbc'), - array('cipher' => 'aes-128', 'key' => $key), - array('mode' => 'cbc', 'key' => $key), - // No HMAC key or not a valid digest - array('cipher' => 'aes-128', 'mode' => 'cbc', 'key' => $key), - array('cipher' => 'aes-128', 'mode' => 'cbc', 'key' => $key, 'hmac_digest' => 'sha1', 'hmac_key' => $key), - // Invalid mode - array('cipher' => 'aes-128', 'mode' => 'foo', 'key' => $key, 'hmac_digest' => 'sha256', 'hmac_key' => $key) - ); - - for ($i = 0, $c = count($params); $i < $c; $i++) - { - $this->assertFalse($this->encryption->__get_params($params[$i])); - } - - // Valid parameters - $params = array( - 'cipher' => 'aes-128', - 'mode' => 'cbc', - 'key' => str_repeat("\x0", 16), - 'hmac_key' => str_repeat("\x0", 16) - ); - - $this->assertTrue(is_array($this->encryption->__get_params($params))); - - $params['base64'] = TRUE; - $params['hmac_digest'] = 'sha512'; - - // Including all parameters - $params = array( - 'cipher' => 'aes-128', - 'mode' => 'cbc', - 'key' => str_repeat("\x0", 16), - 'raw_data' => TRUE, - 'hmac_key' => str_repeat("\x0", 16), - 'hmac_digest' => 'sha256' - ); - - $output = $this->encryption->__get_params($params); - unset($output['handle'], $output['cipher'], $params['raw_data'], $params['cipher']); - $params['base64'] = FALSE; - $this->assertEquals($params, $output); - - // HMAC disabled - unset($params['hmac_key'], $params['hmac_digest']); - $params['hmac'] = $params['raw_data'] = FALSE; - $params['cipher'] = 'aes-128'; - $output = $this->encryption->__get_params($params); - unset($output['handle'], $output['cipher'], $params['hmac'], $params['raw_data'], $params['cipher']); - $params['base64'] = TRUE; - $params['hmac_digest'] = $params['hmac_key'] = NULL; - $this->assertEquals($params, $output); - } - - // -------------------------------------------------------------------- - - /** - * initialize(), encrypt(), decrypt() test - * - * Testing the three methods separately is not realistic as they are - * designed to work together. A more thorough test for initialize() - * though is the OpenSSL/MCrypt compatibility test. - * - * @depends test_hkdf - * @depends test__get_params - */ - public function test_initialize_encrypt_decrypt() - { - $message = 'This is a plain-text message.'; - $key = "\xd0\xc9\x08\xc4\xde\x52\x12\x6e\xf8\xcc\xdb\x03\xea\xa0\x3a\x5c"; - - // Default state (AES-128/Rijndael-128 in CBC mode) - $this->encryption->initialize(array('key' => $key)); - - // Was the key properly set? - $this->assertEquals($key, $this->encryption->get_key()); - - $this->assertEquals($message, $this->encryption->decrypt($this->encryption->encrypt($message))); - - // Try DES in ECB mode, just for the sake of changing stuff - $this->encryption->initialize(array('cipher' => 'des', 'mode' => 'ecb', 'key' => substr($key, 0, 8))); - $this->assertEquals($message, $this->encryption->decrypt($this->encryption->encrypt($message))); - } - - // -------------------------------------------------------------------- - - /** - * encrypt(), decrypt test with custom parameters - * - * @depends test__get_params - */ - public function test_encrypt_decrypt_custom() - { - $message = 'Another plain-text message.'; - - // A random invalid parameter - $this->assertFalse($this->encryption->encrypt($message, array('foo'))); - $this->assertFalse($this->encryption->decrypt($message, array('foo'))); - - // No HMAC, binary output - $params = array( - 'cipher' => 'tripledes', - 'mode' => 'cfb', - 'key' => str_repeat("\x1", 16), - 'base64' => FALSE, - 'hmac' => FALSE - ); - - $ciphertext = $this->encryption->encrypt($message, $params); - - $this->assertEquals($message, $this->encryption->decrypt($ciphertext, $params)); - } - - // -------------------------------------------------------------------- - - /** - * _mcrypt_get_handle() test - */ - public function test__mcrypt_get_handle() - { - if ($this->encryption->drivers['mcrypt'] === FALSE) - { - return $this->markTestSkipped('Cannot test MCrypt because it is not available.'); - } - - $this->assertTrue(is_resource($this->encryption->__driver_get_handle('mcrypt', 'rijndael-128', 'cbc'))); - } - - // -------------------------------------------------------------------- - - /** - * _openssl_get_handle() test - */ - public function test__openssl_mcrypt_get_handle() - { - if ($this->encryption->drivers['openssl'] === FALSE) - { - return $this->markTestSkipped('Cannot test OpenSSL because it is not available.'); - } - - $this->assertEquals('aes-128-cbc', $this->encryption->__driver_get_handle('openssl', 'aes-128', 'cbc')); - $this->assertEquals('rc4-40', $this->encryption->__driver_get_handle('openssl', 'rc4-40', 'stream')); - } - - // -------------------------------------------------------------------- - - /** - * OpenSSL/MCrypt portability test - * - * Amongst the obvious stuff, _cipher_alias() is also tested here. - */ - public function test_portability() - { - if ( ! $this->encryption->drivers['mcrypt'] OR ! $this->encryption->drivers['openssl']) - { - $this->markTestSkipped('Both MCrypt and OpenSSL support are required for portability tests.'); - return; - } - - $message = 'This is a message encrypted via MCrypt and decrypted via OpenSSL, or vice-versa.'; - - // Format is: , , - $portable = array( - array('aes-128', 'cbc', 16), - array('aes-128', 'cfb', 16), - array('aes-128', 'cfb8', 16), - array('aes-128', 'ofb', 16), - array('aes-128', 'ecb', 16), - array('aes-128', 'ctr', 16), - array('aes-192', 'cbc', 24), - array('aes-192', 'cfb', 24), - array('aes-192', 'cfb8', 24), - array('aes-192', 'ofb', 24), - array('aes-192', 'ecb', 24), - array('aes-192', 'ctr', 24), - array('aes-256', 'cbc', 32), - array('aes-256', 'cfb', 32), - array('aes-256', 'cfb8', 32), - array('aes-256', 'ofb', 32), - array('aes-256', 'ecb', 32), - array('aes-256', 'ctr', 32), - array('des', 'cbc', 7), - array('des', 'cfb', 7), - array('des', 'cfb8', 7), - array('des', 'ofb', 7), - array('des', 'ecb', 7), - array('tripledes', 'cbc', 7), - array('tripledes', 'cfb', 7), - array('tripledes', 'cfb8', 7), - array('tripledes', 'ofb', 7), - array('tripledes', 'cbc', 14), - array('tripledes', 'cfb', 14), - array('tripledes', 'cfb8', 14), - array('tripledes', 'ofb', 14), - array('tripledes', 'cbc', 21), - array('tripledes', 'cfb', 21), - array('tripledes', 'cfb8', 21), - array('tripledes', 'ofb', 21), - array('blowfish', 'cbc', 16), - array('blowfish', 'cfb', 16), - array('blowfish', 'ofb', 16), - array('blowfish', 'ecb', 16), - array('blowfish', 'cbc', 56), - array('blowfish', 'cfb', 56), - array('blowfish', 'ofb', 56), - array('blowfish', 'ecb', 56), - array('cast5', 'cbc', 11), - array('cast5', 'cfb', 11), - array('cast5', 'ofb', 11), - array('cast5', 'ecb', 11), - array('cast5', 'cbc', 16), - array('cast5', 'cfb', 16), - array('cast5', 'ofb', 16), - array('cast5', 'ecb', 16), - array('rc4', 'stream', 5), - array('rc4', 'stream', 8), - array('rc4', 'stream', 16), - array('rc4', 'stream', 32), - array('rc4', 'stream', 64), - array('rc4', 'stream', 128), - array('rc4', 'stream', 256) - ); - $driver_index = array('mcrypt', 'openssl'); - - foreach ($portable as &$test) - { - // Add some randomness to the selected driver - $driver = mt_rand(0,1); - $params = array( - 'driver' => $driver_index[$driver], - 'cipher' => $test[0], - 'mode' => $test[1], - 'key' => openssl_random_pseudo_bytes($test[2]) - ); - - $this->encryption->initialize($params); - $ciphertext = $this->encryption->encrypt($message); - - $driver = (int) ! $driver; - $params['driver'] = $driver_index[$driver]; - - $this->encryption->initialize($params); - $this->assertEquals($message, $this->encryption->decrypt($ciphertext)); - } - } - - // -------------------------------------------------------------------- - - /** - * __get() test - */ - public function test_magic_get() - { - $this->assertNull($this->encryption->foo); - $this->assertEquals(array('mcrypt', 'openssl'), array_keys($this->encryption->drivers)); - - // 'stream' mode is translated into an empty string for OpenSSL - $this->encryption->initialize(array('cipher' => 'rc4', 'mode' => 'stream')); - $this->assertEquals('stream', $this->encryption->mode); - } - -} diff --git a/tests/libraries/testCoreLibraries/Extended.php b/tests/libraries/testCoreLibraries/Extended.php new file mode 100644 index 0000000..a5b0ed1 --- /dev/null +++ b/tests/libraries/testCoreLibraries/Extended.php @@ -0,0 +1,8 @@ +_allow_get_array = ($this->factory->config->getConfig('routing')->allow_get_array === TRUE); - $this->_enable_xss = ($this->factory->config->getConfig('security')->global_xss_filtering === TRUE); - $this->_enable_csrf = ($this->factory->config->getConfig('security')->csrf_protection === TRUE); - - // Assign Security and Utf8 classes - $this->security = $security; - $this->uni = $utf8; - - // Sanitize global arrays - $this->_sanitize_globals(); - } - - public function fetch_from_array($array, $index = '', $xss_clean = FALSE) - { - return parent::_fetch_from_array($array, $index, $xss_clean); - } - - /** - * Lie about being a CLI request - * - * We take advantage of this in libraries/Session_test - */ - public function is_cli_request() - { - return FALSE; - } - - public function __set($name, $value) - { - if ($name === 'ip_address') - { - $this->ip_address = $value; - } - } - -} \ No newline at end of file diff --git a/tests/mocks/core/security.php b/tests/mocks/core/security.php deleted file mode 100644 index e3eab57..0000000 --- a/tests/mocks/core/security.php +++ /dev/null @@ -1,37 +0,0 @@ -{'_'.$property}) ? $this->{'_'.$property} : NULL; - } - - public function remove_evil_attributes($str, $is_image) - { - return $this->_remove_evil_attributes($str, $is_image); - } - - // Override inaccessible protected method - public function __call($method, $params) - { - if (is_callable(array($this, '_'.$method))) - { - return call_user_func_array(array($this, '_'.$method), $params); - } - - throw new BadMethodCallException('Method '.$method.' was not found'); - } - -} \ No newline at end of file diff --git a/tests/mocks/core/uri.php b/tests/mocks/core/uri.php deleted file mode 100644 index e257c24..0000000 --- a/tests/mocks/core/uri.php +++ /dev/null @@ -1,31 +0,0 @@ -config = Factory::getInstance()->config; - - // set predictable config values - $this->config->main->index_page = 'index.php'; - $this->config->main->base_url = 'http://example.com/'; - $this->config->main->application_prefix = 'MY_'; - $this->config->routing->enable_query_strings = false; - $this->config->routing->permitted_uri_chars = 'a-z 0-9~%.:_\-'; - - - if ($this->config->routing->enable_query_strings !== TRUE OR is_cli()) - { - $this->_permitted_uri_chars = $this->config->routing->permitted_uri_chars; - } - } - - public function _set_permitted_uri_chars($value) - { - $this->_permitted_uri_chars = $value; - } - -} \ No newline at end of file diff --git a/tests/mocks/core/utf8.php b/tests/mocks/core/utf8.php deleted file mode 100644 index 4a9a690..0000000 --- a/tests/mocks/core/utf8.php +++ /dev/null @@ -1,21 +0,0 @@ -