This commit is contained in:
Alex Tselegidis 2016-04-26 21:34:03 +02:00
commit ebfd04172c
264 changed files with 42997 additions and 26685 deletions

15
.gitignore vendored
View file

@ -1,7 +1,8 @@
/.tmp-package
/composer
/doc
/easyappointments.zip
/node_modules
/src/application/logs/*
/src/config.php
.tmp-package
composer
doc
easyappointments.zip
node_modules
src/application/logs/*
!src/application/logs/index.html
src/config.php

View file

@ -12,7 +12,7 @@
"vendor-dir": "composer"
},
"require-dev": {
"apigen/apigen": "~4.1"
"codeigniter/framework": "^3.0"
},
"require": {
"gregwar/captcha": "^1.1",

39
composer.lock generated
View file

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "9376f6dce837c49ec0467c91adc7dd0e",
"content-hash": "f1caee945fa2c3ffed8c56511645dce9",
"hash": "c484aff175b14ee6c9810d6f4476c3c9",
"content-hash": "066f48bf5bdce6c78e3e440b892865f2",
"packages": [
{
"name": "gregwar/captcha",
@ -117,7 +117,40 @@
"time": "2015-11-01 10:15:28"
}
],
"packages-dev": null,
"packages-dev": [
{
"name": "codeigniter/framework",
"version": "3.0.6",
"source": {
"type": "git",
"url": "https://github.com/bcit-ci/CodeIgniter.git",
"reference": "8082544c5b4b33175790f505587e202e3ca9e488"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/8082544c5b4b33175790f505587e202e3ca9e488",
"reference": "8082544c5b4b33175790f505587e202e3ca9e488",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"require-dev": {
"mikey179/vfsstream": "1.1.*"
},
"suggest": {
"paragonie/random_compat": "Provides better randomness in PHP 5.x"
},
"type": "project",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "The CodeIgniter framework",
"homepage": "https://codeigniter.com",
"time": "2016-03-21 16:26:30"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],

View file

@ -17,7 +17,7 @@ gulp.task('composer', function() {
'!./src/application/third_party/index.html',
]);
exec('composer install --no-dev --prefer-dist', function (err, stdout, stderr) {
exec('composer update && composer install --prefer-dist', function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
});
@ -27,7 +27,8 @@ gulp.task('composer', function() {
'!composer/**/demo{,/**}',
'!composer/**/{demo,docs,examples,test,extras,language}{,/**}',
'!composer/**/{composer.json,composer.lock,.gitignore}',
'!composer/**/{*.yml,*.md}'
'!composer/**/{*.yml,*.md}',
'!composer/codeigniter{,/**}'
])
.pipe(gulp.dest('./src/application/third_party/'));
});

View file

@ -6,12 +6,11 @@
|--------------------------------------------------------------------------
|
| Declare some of the global config values of Easy!Appointments.
| the global "config" variable.
|
*/
$config['ea_version'] = '1.2'; // This must be changed manually.
$config['ea_release_title'] = 'Dev'; // Leave empty for no title or add BETA, TEST etc ...
$config['ea_google_sync_feature'] = Config::GOOGLE_SYNC_FEATURE;
$config['version'] = '1.2'; // This must be changed manually.
$config['release_label'] = 'Dev'; // Leave empty for no title or add Alpha, Beta etc ...
$config['google_sync_feature'] = Config::GOOGLE_SYNC_FEATURE;
/*
|--------------------------------------------------------------------------
@ -291,15 +290,13 @@ $config['encryption_key'] = Config::BASE_URL;
| 'sess_time_to_update' = how many seconds between CI refreshing Session Information
|
*/
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = FALSE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = NULL;
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
/*
|--------------------------------------------------------------------------

View file

@ -46,12 +46,12 @@
*/
$active_group = 'default';
$active_record = TRUE;
$query_builder = TRUE;
$db['default']['hostname'] = Config::DB_HOST;
$db['default']['username'] = Config::DB_USERNAME;
$db['default']['password'] = Config::DB_PASSWORD;
$db['default']['database'] = Config::DB_NAME;
$db['default']['username'] = Config::DB_USERNAME;
$db['default']['password'] = Config::DB_PASSWORD;
$db['default']['database'] = Config::DB_NAME;
$db['default']['dbdriver'] = 'mysqli';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
@ -66,4 +66,4 @@ $db['default']['stricton'] = FALSE;
/* End of file database.php */
/* Location: ./application/config/database.php */
/* Location: ./application/config/database.php */

View file

@ -1,4 +1,6 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
| -------------------------------------------------------------------
| MIME TYPES
@ -7,100 +9,159 @@
| Upload class to help identify allowed file types.
|
*/
$mimes = array( 'hqx' => 'application/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'),
'bin' => 'application/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' => 'application/x-photoshop',
'so' => 'application/octet-stream',
'sea' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => array('application/pdf', 'application/x-download'),
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'),
'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'),
'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',
'php' => 'application/x-httpd-php',
'php4' => 'application/x-httpd-php',
'php3' => 'application/x-httpd-php',
'phtml' => 'application/x-httpd-php',
'phps' => 'application/x-httpd-php-source',
'js' => 'application/x-javascript',
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar',
'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
'aif' => 'audio/x-aiff',
'aiff' => 'audio/x-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-windows-bmp'),
'gif' => 'image/gif',
'jpeg' => array('image/jpeg', 'image/pjpeg'),
'jpg' => array('image/jpeg', 'image/pjpeg'),
'jpe' => array('image/jpeg', 'image/pjpeg'),
'png' => array('image/png', 'image/x-png'),
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'css' => 'text/css',
'html' => 'text/html',
'htm' => 'text/html',
'shtml' => 'text/html',
'txt' => 'text/plain',
'text' => 'text/plain',
'log' => array('text/plain', 'text/x-log'),
'rtx' => 'text/richtext',
'rtf' => 'text/rtf',
'xml' => 'text/xml',
'xsl' => 'text/xml',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'doc' => 'application/msword',
'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'),
'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip'),
'word' => array('application/msword', 'application/octet-stream'),
'xl' => 'application/excel',
'eml' => 'message/rfc822',
'json' => array('application/json', 'text/json')
);
/* End of file mimes.php */
/* Location: ./application/config/mimes.php */
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')
);

View file

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitc1b442ad6654c006bdaf24db72724a82::getLoader();
return ComposerAutoloaderInit643d16bb26f1ca0b505db35afcc43aff::getLoader();

View file

@ -1,5 +1,5 @@
Copyright (c) 2015 Nils Adermann, Jordi Boggiano
Copyright (c) 2016 Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitc1b442ad6654c006bdaf24db72724a82
class ComposerAutoloaderInit643d16bb26f1ca0b505db35afcc43aff
{
private static $loader;
@ -19,9 +19,9 @@ class ComposerAutoloaderInitc1b442ad6654c006bdaf24db72724a82
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitc1b442ad6654c006bdaf24db72724a82', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit643d16bb26f1ca0b505db35afcc43aff', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitc1b442ad6654c006bdaf24db72724a82', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit643d16bb26f1ca0b505db35afcc43aff', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {

View file

@ -51,17 +51,17 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v5.2.13",
"version_normalized": "5.2.13.0",
"version": "v5.2.14",
"version_normalized": "5.2.14.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "45df3a88f7f46071e10d0b600f228d19f95911b3"
"reference": "e774bc9152de85547336e22b8926189e582ece95"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/45df3a88f7f46071e10d0b600f228d19f95911b3",
"reference": "45df3a88f7f46071e10d0b600f228d19f95911b3",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e774bc9152de85547336e22b8926189e582ece95",
"reference": "e774bc9152de85547336e22b8926189e582ece95",
"shasum": ""
},
"require": {
@ -72,9 +72,10 @@
"phpunit/phpunit": "4.7.*"
},
"suggest": {
"league/oauth2-client": "Needed for Gmail's XOAUTH2 authentication system"
"league/oauth2-client": "Needed for XOAUTH2 authentication",
"league/oauth2-google": "Needed for Gmail XOAUTH2"
},
"time": "2015-09-14 09:18:12",
"time": "2015-11-01 10:15:28",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -110,5 +111,39 @@
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP"
},
{
"name": "codeigniter/framework",
"version": "3.0.6",
"version_normalized": "3.0.6.0",
"source": {
"type": "git",
"url": "https://github.com/bcit-ci/CodeIgniter.git",
"reference": "8082544c5b4b33175790f505587e202e3ca9e488"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/8082544c5b4b33175790f505587e202e3ca9e488",
"reference": "8082544c5b4b33175790f505587e202e3ca9e488",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"require-dev": {
"mikey179/vfsstream": "1.1.*"
},
"suggest": {
"paragonie/random_compat": "Provides better randomness in PHP 5.x"
},
"time": "2016-03-21 16:26:30",
"type": "project",
"installation-source": "dist",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "The CodeIgniter framework",
"homepage": "https://codeigniter.com"
}
]

View file

@ -1 +1 @@
5.2.13
5.2.14

File diff suppressed because it is too large Load diff

View file

@ -27,38 +27,38 @@ class PHPMailerOAuth extends PHPMailer
{
/**
* The OAuth user's email address
* @type string
* @var string
*/
public $oauthUserEmail = '';
/**
* The OAuth refresh token
* @type string
* @var string
*/
public $oauthRefreshToken = '';
/**
* The OAuth client ID
* @type string
* @var string
*/
public $oauthClientId = '';
/**
* The OAuth client secret
* @type string
* @var string
*/
public $oauthClientSecret = '';
/**
* An instance of the OAuth class.
* @type OAuth
* An instance of the PHPMailerOAuthGoogle class.
* @var PHPMailerOAuthGoogle
* @access protected
*/
protected $oauth = null;
/**
* Get an OAuth instance to use.
* @return OAuth
* Get a PHPMailerOAuthGoogle instance to use.
* @return PHPMailerOAuthGoogle
*/
public function getOAUTHInstance()
{
@ -79,19 +79,18 @@ class PHPMailerOAuth extends PHPMailer
* @param array $options An array of options compatible with stream_context_create()
* @uses SMTP
* @access public
* @throws phpmailerException
* @return boolean
* @return bool
*/
public function smtpConnect($options = array())
{
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}
if (is_null($this->oauth)) {
$this->oauth = $this->getOAUTHInstance();
}
// Already connected?
if ($this->smtp->connected()) {
return true;

View file

@ -30,7 +30,13 @@ class PHPMailerOAuthGoogle
private $oauthRefreshToken = '';
private $oauthClientId = '';
private $oauthClientSecret = '';
/**
* @param string $UserEmail
* @param string $ClientSecret
* @param string $ClientId
* @param string $RefreshToken
*/
public function __construct(
$UserEmail,
$ClientSecret,
@ -49,19 +55,19 @@ class PHPMailerOAuthGoogle
'clientSecret' => $this->oauthClientSecret
]);
}
private function getGrant()
{
return new \League\OAuth2\Client\Grant\RefreshToken();
}
private function getToken()
{
$provider = $this->getProvider();
$grant = $this->getGrant();
return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);
}
public function getOauth64()
{
$token = $this->getToken();

View file

@ -31,28 +31,28 @@ class POP3
{
/**
* The POP3 PHPMailer Version number.
* @type string
* @var string
* @access public
*/
public $Version = '5.2.13';
public $Version = '5.2.14';
/**
* Default POP3 port number.
* @type integer
* @var integer
* @access public
*/
public $POP3_PORT = 110;
/**
* Default timeout in seconds.
* @type integer
* @var integer
* @access public
*/
public $POP3_TIMEOUT = 30;
/**
* POP3 Carriage Return + Line Feed.
* @type string
* @var string
* @access public
* @deprecated Use the constant instead
*/
@ -61,66 +61,66 @@ class POP3
/**
* Debug display level.
* Options: 0 = no, 1+ = yes
* @type integer
* @var integer
* @access public
*/
public $do_debug = 0;
/**
* POP3 mail server hostname.
* @type string
* @var string
* @access public
*/
public $host;
/**
* POP3 port number.
* @type integer
* @var integer
* @access public
*/
public $port;
/**
* POP3 Timeout Value in seconds.
* @type integer
* @var integer
* @access public
*/
public $tval;
/**
* POP3 username
* @type string
* @var string
* @access public
*/
public $username;
/**
* POP3 password.
* @type string
* @var string
* @access public
*/
public $password;
/**
* Resource handle for the POP3 connection socket.
* @type resource
* @access private
* @var resource
* @access protected
*/
private $pop_conn;
protected $pop_conn;
/**
* Are we connected?
* @type boolean
* @access private
* @var boolean
* @access protected
*/
private $connected = false;
protected $connected = false;
/**
* Error container.
* @type array
* @access private
* @var array
* @access protected
*/
private $errors = array();
protected $errors = array();
/**
* Line break constant
@ -310,9 +310,9 @@ class POP3
* $size is the maximum number of bytes to retrieve
* @param integer $size
* @return string
* @access private
* @access protected
*/
private function getResponse($size = 128)
protected function getResponse($size = 128)
{
$response = fgets($this->pop_conn, $size);
if ($this->do_debug >= 1) {
@ -325,9 +325,9 @@ class POP3
* Send raw data to the POP3 server.
* @param string $string
* @return integer
* @access private
* @access protected
*/
private function sendString($string)
protected function sendString($string)
{
if ($this->pop_conn) {
if ($this->do_debug >= 2) { //Show client messages when debug >= 2
@ -343,9 +343,9 @@ class POP3
* Looks for for +OK or -ERR.
* @param string $string
* @return boolean
* @access private
* @access protected
*/
private function checkResponse($string)
protected function checkResponse($string)
{
if (substr($string, 0, 3) !== '+OK') {
$this->setError(array(
@ -363,8 +363,9 @@ class POP3
* Add an error to the internal error store.
* Also display debug output if it's enabled.
* @param $error
* @access protected
*/
private function setError($error)
protected function setError($error)
{
$this->errors[] = $error;
if ($this->do_debug >= 1) {
@ -376,15 +377,24 @@ class POP3
}
}
/**
* Get an array of error messages, if any.
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* POP3 connection error handler.
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
* @access private
* @access protected
*/
private function catchWarning($errno, $errstr, $errfile, $errline)
protected function catchWarning($errno, $errstr, $errfile, $errline)
{
$this->setError(array(
'error' => "Connecting to the POP3 server raised a PHP warning: ",

View file

@ -28,25 +28,25 @@ class SMTP
{
/**
* The PHPMailer SMTP version number.
* @type string
* @var string
*/
const VERSION = '5.2.13';
const VERSION = '5.2.14';
/**
* SMTP line break constant.
* @type string
* @var string
*/
const CRLF = "\r\n";
/**
* The SMTP port to use if one is not specified.
* @type integer
* @var integer
*/
const DEFAULT_SMTP_PORT = 25;
/**
* The maximum line length allowed by RFC 2822 section 2.1.1
* @type integer
* @var integer
*/
const MAX_LINE_LENGTH = 998;
@ -77,15 +77,15 @@ class SMTP
/**
* The PHPMailer SMTP Version number.
* @type string
* @var string
* @deprecated Use the `VERSION` constant instead
* @see SMTP::VERSION
*/
public $Version = '5.2.13';
public $Version = '5.2.14';
/**
* SMTP server port number.
* @type integer
* @var integer
* @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead
* @see SMTP::DEFAULT_SMTP_PORT
*/
@ -93,7 +93,7 @@ class SMTP
/**
* SMTP reply line ending.
* @type string
* @var string
* @deprecated Use the `CRLF` constant instead
* @see SMTP::CRLF
*/
@ -107,7 +107,7 @@ class SMTP
* * self::DEBUG_SERVER (`2`) Client commands and server responses
* * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status
* * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages
* @type integer
* @var integer
*/
public $do_debug = self::DEBUG_OFF;
@ -122,7 +122,7 @@ class SMTP
* <code>
* $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
* </code>
* @type string|callable
* @var string|callable
*/
public $Debugoutput = 'echo';
@ -130,7 +130,7 @@ class SMTP
* Whether to use VERP.
* @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
* @link http://www.postfix.org/VERP_README.html Info on VERP
* @type boolean
* @var boolean
*/
public $do_verp = false;
@ -139,26 +139,26 @@ class SMTP
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
* This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
* @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2
* @type integer
* @var integer
*/
public $Timeout = 300;
/**
* How long to wait for commands to complete, in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
* @type integer
* @var integer
*/
public $Timelimit = 300;
/**
* The socket for the server connection.
* @type resource
* @var resource
*/
protected $smtp_conn;
/**
* Error information, if any, for the last SMTP command.
* @type array
* @var array
*/
protected $error = array(
'error' => '',
@ -170,7 +170,7 @@ class SMTP
/**
* The reply the server sent to us for HELO.
* If null, no HELO string has yet been received.
* @type string|null
* @var string|null
*/
protected $helo_rply = null;
@ -181,13 +181,13 @@ class SMTP
* represents the server name. In case of HELO it is the only element of the array.
* Other values can be boolean TRUE or an array containing extension options.
* If null, no HELO/EHLO string has yet been received.
* @type array|null
* @var array|null
*/
protected $server_caps = null;
/**
* The most recent reply received from the server.
* @type string
* @var string
*/
protected $last_reply = '';
@ -356,7 +356,7 @@ class SMTP
* @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2)
* @param string $realm The auth realm for NTLM
* @param string $workstation The auth workstation for NTLM
* @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)
* @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)
* @return bool True if successfully authenticated.* @access public
*/
public function authenticate(
@ -814,15 +814,15 @@ class SMTP
* Sets the TO argument to $toaddr.
* Returns true if the recipient was accepted false if it was rejected.
* Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
* @param string $toaddr The address the message is being sent to
* @param string $address The address the message is being sent to
* @access public
* @return boolean
*/
public function recipient($toaddr)
public function recipient($address)
{
return $this->sendCommand(
'RCPT TO',
'RCPT TO:<' . $toaddr . '>',
'RCPT TO:<' . $address . '>',
array(250, 251)
);
}
@ -841,9 +841,9 @@ class SMTP
/**
* Send a command to an SMTP server and check its return code.
* @param string $command The command name - not sent to the server
* @param string $command The command name - not sent to the server
* @param string $commandstring The actual command to send
* @param integer|array $expect One or more expected integer success codes
* @param integer|array $expect One or more expected integer success codes
* @access protected
* @return boolean True on success.
*/
@ -853,6 +853,11 @@ class SMTP
$this->setError("Called $command without being connected");
return false;
}
//Reject line breaks in all commands
if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
$this->setError("Command '$command' contained line breaks");
return false;
}
$this->client_send($commandstring . self::CRLF);
$this->last_reply = $this->get_lines();

View file

@ -1,64 +1,60 @@
<?php
/**
* Get an OAuth2 token from Google.
* * Install this script on your server so that it's accessible
* as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
* e.g.: http://localhost/phpmail/get_oauth_token.php
* * Ensure dependencies are installed with 'composer install'
* * Set up an app in your Google developer console
* * Set the script address as the app's redirect URL
* If no refresh token is obtained when running this file, revoke access to your app
* using link: https://accounts.google.com/b/0/IssuedAuthSubTokens and run the script again.
* This script requires PHP 5.4 or later
*/
require 'vendor/autoload.php';
session_start();
//If this automatic URL doesn't work, set it yourself manually
$redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
//$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php';
$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
//All details obtained by setting up app in Google developer console.
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
$provider = new League\OAuth2\Client\Provider\Google (
[
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri,
'scopes' => ['https://mail.google.com/'],
'accessType' => 'offline'
]
);
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->state;
header('Location: ' . $authUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
$provider->accessType = 'offline';
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken(
'authorization_code',
[
'code' => $_GET['code']
]
);
// Use this to interact with an API on the users behalf
// echo $token->accessToken.'<br>';
// Use this to get a new access token if the old one expires
echo 'Refresh Token: ' . $token->refreshToken;
// Unix timestamp of when the token will expire, and need refreshing
// echo $token->expires;
}
<?php
/**
* Get an OAuth2 token from Google.
* * Install this script on your server so that it's accessible
* as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
* e.g.: http://localhost/phpmail/get_oauth_token.php
* * Ensure dependencies are installed with 'composer install'
* * Set up an app in your Google developer console
* * Set the script address as the app's redirect URL
* If no refresh token is obtained when running this file, revoke access to your app
* using link: https://accounts.google.com/b/0/IssuedAuthSubTokens and run the script again.
* This script requires PHP 5.4 or later
* PHP Version 5.4
*/
require 'vendor/autoload.php';
session_start();
//If this automatic URL doesn't work, set it yourself manually
$redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
//$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php';
//These details obtained are by setting up app in Google developer console.
$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
$provider = new League\OAuth2\Client\Provider\Google(
array(
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri,
'scopes' => array('https://mail.google.com/'),
'accessType' => 'offline'
)
);
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->getState();
header('Location: ' . $authUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken(
'authorization_code',
array(
'code' => $_GET['code']
)
);
// Use this to get a new access token if the old one expires
echo 'Refresh Token: ' . $token->getRefreshToken();
}

View file

@ -33,30 +33,6 @@
type="text/css"
href="<?php echo base_url('assets/css/general.css'); ?>">
<?php
// ------------------------------------------------------------
// INCLUDE JAVASCRIPT FILES
// ------------------------------------------------------------ ?>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/jquery/jquery.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/jquery-ui/jquery-ui.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/jquery-qtip/jquery.qtip.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/bootstrap/js/bootstrap.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/datejs/date.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/js/frontend_book.js'); ?>"></script>
<?php
// ------------------------------------------------------------
// WEBPAGE FAVICON
@ -67,34 +43,6 @@
<link rel="icon" sizes="192x192"
href="<?php echo base_url('assets/img/logo.png'); ?>">
<?php
// ------------------------------------------------------------
// VIEW FILE JAVASCRIPT CODE
// ------------------------------------------------------------ ?>
<script type="text/javascript">
var GlobalVariables = {
availableServices : <?php echo json_encode($available_services); ?>,
availableProviders : <?php echo json_encode($available_providers); ?>,
baseUrl : <?php echo json_encode($this->config->item('base_url')); ?>,
manageMode : <?php echo ($manage_mode) ? 'true' : 'false'; ?>,
dateFormat : <?php echo json_encode($date_format); ?>,
appointmentData : <?php echo json_encode($appointment_data); ?>,
providerData : <?php echo json_encode($provider_data); ?>,
customerData : <?php echo json_encode($customer_data); ?>,
csrfToken : <?php echo json_encode($this->security->get_csrf_hash()); ?>
};
var EALang = <?php echo json_encode($this->lang->language); ?>;
var availableLanguages = <?php echo json_encode($this->config->item('available_languages')); ?>;
$(document).ready(function() {
FrontendBook.initialize(true, GlobalVariables.manageMode);
// GeneralFunctions.centerElementOnPage($('#book-appointment-wizard'));
GeneralFunctions.enableLanguageSelection($('#select-language'));
});
</script>
</head>
<body>
@ -431,9 +379,66 @@
</div>
</div>
<?php
// ------------------------------------------------------------
// GLOBAL JAVASCRIPT VARIABLES
// ------------------------------------------------------------ ?>
<script type="text/javascript">
var GlobalVariables = {
availableServices : <?php echo json_encode($available_services); ?>,
availableProviders : <?php echo json_encode($available_providers); ?>,
baseUrl : <?php echo json_encode($this->config->item('base_url')); ?>,
manageMode : <?php echo ($manage_mode) ? 'true' : 'false'; ?>,
dateFormat : <?php echo json_encode($date_format); ?>,
appointmentData : <?php echo json_encode($appointment_data); ?>,
providerData : <?php echo json_encode($provider_data); ?>,
customerData : <?php echo json_encode($customer_data); ?>,
csrfToken : <?php echo json_encode($this->security->get_csrf_hash()); ?>
};
var EALang = <?php echo json_encode($this->lang->language); ?>;
var availableLanguages = <?php echo json_encode($this->config->item('available_languages')); ?>;
</script>
<?php
// ------------------------------------------------------------
// INCLUDE JAVASCRIPT FILES
// ------------------------------------------------------------ ?>
<script
type="text/javascript"
src="<?php echo base_url('assets/js/general_functions.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/jquery/jquery.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/jquery-ui/jquery-ui.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/jquery-qtip/jquery.qtip.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/bootstrap/js/bootstrap.min.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/ext/datejs/date.js'); ?>"></script>
<script
type="text/javascript"
src="<?php echo base_url('assets/js/frontend_book.js'); ?>"></script>
<?php
// ------------------------------------------------------------
// VIEW FILE JAVASCRIPT CODE
// ------------------------------------------------------------ ?>
<script type="text/javascript">
$(document).ready(function() {
FrontendBook.initialize(true, GlobalVariables.manageMode);
GeneralFunctions.enableLanguageSelection($('#select-language'));
});
</script>
<?php google_analytics_script(); ?>
</body>

View file

@ -51,7 +51,7 @@
</a>
';
if ($this->config->item('ea_google_sync_feature')) {
if ($this->config->item('google_sync_feature')) {
echo '
<button id="add-to-google-calendar" class="btn btn-primary">
<span class="glyphicon glyphicon-plus"></span>

View file

@ -3,9 +3,9 @@
Powered by
<a href="http://easyappointments.org">Easy!Appointments
<?php
echo 'v' . $this->config->item('ea_version');
echo 'v' . $this->config->item('version');
$release_title = $this->config->item('ea_release_title');
$release_title = $this->config->item('release_label');
if ($release_title != '') {
echo ' - ' . $release_title;
}

View file

@ -438,8 +438,8 @@
<div class="current-version">
<?php
echo $this->lang->line('current_version') . ' ';
echo $this->config->item('ea_version');
$release_title = $this->config->item('ea_release_title');
echo $this->config->item('version');
$release_title = $this->config->item('release_label');
if ($release_title != '') {
echo ' - ' . $release_title;
}

View file

@ -0,0 +1,8 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
echo "\nERROR: ",
$heading,
"\n\n",
$message,
"\n\n";

View file

@ -0,0 +1,8 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
echo "\nDatabase error: ",
$heading,
"\n\n",
$message,
"\n\n";

View file

@ -0,0 +1,21 @@
<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>
An uncaught Exception was encountered
Type: <?php echo get_class($exception), "\n"; ?>
Message: <?php echo $message, "\n"; ?>
Filename: <?php echo $exception->getFile(), "\n"; ?>
Line Number: <?php echo $exception->getLine(); ?>
<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
Backtrace:
<?php foreach ($exception->getTrace() as $error): ?>
<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
File: <?php echo $error['file'], "\n"; ?>
Line: <?php echo $error['line'], "\n"; ?>
Function: <?php echo $error['function'], "\n\n"; ?>
<?php endif ?>
<?php endforeach ?>
<?php endif ?>

View file

@ -0,0 +1,8 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
echo "\nERROR: ",
$heading,
"\n\n",
$message,
"\n\n";

View file

@ -0,0 +1,21 @@
<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>
A PHP Error was encountered
Severity: <?php echo $severity, "\n"; ?>
Message: <?php echo $message, "\n"; ?>
Filename: <?php echo $filepath, "\n"; ?>
Line Number: <?php echo $line; ?>
<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
Backtrace:
<?php foreach (debug_backtrace() as $error): ?>
<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
File: <?php echo $error['file'], "\n"; ?>
Line: <?php echo $error['line'], "\n"; ?>
Function: <?php echo $error['function'], "\n\n"; ?>
<?php endif ?>
<?php endforeach ?>
<?php endif ?>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View file

@ -0,0 +1,32 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?>
<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
<h4>An uncaught Exception was encountered</h4>
<p>Type: <?php echo get_class($exception); ?></p>
<p>Message: <?php echo $message; ?></p>
<p>Filename: <?php echo $exception->getFile(); ?></p>
<p>Line Number: <?php echo $exception->getLine(); ?></p>
<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
<p>Backtrace:</p>
<?php foreach ($exception->getTrace() as $error): ?>
<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
<p style="margin-left:10px">
File: <?php echo $error['file']; ?><br />
Line: <?php echo $error['line']; ?><br />
Function: <?php echo $error['function']; ?>
</p>
<?php endif ?>
<?php endforeach ?>
<?php endif ?>
</div>

View file

@ -9,70 +9,75 @@
* @since v1.0.0
* ---------------------------------------------------------------------------- */
/**
* Main javascript code for the backend of Easy!Appointments.
*/
$(document).ready(function() {
if (window.console === undefined) {
window.console = function() {} // IE compatibility
}
window.Backend = window.Backend || {};
$(window).resize(function() {
Backend.placeFooterToBottom();
}).trigger('resize');
/**
* This module contains functions that are used in the backend section of
* the application.
*
* @module Backend
*/
(function(exports) {
$(document).ajaxStart(function() {
$('#loading').show();
});
'use strict';
$(document).ajaxStop(function() {
$('#loading').hide();
});
$('.menu-item').qtip({
position: {
my: 'top center',
at: 'bottom center'
},
style: {
classes: 'qtip-green qtip-shadow custom-qtip'
/**
* Main javascript code for the backend of Easy!Appointments.
*/
$(document).ready(function() {
if (window.console === undefined) {
window.console = function() {} // IE compatibility
}
$(window).resize(function() {
Backend.placeFooterToBottom();
}).trigger('resize');
$(document).ajaxStart(function() {
$('#loading').show();
});
$(document).ajaxStop(function() {
$('#loading').hide();
});
$('.menu-item').qtip({
position: {
my: 'top center',
at: 'bottom center'
},
style: {
classes: 'qtip-green qtip-shadow custom-qtip'
}
});
GeneralFunctions.enableLanguageSelection($('#select-language'));
});
GeneralFunctions.enableLanguageSelection($('#select-language'));
});
/**
* This namespace contains functions that are used in the backend section of
* the applications.
*
* @namespace Backend
*/
var Backend = {
/**
* Backend Constants
*/
DB_SLUG_ADMIN: 'admin',
DB_SLUG_PROVIDER: 'provider',
DB_SLUG_SECRETARY: 'secretary',
DB_SLUG_CUSTOMER: 'customer',
exports.DB_SLUG_ADMIN = 'admin';
exports.DB_SLUG_PROVIDER = 'provider';
exports.DB_SLUG_SECRETARY = 'secretary';
exports.DB_SLUG_CUSTOMER = 'customer';
PRIV_VIEW: 1,
PRIV_ADD: 2,
PRIV_EDIT: 4,
PRIV_DELETE: 8,
exports.PRIV_VIEW = 1;
exports.PRIV_ADD = 2;
exports.PRIV_EDIT = 4;
exports.PRIV_DELETE = 8;
PRIV_APPOINTMENTS: 'appointments',
PRIV_CUSTOMERS: 'customers',
PRIV_SERVICES: 'services',
PRIV_USERS: 'users',
PRIV_SYSTEM_SETTINGS: 'system_settings',
PRIV_USER_SETTINGS: 'user_settings',
exports.PRIV_APPOINTMENTS = 'appointments';
exports.PRIV_CUSTOMERS = 'customers';
exports.PRIV_SERVICES = 'services';
exports.PRIV_USERS = 'users';
exports.PRIV_SYSTEM_SETTINGS = 'system_settings';
exports.PRIV_USER_SETTINGS = 'user_settings';
/**
* Place the backend footer always on the bottom of the page.
*/
placeFooterToBottom: function() {
exports.placeFooterToBottom = function() {
var $footer = $('#footer');
if (window.innerHeight > $('body').height()) {
@ -86,7 +91,7 @@ var Backend = {
'position': 'static'
});
}
},
};
/**
* Display backend notifications to user.
@ -100,7 +105,7 @@ var Backend = {
* to the user. Every array item is an object that contains the 'label' and
* 'function' key values.
*/
displayNotification: function(message, actions) {
exports.displayNotification = function(message, actions) {
if (message == undefined) {
message = 'NO MESSAGE PROVIDED FOR THIS NOTIFICATION';
}
@ -130,4 +135,5 @@ var Backend = {
$('#notification').html(notificationHtml);
$('#notification').show('blind');
}
};
})(window.Backend);

View file

@ -9,33 +9,36 @@
* @since v1.0.0
* ---------------------------------------------------------------------------- */
window.GeneralFunctions = window.GeneralFunctions || {};
/**
* This file contains the General Functions javascript namespace.
* It contains functions that apply both on the front and back
* end of the application.
* General Functions Module
*
* @namespace GeneralFunctions
* It contains functions that apply both on the front and back end of the application.
*
* @module GeneralFunctions
*/
var GeneralFunctions = {
(function(exports) {
'use strict';
/**
* General Functions Constants
*/
EXCEPTIONS_TITLE: EALang['unexpected_issues'],
EXCEPTIONS_MESSAGE: EALang['unexpected_issues_message'],
WARNINGS_TITLE: EALang['unexpected_warnings'],
WARNINGS_MESSAGE: EALang['unexpected_warnings_message'],
exports.EXCEPTIONS_TITLE = EALang['unexpected_issues'];
exports.EXCEPTIONS_MESSAGE = EALang['unexpected_issues_message'];
exports.WARNINGS_TITLE = EALang['unexpected_warnings'];
exports.WARNINGS_MESSAGE = EALang['unexpected_warnings_message'];
/**
* This functions displays a message box in
* the admin array. It is usefull when user
* This functions displays a message box in the admin array. It is usefull when user
* decisions or verifications are needed.
*
* @param {string} title The title of the message box.
* @param {string} message The message of the dialog.
* @param {array} messageButtons Contains the dialog
* buttons along with their functions.
* @param {array} messageButtons Contains the dialog buttons along with their functions.
*/
displayMessageBox: function(title, message, messageButtons) {
exports.displayMessageBox = function(title, message, messageButtons) {
// Check arguments integrity.
if (title == undefined || title == '') {
title = '<No Title Given>';
@ -77,16 +80,14 @@ var GeneralFunctions = {
$('#message_box').dialog('open');
$('.ui-dialog .ui-dialog-buttonset button').addClass('btn btn-default');
$('#message_box .ui-dialog-titlebar-close').hide();
},
};
/**
* This method centers a DOM element vertically and horizontally
* on the page.
* This method centers a DOM element vertically and horizontally on the page.
*
* @param {object} elementHandle The object that is going to be
* centered.
* @param {object} elementHandle The object that is going to be centered.
*/
centerElementOnPage: function(elementHandle) {
exports.centerElementOnPage = function(elementHandle) {
// Center main frame vertical middle
$(window).resize(function() {
var elementLeft = ($(window).width() - elementHandle.outerWidth()) / 2;
@ -100,7 +101,7 @@ var GeneralFunctions = {
});
});
$(window).resize();
},
};
/**
* This function retrieves a parameter from a "GET" formed url.
@ -109,24 +110,26 @@ var GeneralFunctions = {
*
* @param {string} url The selected url.
* @param {string} name The parameter name.
* @returns {String} Returns the parameter value.
* @return {string} Returns the parameter value.
*/
getUrlParameter: function(url, parameterName) {
exports.getUrlParameter = function(url, parameterName) {
parameterName = parameterName.replace(/[\[]/,'\\\[').replace(/[\]]/,'\\\]');
var regexS = '[\\#&]' + parameterName + '=([^&#]*)',
regex = new RegExp(regexS),
results = regex.exec(url);
return (results == null) ? '' : results[1];
},
};
/**
* This function creates a RFC 3339 date string. This string is needed
* by the Google Calendar API in order to pass dates as parameters.
* This function creates a RFC 3339 date string. This string is needed by the Google Calendar API
in order to pass dates as parameters.
*
* @param {date} dt The given date that will be transformed
* @returns {String} Returns the transformed string.
* @param {date} dt The given date that will be transformed.
* @return {String} Returns the transformed string.
*/
ISODateString: function(dt) {
exports.ISODateString = function(dt) {
function pad(n) {
return n<10 ? '0'+n : n;
}
@ -137,19 +140,21 @@ var GeneralFunctions = {
+ pad(dt.getUTCHours())+':'
+ pad(dt.getUTCMinutes())+':'
+ pad(dt.getUTCSeconds())+'Z';
},
};
/**
* This method creates and returns an exact copy of the provided object.
* It is very usefull whenever changes need to be made to an object without
* modyfing the original data.
*
* @link http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object
*
* @param {object} originalObject Object to be copied.
* @returns {object} Returns an exact copy of the provided element.
* @return {object} Returns an exact copy of the provided element.
*/
clone: function(originalObject) {
exports.clone = function(originalObject) {
// Handle the 3 simple types, and null or undefined
if (null == originalObject || 'object' != typeof originalObject)
return originalObject;
@ -181,7 +186,7 @@ var GeneralFunctions = {
}
throw new Error('Unable to copy obj! Its type isn\'t supported.');
},
};
/**
* This method validates an email address. If the address is not on the proper
@ -190,22 +195,25 @@ var GeneralFunctions = {
* @link http://badsyntax.co/post/javascript-email-validation-rfc822
*
* @param {string} email The email address to be checked.
* @returns {bool} Returns the validation result.
* @return {bool} Returns the validation result.
*/
validateEmail: function (email) {
exports.validateEmail = function (email) {
var re = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/;
return re.test(email);
},
};
/**
* This method returns the exception html display for javascript ajax calls.
* This method returns the exception HTML display for javascript ajax calls.
* It uses the Bootstrap collapse module to show exception messages when the
* user opens the "Details" collapse component.
*
* @param {array} exceptions Contains the exceptions to be displayed.
* @returns {string} Returns the html markup for the exceptions.
*
* @return {string} Returns the html markup for the exceptions.
*/
exceptionsToHtml: function(exceptions) {
exports.exceptionsToHtml = function(exceptions) {
var html =
'<div class="accordion" id="error-accordion">' +
'<div class="accordion-group">' +
@ -228,7 +236,7 @@ var GeneralFunctions = {
html += '</div></div>';
return html;
},
};
/**
* This method parse the json encoded strings that are fetched by ajax calls.
@ -236,7 +244,7 @@ var GeneralFunctions = {
* @param {array} exceptions Exception array returned by an ajax call.
* @returns {array} Returns the parsed js objects.
*/
parseExceptions: function(exceptions) {
exports.parseExceptions = function(exceptions) {
var parsedExceptions = new Array();
$.each(exceptions, function(index, exception) {
@ -244,7 +252,7 @@ var GeneralFunctions = {
});
return parsedExceptions;
},
};
/**
* Makes the first letter of the string upper case.
@ -252,20 +260,21 @@ var GeneralFunctions = {
* @param {string} str The string to be converted.
* @returns {string} Returns the capitalized string.
*/
ucaseFirstLetter: function(str){
exports.ucaseFirstLetter = function(str){
return str.charAt(0).toUpperCase() + str.slice(1);
},
};
/**
* All backend js code has the same way of dislaying exceptions that are raised on the
* server during an ajax call.
*
* @param {object} response Contains the server response. If exceptions or warnings are
* found, user friendly messages are going to be displayed to the user.
* @returns {bool} Returns whether the the ajax callback should continue the execution or
* found, user friendly messages are going to be displayed to the user.4
*
* @return {bool} Returns whether the the ajax callback should continue the execution or
* stop, due to critical server exceptions.
*/
handleAjaxExceptions: function(response) {
exports.handleAjaxExceptions = function(response) {
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE, GeneralFunctions.EXCEPTIONS_MESSAGE);
@ -280,7 +289,7 @@ var GeneralFunctions = {
}
return true;
},
};
/**
* Enables the language selection functionality. Must be called on every page has a
@ -289,7 +298,7 @@ var GeneralFunctions = {
*
* @param {object} $element Selected element button for the language selection.
*/
enableLanguageSelection: function($element) {
exports.enableLanguageSelection = function($element) {
// Select Language
var html = '<ul id="language-list">';
$.each(availableLanguages, function() {
@ -330,7 +339,7 @@ var GeneralFunctions = {
}, 'json').fail(GeneralFunctions.ajaxFailureHandler);
});
},
};
/**
* Use this method for common error handling between
@ -339,7 +348,7 @@ var GeneralFunctions = {
* @param {string} textStatus
* @param {object} errorThrown
*/
ajaxFailureHandler: function(jqxhr, textStatus, errorThrown) {
exports.ajaxFailureHandler = function(jqxhr, textStatus, errorThrown) {
var exceptions = [
{
message: 'AJAX Error: ' + errorThrown
@ -348,7 +357,7 @@ var GeneralFunctions = {
GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE,
GeneralFunctions.EXCEPTIONS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(exceptions));
},
};
/**
* Escape JS HTML string values for XSS prevention.
@ -356,9 +365,9 @@ var GeneralFunctions = {
* @param {string} str String to be escaped.
* @returns {string} Returns the escaped string.
*/
escapeHtml: function(str) {
exports.escapeHtml = function(str) {
return $('<div/>').text(str).html();
},
};
/**
* Format a given date according to the date format setting.
@ -367,9 +376,10 @@ var GeneralFunctions = {
* @param {string} dateFormatSetting The setting provided by PHP must be one of
* the "DMY", "MDY" or "YMD".
* @param {bool} addHours (optional) Whether to add hours to the result.
* @returns {string} Returns the formatted date string.
* @return {string} Returns the formatted date string.
*/
formatDate: function(date, dateFormatSetting, addHours) {
exports.formatDate = function(date, dateFormatSetting, addHours) {
var format, result,
hours = addHours ? ' HH:mm' : '';
@ -388,5 +398,6 @@ var GeneralFunctions = {
}
return result;
}
};
};
})(window.GeneralFunctions);

View file

@ -10,9 +10,11 @@
* ---------------------------------------------------------------------------- */
$(document).ready(function() {
var MIN_PASSWORD_LENGTH = 7;
var AJAX_SUCCESS = 'SUCCESS';
var AJAX_FAILURE = 'FAILURE';
'use strict';
var MIN_PASSWORD_LENGTH = 7,
AJAX_SUCCESS = 'SUCCESS',
AJAX_FAILURE = 'FAILURE';
$(document).ajaxStart(function() {
$('#loading').show();
@ -26,14 +28,16 @@ $(document).ready(function() {
* Event: Install Easy!Appointments Button "Click"
*/
$('#install').click(function() {
if (!validate()) return;
if (!validate()) {
return;
}
var postUrl = GlobalVariables.baseUrl + '/index.php/installation/ajax_install';
var postData = {
'csrfToken': GlobalVariables.csrfToken,
'admin': JSON.stringify(getAdminData()),
'company': JSON.stringify(getCompanyData())
};
var postUrl = GlobalVariables.baseUrl + '/index.php/installation/ajax_install',
postData = {
csrfToken: GlobalVariables.csrfToken,
admin: JSON.stringify(getAdminData()),
company: JSON.stringify(getCompanyData())
};
$.ajax({
url: postUrl,
@ -41,11 +45,9 @@ $(document).ready(function() {
data: postData,
datatype: 'json',
success: function(response) {
//////////////////////////////////////////////////////
console.log('Ajax Install E!A Response:', response);
//////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
if (!GeneralFunctions.handleAjaxExceptions(response)) {
return;
}
$('.alert').text('Easy!Appointments has been successfully installed!');
$('.alert').addClass('alert-success');
@ -90,8 +92,9 @@ $(document).ready(function() {
}
});
if (missingRequired)
if (missingRequired) {
throw 'All the page fields are required.';
}
// Validate Passwords
if ($('#password').val() != $('#retype-password').val()) {
@ -132,12 +135,12 @@ $(document).ready(function() {
*/
function getAdminData() {
var admin = {
'first_name': $('#first-name').val(),
'last_name': $('#last-name').val(),
'email': $('#email').val(),
'phone_number': $('#phone-number').val(),
'username': $('#username').val(),
'password': $('#password').val()
first_name: $('#first-name').val(),
last_name: $('#last-name').val(),
email: $('#email').val(),
phone_number: $('#phone-number').val(),
username: $('#username').val(),
password: $('#password').val()
};
return admin;
@ -150,9 +153,9 @@ $(document).ready(function() {
*/
function getCompanyData() {
var company = {
'company_name': $('#company-name').val(),
'company_email': $('#company-email').val(),
'company_link': $('#company-link').val()
company_name: $('#company-name').val(),
company_email: $('#company-email').val(),
company_link: $('#company-link').val()
};
return company;

View file

@ -9,413 +9,431 @@
* @since v1.0.0
* ---------------------------------------------------------------------------- */
/**
* Contains the working plan functionality. The working plan DOM elements must be same
* in every page this class is used.
*
* @class WorkingPlan
*/
var WorkingPlan = function() {
/**
* This flag is used when trying to cancel row editing. It is
* true only whenever the user presses the cancel button.
*
* @type {bool}
*/
this.enableCancel = false;
(function() {
'use strict';
/**
* This flag determines whether the jeditables are allowed to submit. It is
* true only whenever the user presses the save button.
* Contains the working plan functionality. The working plan DOM elements must be same
* in every page this class is used.
*
* @type {bool}
* @class WorkingPlan
*/
this.enableSubmit = false;
};
var WorkingPlan = function() {
/**
* This flag is used when trying to cancel row editing. It is
* true only whenever the user presses the cancel button.
*
* @type {bool}
*/
this.enableCancel = false;
/**
* Setup the dom elements of a given working plan.
*
* @param {object} workingPlan Contains the working hours and breaks for each day of the week.
*/
WorkingPlan.prototype.setup = function(workingPlan) {
$.each(workingPlan, function(index, workingDay) {
if (workingDay != null) {
$('#' + index).prop('checked', true);
$('#' + index + '-start').val(workingDay.start);
$('#' + index + '-end').val(workingDay.end);
// Add the day's breaks on the breaks table.
$.each(workingDay.breaks, function(i, brk) {
var day = WorkingPlan.prototype.convertValueToDay(index);
var tr =
'<tr>' +
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(day) + '</td>' +
'<td class="break-start editable">' + brk.start + '</td>' +
'<td class="break-end editable">' + brk.end + '</td>' +
'<td>' +
'<button type="button" class="btn btn-default btn-sm edit-break" title="' + EALang['edit'] + '">' +
'<span class="glyphicon glyphicon-pencil"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm delete-break" title="' + EALang['delete'] + '">' +
'<span class="glyphicon glyphicon-remove"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm save-break hidden" title="' + EALang['save'] + '">' +
'<span class="glyphicon glyphicon-ok"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm cancel-break hidden" title="' + EALang['cancel'] + '">' +
'<span class="glyphicon glyphicon-ban-circle"></span>' +
'</button>' +
'</td>' +
'</tr>';
$('.breaks').append(tr);
});
} else {
$('#' + index).prop('checked', false);
$('#' + index + '-start').prop('disabled', true);
$('#' + index + '-end').prop('disabled', true);
}
});
// Make break cells editable.
WorkingPlan.prototype.editableBreakDay($('.breaks .break-day'));
WorkingPlan.prototype.editableBreakTime($('.breaks').find('.break-start, .break-end'));
};
/**
* This method makes editable the break day cells.
*
* @param {object} $selector The jquery selector ready for use.
*/
WorkingPlan.prototype.editableBreakDay = function($selector) {
var weekDays = {};
weekDays[EALang['monday']] = EALang['monday']; //'Monday';
weekDays[EALang['tuesday']] = EALang['tuesday']; //'Tuesday';
weekDays[EALang['wednesday']] = EALang['wednesday']; //'Wednesday';
weekDays[EALang['thursday']] = EALang['thursday']; //'Thursday';
weekDays[EALang['friday']] = EALang['friday']; //'Friday';
weekDays[EALang['saturday']] = EALang['saturday']; //'Saturday';
weekDays[EALang['sunday']] = EALang['sunday']; //'Sunday';
$selector.editable(function(value, settings) {
return value;
}, {
'type': 'select',
'data': weekDays,
'event': 'edit',
'height': '30px',
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
'onblur': 'ignore',
'onreset': function(settings, td) {
if (!WorkingPlan.prototype.enableCancel) return false; // disable ESC button
},
'onsubmit': function(settings, td) {
if (!WorkingPlan.prototype.enableSubmit) return false; // disable Enter button
}
});
};
/**
* This method makes editable the break time cells.
*
* @param {object} $selector The jquery selector ready for use.
*/
WorkingPlan.prototype.editableBreakTime = function($selector) {
$selector.editable(function(value, settings) {
// Do not return the value because the user needs to press the "Save" button.
return value;
}, {
'event': 'edit',
'height': '25px',
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
'onblur': 'ignore',
'onreset': function(settings, td) {
if (!WorkingPlan.prototype.enableCancel) return false; // disable ESC button
},
'onsubmit': function(settings, td) {
if (!WorkingPlan.prototype.enableSubmit) return false; // disable Enter button
}
});
};
/**
* Binds the event handlers for the working plan dom elements.
*/
WorkingPlan.prototype.bindEventHandlers = function() {
/**
* Event: Day Checkbox "Click"
*
* Enable or disable the time selection for each day.
*/
$('.working-plan input[type="checkbox"]').click(function() {
var id = $(this).attr('id');
if ($(this).prop('checked') == true) {
$('#' + id + '-start').prop('disabled', false).val('09:00');
$('#' + id + '-end').prop('disabled', false).val('18:00');
} else {
$('#' + id + '-start').prop('disabled', true).val('');
$('#' + id + '-end').prop('disabled', true).val('');
}
});
/**
* This flag determines whether the jeditables are allowed to submit. It is
* true only whenever the user presses the save button.
*
* @type {bool}
*/
this.enableSubmit = false;
};
/**
* Event: Add Break Button "Click"
* Setup the dom elements of a given working plan.
*
* A new row is added on the table and the user can enter the new break
* data. After that he can either press the save or cancel button.
* @param {object} workingPlan Contains the working hours and breaks for each day of the week.
*/
$('.add-break').click(function() {
var tr =
'<tr>' +
'<td class="break-day editable">' + EALang['monday'] + '</td>' +
'<td class="break-start editable">09:00</td>' +
'<td class="break-end editable">10:00</td>' +
'<td>' +
'<button type="button" class="btn btn-default btn-sm edit-break" title="' + EALang['edit'] + '">' +
'<span class="glyphicon glyphicon-pencil"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm delete-break" title="' + EALang['delete'] + '">' +
'<span class="glyphicon glyphicon-remove"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm save-break hidden" title="' + EALang['save'] + '">' +
'<span class="glyphicon glyphicon-ok"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm cancel-break hidden" title="' + EALang['cancel'] + '">' +
'<span class="glyphicon glyphicon-ban-circle"></span>' +
'</button>' +
'</td>' +
'</tr>';
$('.breaks').prepend(tr);
WorkingPlan.prototype.setup = function(workingPlan) {
$.each(workingPlan, function(index, workingDay) {
if (workingDay != null) {
$('#' + index).prop('checked', true);
$('#' + index + '-start').val(workingDay.start);
$('#' + index + '-end').val(workingDay.end);
// Bind editable and event handlers.
tr = $('.breaks tr').get()[1];
WorkingPlan.prototype.editableBreakDay($(tr).find('.break-day'));
WorkingPlan.prototype.editableBreakTime($(tr).find('.break-start, .break-end'));
$(tr).find('.edit-break').trigger('click');
$('.add-break').prop('disabled', true);
});
// Add the day's breaks on the breaks table.
$.each(workingDay.breaks, function(i, brk) {
var day = this.convertValueToDay(index);
var tr =
'<tr>' +
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(day) + '</td>' +
'<td class="break-start editable">' + brk.start + '</td>' +
'<td class="break-end editable">' + brk.end + '</td>' +
'<td>' +
'<button type="button" class="btn btn-default btn-sm edit-break" title="' + EALang['edit'] + '">' +
'<span class="glyphicon glyphicon-pencil"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm delete-break" title="' + EALang['delete'] + '">' +
'<span class="glyphicon glyphicon-remove"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm save-break hidden" title="' + EALang['save'] + '">' +
'<span class="glyphicon glyphicon-ok"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm cancel-break hidden" title="' + EALang['cancel'] + '">' +
'<span class="glyphicon glyphicon-ban-circle"></span>' +
'</button>' +
'</td>' +
'</tr>';
$('.breaks').append(tr);
}.bind(this));
} else {
$('#' + index).prop('checked', false);
$('#' + index + '-start').prop('disabled', true);
$('#' + index + '-end').prop('disabled', true);
}
}.bind(this));
// Make break cells editable.
this.editableBreakDay($('.breaks .break-day'));
this.editableBreakTime($('.breaks').find('.break-start, .break-end'));
};
/**
* Event: Edit Break Button "Click"
* This method makes editable the break day cells.
*
* Enables the row editing for the "Breaks" table rows.
* @param {object} $selector The jquery selector ready for use.
*/
$(document).on('click', '.edit-break', function() {
// Reset previous editable tds
var $previousEdt = $(this).closest('table').find('.editable').get();
$.each($previousEdt, function(index, edt) {
if (edt.reset !== undefined) edt.reset();
});
WorkingPlan.prototype.editableBreakDay = function($selector) {
var weekDays = {};
weekDays[EALang['monday']] = EALang['monday']; //'Monday';
weekDays[EALang['tuesday']] = EALang['tuesday']; //'Tuesday';
weekDays[EALang['wednesday']] = EALang['wednesday']; //'Wednesday';
weekDays[EALang['thursday']] = EALang['thursday']; //'Thursday';
weekDays[EALang['friday']] = EALang['friday']; //'Friday';
weekDays[EALang['saturday']] = EALang['saturday']; //'Saturday';
weekDays[EALang['sunday']] = EALang['sunday']; //'Sunday';
// Make all cells in current row editable.
$(this).parent().parent().children().trigger('edit');
$(this).parent().parent().find('.break-start input, .break-end input').timepicker({
currentText: EALang['now'],
closeText: EALang['close'],
timeOnlyTitle: EALang['select_time'],
timeText: EALang['time'],
hourText: EALang['hour'],
minuteText: EALang['minutes']
});
$(this).parent().parent().find('.break-day select').focus();
// Show save - cancel buttons.
$(this).closest('table').find('.edit-break, .delete-break').addClass('hidden');
$(this).parent().find('.save-break, .cancel-break').removeClass('hidden');
$('.add-break').prop('disabled', true);
});
/**
* Event: Delete Break Button "Click"
*
* Removes the current line from the "Breaks" table.
*/
$(document).on('click', '.delete-break', function() {
$(this).parent().parent().remove();
});
/**
* Event: Cancel Break Button "Click"
*
* Bring the ".breaks" table back to its initial state.
*/
$(document).on('click', '.cancel-break', function() {
WorkingPlan.prototype.enableCancel = true;
$(this).parent().parent().find('.cancel-editable').trigger('click');
WorkingPlan.prototype.enableCancel = false;
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
$('.add-break').prop('disabled', false);
});
/**
* Event: Save Break Button "Click"
*
* Save the editable values and restore the table to its initial state.
*/
$(document).on('click', '.save-break', function() {
// Break's start time must always be prior to break's end.
var start = Date.parse($(this).parent().parent().find('.break-start input').val());
var end = Date.parse($(this).parent().parent().find('.break-end input').val());
if (start > end) {
$(this).parent().parent().find('.break-end input').val(start.addHours(1).toString('HH:mm'));
}
WorkingPlan.prototype.enableSubmit = true;
$(this).parent().parent().find('.editable .submit-editable').trigger('click');
WorkingPlan.prototype.enableSubmit = false;
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
$('.add-break').prop('disabled', false);
});
};
/**
* Get the working plan settings.
*
* @returns {object} Returns the working plan settings object.
*/
WorkingPlan.prototype.get = function() {
var workingPlan = {};
$('.working-plan input[type="checkbox"]').each(function() {
var id = $(this).attr('id');
if ($(this).prop('checked') == true) {
workingPlan[id] = {};
workingPlan[id].start = $('#' + id + '-start').val();
workingPlan[id].end = $('#' + id + '-end').val();
workingPlan[id].breaks = [];
$('.breaks tr').each(function(index, tr) {
var day = WorkingPlan.prototype.convertDayToValue(
$(tr).find('.break-day').text());
if (day == id) {
var start = $(tr).find('.break-start').text();
var end = $(tr).find('.break-end').text();
workingPlan[id].breaks.push({
'start': start,
'end': end
});
$selector.editable(function(value, settings) {
return value;
}, {
type: 'select',
data: weekDays,
event: 'edit',
height: '30px',
submit: '<button type="button" class="hidden submit-editable">Submit</button>',
cancel: '<button type="button" class="hidden cancel-editable">Cancel</button>',
onblur: 'ignore',
onreset: function(settings, td) {
if (!this.enableCancel) {
return false; // disable ESC button
}
});
} else {
workingPlan[id] = null;
}
});
return workingPlan;
};
/**
* Enables or disabled the timepicker functionality from the working plan input
* text fields.
*
* @param {bool} disabled (OPTIONAL = false) If true then the timepickers will be
* disabled.
*/
WorkingPlan.prototype.timepickers = function(disabled) {
if (disabled == undefined) disabled == false;
if (disabled == false) {
// Set timepickers where needed.
$('.working-plan input[type="text"]').timepicker({
'timeFormat': 'HH:mm',
currentText: EALang['now'],
closeText: EALang['close'],
timeOnlyTitle: EALang['select_time'],
timeText: EALang['time'],
hourText: EALang['hour'],
minuteText: EALang['minutes'],
'onSelect': function(datetime, inst) {
// Start time must be earlier than end time.
var start = Date.parse($(this).parent().parent().find('.work-start').val());
var end = Date.parse($(this).parent().parent().find('.work-end').val());
if (start > end) {
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
}.bind(this),
onsubmit: function(settings, td) {
if (!this.enableSubmit) {
return false; // disable Enter button
}
}.bind(this)
});
};
/**
* This method makes editable the break time cells.
*
* @param {object} $selector The jquery selector ready for use.
*/
WorkingPlan.prototype.editableBreakTime = function($selector) {
$selector.editable(function(value, settings) {
// Do not return the value because the user needs to press the "Save" button.
return value;
}, {
event: 'edit',
height: '25px',
submit: '<button type="button" class="hidden submit-editable">Submit</button>',
cancel: '<button type="button" class="hidden cancel-editable">Cancel</button>',
onblur: 'ignore',
onreset: function(settings, td) {
if (!this.enableCancel) {
return false; // disable ESC button
}
}.bind(this),
onsubmit: function(settings, td) {
if (!this.enableSubmit) {
return false; // disable Enter button
}
}.bind(this)
});
};
/**
* Binds the event handlers for the working plan dom elements.
*/
WorkingPlan.prototype.bindEventHandlers = function() {
/**
* Event: Day Checkbox "Click"
*
* Enable or disable the time selection for each day.
*/
$('.working-plan input[type="checkbox"]').click(function() {
var id = $(this).attr('id');
if ($(this).prop('checked') == true) {
$('#' + id + '-start').prop('disabled', false).val('09:00');
$('#' + id + '-end').prop('disabled', false).val('18:00');
} else {
$('#' + id + '-start').prop('disabled', true).val('');
$('#' + id + '-end').prop('disabled', true).val('');
}
});
} else {
$('.working-plan input').timepicker('destroy');
}
};
/**
* Reset the current plan back to the company's default working plan.
*/
WorkingPlan.prototype.reset = function() {
/**
* Event: Add Break Button "Click"
*
* A new row is added on the table and the user can enter the new break
* data. After that he can either press the save or cancel button.
*/
$('.add-break').click(function() {
var tr =
'<tr>' +
'<td class="break-day editable">' + EALang['monday'] + '</td>' +
'<td class="break-start editable">09:00</td>' +
'<td class="break-end editable">10:00</td>' +
'<td>' +
'<button type="button" class="btn btn-default btn-sm edit-break" title="' + EALang['edit'] + '">' +
'<span class="glyphicon glyphicon-pencil"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm delete-break" title="' + EALang['delete'] + '">' +
'<span class="glyphicon glyphicon-remove"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm save-break hidden" title="' + EALang['save'] + '">' +
'<span class="glyphicon glyphicon-ok"></span>' +
'</button>' +
'<button type="button" class="btn btn-default btn-sm cancel-break hidden" title="' + EALang['cancel'] + '">' +
'<span class="glyphicon glyphicon-ban-circle"></span>' +
'</button>' +
'</td>' +
'</tr>';
$('.breaks').prepend(tr);
};
// Bind editable and event handlers.
tr = $('.breaks tr')[1];
this.editableBreakDay($(tr).find('.break-day'));
this.editableBreakTime($(tr).find('.break-start, .break-end'));
$(tr).find('.edit-break').trigger('click');
$('.add-break').prop('disabled', true);
}.bind(this));
/**
* This is necessary for translated days.
*
* @param {string} value Day value could be like "monday", "tuesday" etc.
*/
WorkingPlan.prototype.convertValueToDay = function(value) {
switch (value) {
case 'monday':
return EALang['monday'];
break;
case 'tuesday':
return EALang['tuesday'];
break;
case 'wednesday':
return EALang['wednesday'];
break;
case 'thursday':
return EALang['thursday'];
break;
case 'friday':
return EALang['friday'];
break;
case 'saturday':
return EALang['saturday'];
break;
case 'sunday':
return EALang['sunday'];
break;
}
};
/**
* Event: Edit Break Button "Click"
*
* Enables the row editing for the "Breaks" table rows.
*/
$(document).on('click', '.edit-break', function() {
// Reset previous editable tds
var $previousEdt = $(this).closest('table').find('.editable').get();
$.each($previousEdt, function(index, edt) {
if (edt.reset !== undefined) {
edt.reset();
}
});
/**
* This is necessary for translated days.
*
* @param {string} value Day value could be like "Monday", "Tuesday" etc.
*/
WorkingPlan.prototype.convertDayToValue = function(day) {
switch (day) {
case EALang['monday']:
return 'monday';
break;
case EALang['tuesday']:
return 'tuesday';
break;
case EALang['wednesday']:
return 'wednesday';
break;
case EALang['thursday']:
return 'thursday';
break;
case EALang['friday']:
return 'friday';
break;
case EALang['saturday']:
return 'saturday';
break;
case EALang['sunday']:
return 'sunday';
break;
}
};
// Make all cells in current row editable.
$(this).parent().parent().children().trigger('edit');
$(this).parent().parent().find('.break-start input, .break-end input').timepicker({
currentText: EALang['now'],
closeText: EALang['close'],
timeOnlyTitle: EALang['select_time'],
timeText: EALang['time'],
hourText: EALang['hour'],
minuteText: EALang['minutes']
});
$(this).parent().parent().find('.break-day select').focus();
// Show save - cancel buttons.
$(this).closest('table').find('.edit-break, .delete-break').addClass('hidden');
$(this).parent().find('.save-break, .cancel-break').removeClass('hidden');
$('.add-break').prop('disabled', true);
});
/**
* Event: Delete Break Button "Click"
*
* Removes the current line from the "Breaks" table.
*/
$(document).on('click', '.delete-break', function() {
$(this).parent().parent().remove();
});
/**
* Event: Cancel Break Button "Click"
*
* Bring the ".breaks" table back to its initial state.
*/
$(document).on('click', '.cancel-break', function(e) {
var element = e.target;
this.enableCancel = true;
$(element).parent().parent().find('.cancel-editable').trigger('click');
this.enableCancel = false;
$(element).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
$(element).parent().find('.save-break, .cancel-break').addClass('hidden');
$('.add-break').prop('disabled', false);
}.bind(this));
/**
* Event: Save Break Button "Click"
*
* Save the editable values and restore the table to its initial state.
*/
$(document).on('click', '.save-break', function(e) {
// Break's start time must always be prior to break's end.
var element = e.target,
start = Date.parse($(element).parent().parent().find('.break-start input').val()),
end = Date.parse($(element).parent().parent().find('.break-end input').val());
if (start > end) {
$(element).parent().parent().find('.break-end input').val(start.addHours(1).toString('HH:mm'));
}
this.enableSubmit = true;
$(element).parent().parent().find('.editable .submit-editable').trigger('click');
this.enableSubmit = false;
$(element).parent().find('.save-break, .cancel-break').addClass('hidden');
$(element).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
$('.add-break').prop('disabled', false);
}.bind(this));
};
/**
* Get the working plan settings.
*
* @returns {object} Returns the working plan settings object.
*/
WorkingPlan.prototype.get = function() {
var workingPlan = {};
$('.working-plan input[type="checkbox"]').each(function(index, checkbox) {
var id = $(checkbox).attr('id');
if ($(checkbox).prop('checked') == true) {
workingPlan[id] = {};
workingPlan[id].start = $('#' + id + '-start').val();
workingPlan[id].end = $('#' + id + '-end').val();
workingPlan[id].breaks = [];
$('.breaks tr').each(function(index, tr) {
var day = this.convertDayToValue($(tr).find('.break-day').text());
if (day == id) {
var start = $(tr).find('.break-start').text(),
end = $(tr).find('.break-end').text();
workingPlan[id].breaks.push({
'start': start,
'end': end
});
}
}.bind(this));
} else {
workingPlan[id] = null;
}
}.bind(this));
return workingPlan;
};
/**
* Enables or disabled the timepicker functionality from the working plan input
* text fields.
*
* @param {bool} disabled (OPTIONAL = false) If true then the timepickers will be
* disabled.
*/
WorkingPlan.prototype.timepickers = function(disabled) {
disabled = disabled || false;
if (disabled == false) {
// Set timepickers where needed.
$('.working-plan input[type="text"]').timepicker({
timeFormat: 'HH:mm',
currentText: EALang['now'],
closeText: EALang['close'],
timeOnlyTitle: EALang['select_time'],
timeText: EALang['time'],
hourText: EALang['hour'],
minuteText: EALang['minutes'],
onSelect: function(datetime, inst) {
// Start time must be earlier than end time.
var start = Date.parse($(this).parent().parent().find('.work-start').val()),
end = Date.parse($(this).parent().parent().find('.work-end').val());
if (start > end) {
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
}
}
});
} else {
$('.working-plan input').timepicker('destroy');
}
};
/**
* Reset the current plan back to the company's default working plan.
*/
WorkingPlan.prototype.reset = function() {
};
/**
* This is necessary for translated days.
*
* @param {string} value Day value could be like "monday", "tuesday" etc.
*/
WorkingPlan.prototype.convertValueToDay = function(value) {
switch (value) {
case 'monday':
return EALang['monday'];
break;
case 'tuesday':
return EALang['tuesday'];
break;
case 'wednesday':
return EALang['wednesday'];
break;
case 'thursday':
return EALang['thursday'];
break;
case 'friday':
return EALang['friday'];
break;
case 'saturday':
return EALang['saturday'];
break;
case 'sunday':
return EALang['sunday'];
break;
}
};
/**
* This is necessary for translated days.
*
* @param {string} value Day value could be like "Monday", "Tuesday" etc.
*/
WorkingPlan.prototype.convertDayToValue = function(day) {
switch (day) {
case EALang['monday']:
return 'monday';
break;
case EALang['tuesday']:
return 'tuesday';
break;
case EALang['wednesday']:
return 'wednesday';
break;
case EALang['thursday']:
return 'thursday';
break;
case EALang['friday']:
return 'friday';
break;
case EALang['saturday']:
return 'saturday';
break;
case EALang['sunday']:
return 'sunday';
break;
}
};
window.WorkingPlan = WorkingPlan;
})();

View file

@ -1,31 +1,66 @@
<?php
/*
*---------------------------------------------------------------
* EASY!APPOINTMENTS CONFIGURATION
*---------------------------------------------------------------
/**
* CodeIgniter
*
* Include Easy!Appointments configuration file so that it is available
* globally in the application. You can access configuration information
* through the static Config class.
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
require_once __DIR__ . '/config.php';
/*
*---------------------------------------------------------------
* EASY!APPOINTMENTS CONFIGURATION
*---------------------------------------------------------------
*
* Include Easy!Appointments configuration file so that it is available
* globally in the application. You can access configuration information
* through the static Config class.
*
*/
require_once __DIR__ . '/config.php';
/*
*---------------------------------------------------------------
* COMPOSER AUTOLOAD FILE
*---------------------------------------------------------------
*
* Include Composer's autoload.php file so that I can use external
* libraries directly in every section of the application.
*
*/
require_once __DIR__ . '/application/third_party/autoload.php';
/*
*---------------------------------------------------------------
* COMPOSER AUTOLOAD FILE
*---------------------------------------------------------------
*
* Include Composer's autoload.php file so that I can use external
* libraries directly in every section of the application.
*
*/
require_once __DIR__ . '/application/third_party/autoload.php';
/*
*---------------------------------------------------------------
@ -43,9 +78,9 @@ require_once __DIR__ . '/application/third_party/autoload.php';
* production
*
* NOTE: If you change these, also change the error_reporting() code below
*
*/
define('ENVIRONMENT', (Config::DEBUG_MODE) ? 'development' : 'production');
/*
*---------------------------------------------------------------
* ERROR REPORTING
@ -54,53 +89,75 @@ require_once __DIR__ . '/application/third_party/autoload.php';
* Different environments will require different levels of error reporting.
* By default development will show errors but testing and live will hide them.
*/
if (defined('ENVIRONMENT'))
switch (ENVIRONMENT)
{
switch (ENVIRONMENT)
{
case 'development':
error_reporting(E_ALL);
ini_set('display_errors', 1);
break;
case 'development':
error_reporting(-1);
ini_set('display_errors', 1);
break;
case 'production':
error_reporting(0);
break;
case 'testing':
case 'production':
ini_set('display_errors', 0);
if (version_compare(PHP_VERSION, '5.3', '>='))
{
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
}
else
{
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE);
}
break;
default:
exit('The application environment is not set correctly.');
}
default:
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'The application environment is not set correctly.';
exit(1); // EXIT_ERROR
}
/*
*---------------------------------------------------------------
* SYSTEM FOLDER NAME
* SYSTEM DIRECTORY NAME
*---------------------------------------------------------------
*
* This variable must contain the name of your "system" folder.
* Include the path if the folder is not in the same directory
* as this file.
*
* This variable must contain the name of your "system" directory.
* Set the path if it is not in the same directory as this file.
*/
$system_path = 'system';
/*
*---------------------------------------------------------------
* APPLICATION FOLDER NAME
* APPLICATION DIRECTORY NAME
*---------------------------------------------------------------
*
* If you want this front controller to use a different "application"
* folder then the default one you can set its name here. The folder
* can also be renamed or relocated anywhere on your server. If
* you do, use a full server path. For more info please see the user guide:
* http://codeigniter.com/user_guide/general/managing_apps.html
* directory than the default one you can set its name here. The directory
* can also be renamed or relocated anywhere on your server. If you do,
* use an absolute (full) server path.
* For more info please see the user guide:
*
* https://codeigniter.com/user_guide/general/managing_apps.html
*
* NO TRAILING SLASH!
*
*/
$application_folder = 'application';
/*
*---------------------------------------------------------------
* VIEW DIRECTORY NAME
*---------------------------------------------------------------
*
* If you want to move the view directory out of the application
* directory, set the path to it here. The directory can be renamed
* and relocated anywhere on your server. If blank, it will default
* to the standard location inside your application directory.
* If you do move this, use an absolute (full) server path.
*
* NO TRAILING SLASH!
*/
$view_folder = '';
/*
* --------------------------------------------------------------------
* DEFAULT CONTROLLER
@ -108,24 +165,23 @@ if (defined('ENVIRONMENT'))
*
* Normally you will set your default controller in the routes.php file.
* You can, however, force a custom routing by hard-coding a
* specific controller class/function here. For most applications, you
* specific controller class/function here. For most applications, you
* WILL NOT set your routing here, but it's an option for those
* special instances where you might want to override the standard
* routing in a specific front controller that shares a common CI installation.
*
* IMPORTANT: If you set the routing here, NO OTHER controller will be
* IMPORTANT: If you set the routing here, NO OTHER controller will be
* callable. In essence, this preference limits your application to ONE
* specific controller. Leave the function name blank if you need
* specific controller. Leave the function name blank if you need
* to call functions dynamically via the URI.
*
* Un-comment the $routing array below to use this feature
*
*/
// The directory name, relative to the "controllers" folder. Leave blank
// if your controller is not in a sub-folder within the "controllers" folder
// The directory name, relative to the "controllers" directory. Leave blank
// if your controller is not in a sub-directory within the "controllers" one
// $routing['directory'] = '';
// The controller class file name. Example: Mycontroller
// The controller class file name. Example: mycontroller
// $routing['controller'] = '';
// The controller function you wish to be called.
@ -145,7 +201,6 @@ if (defined('ENVIRONMENT'))
* config values.
*
* Un-comment the $assign_to_config array below to use this feature
*
*/
// $assign_to_config['name_of_config_item'] = 'value of config item';
@ -167,18 +222,26 @@ if (defined('ENVIRONMENT'))
chdir(dirname(__FILE__));
}
if (realpath($system_path) !== FALSE)
if (($_temp = realpath($system_path)) !== FALSE)
{
$system_path = realpath($system_path).'/';
$system_path = $_temp.DIRECTORY_SEPARATOR;
}
else
{
// Ensure there's a trailing slash
$system_path = strtr(
rtrim($system_path, '/\\'),
'/\\',
DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
).DIRECTORY_SEPARATOR;
}
// ensure there's a trailing slash
$system_path = rtrim($system_path, '/').'/';
// Is the system path correct?
if ( ! is_dir($system_path))
{
exit("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".pathinfo(__FILE__, PATHINFO_BASENAME));
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: '.pathinfo(__FILE__, PATHINFO_BASENAME);
exit(3); // EXIT_CONFIG
}
/*
@ -189,44 +252,90 @@ if (defined('ENVIRONMENT'))
// The name of THIS file
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
// The PHP file extension
// this global constant is deprecated.
define('EXT', '.php');
// Path to the system directory
define('BASEPATH', $system_path);
// Path to the system folder
define('BASEPATH', str_replace("\\", "/", $system_path));
// Path to the front controller (this file) directory
define('FCPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
// Path to the front controller (this file)
define('FCPATH', str_replace(SELF, '', __FILE__));
// Name of the "system" directory
define('SYSDIR', basename(BASEPATH));
// Name of the "system folder"
define('SYSDIR', trim(strrchr(trim(BASEPATH, '/'), '/'), '/'));
// The path to the "application" folder
// The path to the "application" directory
if (is_dir($application_folder))
{
define('APPPATH', $application_folder.'/');
if (($_temp = realpath($application_folder)) !== FALSE)
{
$application_folder = $_temp;
}
else
{
$application_folder = strtr(
rtrim($application_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
);
}
}
elseif (is_dir(BASEPATH.$application_folder.DIRECTORY_SEPARATOR))
{
$application_folder = BASEPATH.strtr(
trim($application_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
);
}
else
{
if ( ! is_dir(BASEPATH.$application_folder.'/'))
{
exit("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".SELF);
}
define('APPPATH', BASEPATH.$application_folder.'/');
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
exit(3); // EXIT_CONFIG
}
define('APPPATH', $application_folder.DIRECTORY_SEPARATOR);
// The path to the "views" directory
if ( ! isset($view_folder[0]) && is_dir(APPPATH.'views'.DIRECTORY_SEPARATOR))
{
$view_folder = APPPATH.'views';
}
elseif (is_dir($view_folder))
{
if (($_temp = realpath($view_folder)) !== FALSE)
{
$view_folder = $_temp;
}
else
{
$view_folder = strtr(
rtrim($view_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
);
}
}
elseif (is_dir(APPPATH.$view_folder.DIRECTORY_SEPARATOR))
{
$view_folder = APPPATH.strtr(
trim($view_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
);
}
else
{
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
exit(3); // EXIT_CONFIG
}
define('VIEWPATH', $view_folder.DIRECTORY_SEPARATOR);
/*
* --------------------------------------------------------------------
* LOAD THE BOOTSTRAP FILE
* --------------------------------------------------------------------
*
* And away we go...
*
*/
require_once BASEPATH.'core/CodeIgniter.php';
/* End of file index.php */
/* Location: ./index.php */

View file

@ -1 +1,6 @@
Deny from all
<IfModule authz_core_module>
Require all denied
</IfModule>
<IfModule !authz_core_module>
Deny from all
</IfModule>

View file

@ -1,62 +1,82 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter Benchmark Class
* Benchmark Class
*
* This class enables you to mark points and calculate the time difference
* between them. Memory consumption can also be displayed.
* between them. Memory consumption can also be displayed.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/benchmark.html
* @link https://codeigniter.com/user_guide/libraries/benchmark.html
*/
class CI_Benchmark {
/**
* List of all benchmark markers and when they were added
* List of all benchmark markers
*
* @var array
* @var array
*/
var $marker = array();
// --------------------------------------------------------------------
public $marker = array();
/**
* Set a benchmark marker
*
* Multiple calls to this function can be made so that several
* execution points can be timed
* execution points can be timed.
*
* @access public
* @param string $name name of the marker
* @param string $name Marker name
* @return void
*/
function mark($name)
public function mark($name)
{
$this->marker[$name] = microtime();
$this->marker[$name] = microtime(TRUE);
}
// --------------------------------------------------------------------
/**
* Elapsed time
*
* Calculates the time difference between two marked points.
*
* If the first parameter is empty this function instead returns the
@ -64,15 +84,17 @@ class CI_Benchmark {
* execution time to be shown in a template. The output class will
* swap the real value for this variable.
*
* @access public
* @param string a particular marked point
* @param string a particular marked point
* @param integer the number of decimal places
* @return mixed
* @param string $point1 A particular marked point
* @param string $point2 A particular marked point
* @param int $decimals Number of decimal places
*
* @return string Calculated elapsed time on success,
* an '{elapsed_string}' if $point1 is empty
* or an empty string if $point1 is not found.
*/
function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
public function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
{
if ($point1 == '')
if ($point1 === '')
{
return '{elapsed_time}';
}
@ -84,13 +106,10 @@ class CI_Benchmark {
if ( ! isset($this->marker[$point2]))
{
$this->marker[$point2] = microtime();
$this->marker[$point2] = microtime(TRUE);
}
list($sm, $ss) = explode(' ', $this->marker[$point1]);
list($em, $es) = explode(' ', $this->marker[$point2]);
return number_format(($em + $es) - ($sm + $ss), $decimals);
return number_format($this->marker[$point2] - $this->marker[$point1], $decimals);
}
// --------------------------------------------------------------------
@ -98,22 +117,17 @@ class CI_Benchmark {
/**
* Memory Usage
*
* This function returns the {memory_usage} pseudo-variable.
* Simply returns the {memory_usage} marker.
*
* This permits it to be put it anywhere in a template
* without the memory being calculated until the end.
* The output class will swap the real value for this variable.
*
* @access public
* @return string
* @return string '{memory_usage}'
*/
function memory_usage()
public function memory_usage()
{
return '{memory_usage}';
}
}
// END CI_Benchmark class
/* End of file Benchmark.php */
/* Location: ./system/core/Benchmark.php */

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* System Initialization File
@ -22,60 +43,98 @@
* Loads the base classes and executes the request.
*
* @package CodeIgniter
* @subpackage codeigniter
* @subpackage CodeIgniter
* @category Front-controller
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/
* @link https://codeigniter.com/user_guide/
*/
/**
* CodeIgniter Version
*
* @var string
* @var string
*
*/
define('CI_VERSION', '2.2.4');
/**
* CodeIgniter Branch (Core = TRUE, Reactor = FALSE)
*
* @var boolean
*
*/
define('CI_CORE', FALSE);
/*
* ------------------------------------------------------
* Load the global functions
* ------------------------------------------------------
*/
require(BASEPATH.'core/Common.php');
define('CI_VERSION', '3.0.6');
/*
* ------------------------------------------------------
* Load the framework constants
* ------------------------------------------------------
*/
if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
{
require(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
}
else
require_once(APPPATH.'config/constants.php');
/*
* ------------------------------------------------------
* Load the global functions
* ------------------------------------------------------
*/
require_once(BASEPATH.'core/Common.php');
/*
* ------------------------------------------------------
* Security procedures
* ------------------------------------------------------
*/
if ( ! is_php('5.4'))
{
ini_set('magic_quotes_runtime', 0);
if ((bool) ini_get('register_globals'))
{
require(APPPATH.'config/constants.php');
$_protected = array(
'_SERVER',
'_GET',
'_POST',
'_FILES',
'_REQUEST',
'_SESSION',
'_ENV',
'_COOKIE',
'GLOBALS',
'HTTP_RAW_POST_DATA',
'system_path',
'application_folder',
'view_folder',
'_protected',
'_registered'
);
$_registered = ini_get('variables_order');
foreach (array('E' => '_ENV', 'G' => '_GET', 'P' => '_POST', 'C' => '_COOKIE', 'S' => '_SERVER') as $key => $superglobal)
{
if (strpos($_registered, $key) === FALSE)
{
continue;
}
foreach (array_keys($$superglobal) as $var)
{
if (isset($GLOBALS[$var]) && ! in_array($var, $_protected, TRUE))
{
$GLOBALS[$var] = NULL;
}
}
}
}
}
/*
* ------------------------------------------------------
* Define a custom error handler so we can log PHP errors
* ------------------------------------------------------
*/
set_error_handler('_exception_handler');
if ( ! is_php('5.3'))
{
@set_magic_quotes_runtime(0); // Kill magic quotes
}
set_error_handler('_error_handler');
set_exception_handler('_exception_handler');
register_shutdown_function('_shutdown_handler');
/*
* ------------------------------------------------------
@ -86,26 +145,39 @@
* The subclass prefix allows CI to know if a core class is
* being extended via a library in the local application
* "libraries" folder. Since CI allows config items to be
* overriden via data set in the main index. php file,
* overridden via data set in the main index.php file,
* before proceeding we need to know if a subclass_prefix
* override exists. If so, we will set this value now,
* override exists. If so, we will set this value now,
* before any classes are loaded
* Note: Since the config file data is cached it doesn't
* hurt to load it here.
*/
if (isset($assign_to_config['subclass_prefix']) AND $assign_to_config['subclass_prefix'] != '')
if ( ! empty($assign_to_config['subclass_prefix']))
{
get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
}
/*
* ------------------------------------------------------
* Set a liberal script execution time limit
* Should we use a Composer autoloader?
* ------------------------------------------------------
*/
if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0)
if ($composer_autoload = config_item('composer_autoload'))
{
@set_time_limit(300);
if ($composer_autoload === TRUE)
{
file_exists(APPPATH.'vendor/autoload.php')
? require_once(APPPATH.'vendor/autoload.php')
: log_message('error', '$config[\'composer_autoload\'] is set to TRUE but '.APPPATH.'vendor/autoload.php was not found.');
}
elseif (file_exists($composer_autoload))
{
require_once($composer_autoload);
}
else
{
log_message('error', 'Could not find the specified $config[\'composer_autoload\'] path: '.$composer_autoload);
}
}
/*
@ -129,33 +201,96 @@
* Is there a "pre_system" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('pre_system');
$EXT->call_hook('pre_system');
/*
* ------------------------------------------------------
* Instantiate the config class
* ------------------------------------------------------
*
* Note: It is important that Config is loaded first as
* most other classes depend on it either directly or by
* depending on another class that uses it.
*
*/
$CFG =& load_class('Config', 'core');
// Do we have any manually set config items in the index.php file?
if (isset($assign_to_config))
if (isset($assign_to_config) && is_array($assign_to_config))
{
$CFG->_assign_to_config($assign_to_config);
foreach ($assign_to_config as $key => $value)
{
$CFG->set_item($key, $value);
}
}
/*
* ------------------------------------------------------
* Important charset-related stuff
* ------------------------------------------------------
*
* 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.
*
* Note: UTF-8 class depends on this. It used to be done
* in it's constructor, but it's _not_ class-specific.
*
*/
$charset = strtoupper(config_item('charset'));
ini_set('default_charset', $charset);
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.
@ini_set('mbstring.internal_encoding', $charset);
// This is required for mb_convert_encoding() to strip invalid characters.
// That's utilized by CI_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.
@ini_set('iconv.internal_encoding', $charset);
}
else
{
define('ICONV_ENABLED', FALSE);
}
if (is_php('5.6'))
{
ini_set('php.internal_encoding', $charset);
}
/*
* ------------------------------------------------------
* Load compatibility features
* ------------------------------------------------------
*/
require_once(BASEPATH.'core/compat/mbstring.php');
require_once(BASEPATH.'core/compat/hash.php');
require_once(BASEPATH.'core/compat/password.php');
require_once(BASEPATH.'core/compat/standard.php');
/*
* ------------------------------------------------------
* Instantiate the UTF-8 class
* ------------------------------------------------------
*
* Note: Order here is rather important as the UTF-8
* class needs to be used very early on, but it cannot
* properly determine if UTf-8 can be supported until
* after the Config class is instantiated.
*
*/
$UNI =& load_class('Utf8', 'core');
/*
@ -170,14 +305,7 @@
* Instantiate the routing class and set the routing
* ------------------------------------------------------
*/
$RTR =& load_class('Router', 'core');
$RTR->_set_routing();
// Set any routing overrides that may exist in the main index file
if (isset($routing))
{
$RTR->_set_overrides($routing);
}
$RTR =& load_class('Router', 'core', isset($routing) ? $routing : NULL);
/*
* ------------------------------------------------------
@ -188,15 +316,12 @@
/*
* ------------------------------------------------------
* Is there a valid cache file? If so, we're done...
* Is there a valid cache file? If so, we're done...
* ------------------------------------------------------
*/
if ($EXT->_call_hook('cache_override') === FALSE)
if ($EXT->call_hook('cache_override') === FALSE && $OUT->_display_cache($CFG, $URI) === TRUE)
{
if ($OUT->_display_cache($CFG, $URI) == TRUE)
{
exit;
}
exit;
}
/*
@ -227,76 +352,142 @@
*
*/
// Load the base controller class
require BASEPATH.'core/Controller.php';
require_once BASEPATH.'core/Controller.php';
/**
* Reference to the CI_Controller method.
*
* Returns current CI instance object
*
* @return CI_Controller
*/
function &get_instance()
{
return CI_Controller::get_instance();
}
if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
{
require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
require_once APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
}
// Load the local application controller
// Note: The Router class automatically validates the controller path using the router->_validate_request().
// If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.
if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'))
{
show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
}
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
// Set a mark point for benchmarking
$BM->mark('loading_time:_base_classes_end');
/*
* ------------------------------------------------------
* Security check
* Sanity checks
* ------------------------------------------------------
*
* None of the functions in the app controller or the
* loader class can be called via the URI, nor can
* controller functions that begin with an underscore
* The Router class has already validated the request,
* leaving us with 3 options here:
*
* 1) an empty class name, if we reached the default
* controller, but it didn't exist;
* 2) a query string which doesn't go through a
* file_exists() check
* 3) a regular request for a non-existing page
*
* We handle all of these as a 404 error.
*
* Furthermore, none of the methods in the app controller
* or the loader class can be called via the URI, nor can
* controller methods that begin with an underscore.
*/
$class = $RTR->fetch_class();
$method = $RTR->fetch_method();
if ( ! class_exists($class)
OR strncmp($method, '_', 1) == 0
OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
)
$e404 = FALSE;
$class = ucfirst($RTR->class);
$method = $RTR->method;
if (empty($class) OR ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php'))
{
$e404 = TRUE;
}
else
{
require_once(APPPATH.'controllers/'.$RTR->directory.$class.'.php');
if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
{
$e404 = TRUE;
}
elseif (method_exists($class, '_remap'))
{
$params = array($method, array_slice($URI->rsegments, 2));
$method = '_remap';
}
// WARNING: It appears that there are issues with is_callable() even in PHP 5.2!
// Furthermore, there are bug reports and feature/change requests related to it
// that make it unreliable to use in this context. Please, DO NOT change this
// work-around until a better alternative is available.
elseif ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE))
{
$e404 = TRUE;
}
}
if ($e404)
{
if ( ! empty($RTR->routes['404_override']))
{
$x = explode('/', $RTR->routes['404_override']);
$class = $x[0];
$method = (isset($x[1]) ? $x[1] : 'index');
if ( ! class_exists($class))
if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $error_class, $error_method) !== 2)
{
if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
{
show_404("{$class}/{$method}");
}
include_once(APPPATH.'controllers/'.$class.'.php');
$error_method = 'index';
}
$error_class = ucfirst($error_class);
if ( ! class_exists($error_class, FALSE))
{
if (file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php'))
{
require_once(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php');
$e404 = ! class_exists($error_class, FALSE);
}
// Were we in a directory? If so, check for a global override
elseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php'))
{
require_once(APPPATH.'controllers/'.$error_class.'.php');
if (($e404 = ! class_exists($error_class, FALSE)) === FALSE)
{
$RTR->directory = '';
}
}
}
else
{
$e404 = FALSE;
}
}
// Did we reset the $e404 flag? If so, set the rsegments, starting from index 1
if ( ! $e404)
{
$class = $error_class;
$method = $error_method;
$URI->rsegments = array(
1 => $class,
2 => $method
);
}
else
{
show_404("{$class}/{$method}");
show_404($RTR->directory.$class.'/'.$method);
}
}
if ($method !== '_remap')
{
$params = array_slice($URI->rsegments, 2);
}
/*
* ------------------------------------------------------
* Is there a "pre_controller" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('pre_controller');
$EXT->call_hook('pre_controller');
/*
* ------------------------------------------------------
@ -313,53 +504,14 @@
* Is there a "post_controller_constructor" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('post_controller_constructor');
$EXT->call_hook('post_controller_constructor');
/*
* ------------------------------------------------------
* Call the requested method
* ------------------------------------------------------
*/
// Is there a "remap" function? If so, we call it instead
if (method_exists($CI, '_remap'))
{
$CI->_remap($method, array_slice($URI->rsegments, 2));
}
else
{
// is_callable() returns TRUE on some versions of PHP 5 for private and protected
// methods, so we'll use this workaround for consistent behavior
if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
{
// Check and see if we are using a 404 override and use it.
if ( ! empty($RTR->routes['404_override']))
{
$x = explode('/', $RTR->routes['404_override']);
$class = $x[0];
$method = (isset($x[1]) ? $x[1] : 'index');
if ( ! class_exists($class))
{
if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
{
show_404("{$class}/{$method}");
}
include_once(APPPATH.'controllers/'.$class.'.php');
unset($CI);
$CI = new $class();
}
}
else
{
show_404("{$class}/{$method}");
}
}
// Call the requested method.
// Any URI segments present (besides the class/function) will be passed to the method for convenience
call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
}
call_user_func_array(array(&$CI, $method), $params);
// Mark a benchmark end point
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
@ -369,14 +521,14 @@
* Is there a "post_controller" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('post_controller');
$EXT->call_hook('post_controller');
/*
* ------------------------------------------------------
* Send the final rendered output to the browser
* ------------------------------------------------------
*/
if ($EXT->_call_hook('display_override') === FALSE)
if ($EXT->call_hook('display_override') === FALSE)
{
$OUT->_display();
}
@ -386,18 +538,4 @@
* Is there a "post_system" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('post_system');
/*
* ------------------------------------------------------
* Close the DB connection if one exists
* ------------------------------------------------------
*/
if (class_exists('CI_DB') AND isset($CI->db))
{
$CI->db->close();
}
/* End of file CodeIgniter.php */
/* Location: ./system/core/CodeIgniter.php */
$EXT->call_hook('post_system');

File diff suppressed because it is too large Load diff

View file

@ -1,23 +1,44 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter Config Class
* Config Class
*
* This class contains functions that enable config files to be managed
*
@ -25,57 +46,62 @@
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/config.html
* @link https://codeigniter.com/user_guide/libraries/config.html
*/
class CI_Config {
/**
* List of all loaded config values
*
* @var array
* @var array
*/
var $config = array();
public $config = array();
/**
* List of all loaded config files
*
* @var array
* @var array
*/
var $is_loaded = array();
/**
* List of paths to search when trying to load a config file
*
* @var array
*/
var $_config_paths = array(APPPATH);
public $is_loaded = array();
/**
* Constructor
* List of paths to search when trying to load a config file.
*
* Sets the $config data from the primary config.php file as a class variable
*
* @access public
* @param string the config file name
* @param boolean if configuration values should be loaded into their own section
* @param boolean true if errors should just return false, false if an error message should be displayed
* @return boolean if the file was successfully loaded or not
* @used-by CI_Loader
* @var array
*/
function __construct()
public $_config_paths = array(APPPATH);
// --------------------------------------------------------------------
/**
* Class constructor
*
* Sets the $config data from the primary config.php file as a class variable.
*
* @return void
*/
public function __construct()
{
$this->config =& get_config();
log_message('debug', "Config Class Initialized");
// Set the base_url automatically if none was provided
if ($this->config['base_url'] == '')
if (empty($this->config['base_url']))
{
// The regular expression is only a basic validation for a valid "Host" header.
// It's not exhaustive, only checks for valid characters.
if (isset($_SERVER['HTTP_HOST']) && preg_match('/^((\[[0-9a-f:]+\])|(\d{1,3}(\.\d{1,3}){3})|[a-z0-9\-\.]+)(:\d+)?$/i', $_SERVER['HTTP_HOST']))
if (isset($_SERVER['SERVER_ADDR']))
{
$base_url = (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off') ? 'http' : 'https';
$base_url .= '://'. $_SERVER['HTTP_HOST'];
$base_url .= substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
}
if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE)
{
$server_addr = '['.$_SERVER['SERVER_ADDR'].']';
}
else
{
$server_addr = $_SERVER['SERVER_ADDR'];
}
$base_url = (is_https() ? 'https' : 'http').'://'.$server_addr
.substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
}
else
{
$base_url = 'http://localhost/';
@ -83,6 +109,8 @@ class CI_Config {
$this->set_item('base_url', $base_url);
}
log_message('info', 'Config Class Initialized');
}
// --------------------------------------------------------------------
@ -90,91 +118,71 @@ class CI_Config {
/**
* Load Config File
*
* @access public
* @param string the config file name
* @param boolean if configuration values should be loaded into their own section
* @param boolean true if errors should just return false, false if an error message should be displayed
* @return boolean if the file was loaded correctly
* @param string $file Configuration file name
* @param bool $use_sections Whether configuration values should be loaded into their own section
* @param bool $fail_gracefully Whether to just return FALSE or display an error message
* @return bool TRUE if the file was loaded correctly or FALSE on failure
*/
function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
$file = ($file == '') ? 'config' : str_replace('.php', '', $file);
$found = FALSE;
$file = ($file === '') ? 'config' : str_replace('.php', '', $file);
$loaded = FALSE;
$check_locations = defined('ENVIRONMENT')
? array(ENVIRONMENT.'/'.$file, $file)
: array($file);
foreach ($this->_config_paths as $path)
{
foreach ($check_locations as $location)
foreach (array($file, ENVIRONMENT.DIRECTORY_SEPARATOR.$file) as $location)
{
$file_path = $path.'config/'.$location.'.php';
if (in_array($file_path, $this->is_loaded, TRUE))
{
$loaded = TRUE;
continue 2;
return TRUE;
}
if (file_exists($file_path))
if ( ! file_exists($file_path))
{
$found = TRUE;
break;
continue;
}
}
if ($found === FALSE)
{
continue;
}
include($file_path);
include($file_path);
if ( ! isset($config) OR ! is_array($config))
{
if ($fail_gracefully === TRUE)
if ( ! isset($config) OR ! is_array($config))
{
return FALSE;
if ($fail_gracefully === TRUE)
{
return FALSE;
}
show_error('Your '.$file_path.' file does not appear to contain a valid configuration array.');
}
show_error('Your '.$file_path.' file does not appear to contain a valid configuration array.');
}
if ($use_sections === TRUE)
{
if (isset($this->config[$file]))
if ($use_sections === TRUE)
{
$this->config[$file] = array_merge($this->config[$file], $config);
$this->config[$file] = isset($this->config[$file])
? array_merge($this->config[$file], $config)
: $config;
}
else
{
$this->config[$file] = $config;
$this->config = array_merge($this->config, $config);
}
}
else
{
$this->config = array_merge($this->config, $config);
}
$this->is_loaded[] = $file_path;
unset($config);
$loaded = TRUE;
log_message('debug', 'Config file loaded: '.$file_path);
break;
$this->is_loaded[] = $file_path;
$config = NULL;
$loaded = TRUE;
log_message('debug', 'Config file loaded: '.$file_path);
}
}
if ($loaded === FALSE)
if ($loaded === TRUE)
{
if ($fail_gracefully === TRUE)
{
return FALSE;
}
show_error('The configuration file '.$file.'.php does not exist.');
return TRUE;
}
elseif ($fail_gracefully === TRUE)
{
return FALSE;
}
return TRUE;
show_error('The configuration file '.$file.'.php does not exist.');
}
// --------------------------------------------------------------------
@ -182,59 +190,35 @@ class CI_Config {
/**
* Fetch a config file item
*
*
* @access public
* @param string the config item name
* @param string the index name
* @param bool
* @return string
* @param string $item Config item name
* @param string $index Index name
* @return string|null The configuration item or NULL if the item doesn't exist
*/
function item($item, $index = '')
public function item($item, $index = '')
{
if ($index == '')
{
if ( ! isset($this->config[$item]))
{
return FALSE;
}
$pref = $this->config[$item];
}
else
{
if ( ! isset($this->config[$index]))
{
return FALSE;
}
if ( ! isset($this->config[$index][$item]))
{
return FALSE;
}
$pref = $this->config[$index][$item];
return isset($this->config[$item]) ? $this->config[$item] : NULL;
}
return $pref;
return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : NULL;
}
// --------------------------------------------------------------------
/**
* Fetch a config file item - adds slash after item (if item is not empty)
* Fetch a config file item with slash appended (if not empty)
*
* @access public
* @param string the config item name
* @param bool
* @return string
* @param string $item Config item name
* @return string|null The configuration item or NULL if the item doesn't exist
*/
function slash_item($item)
public function slash_item($item)
{
if ( ! isset($this->config[$item]))
{
return FALSE;
return NULL;
}
if( trim($this->config[$item]) == '')
elseif (trim($this->config[$item]) === '')
{
return '';
}
@ -246,80 +230,125 @@ class CI_Config {
/**
* Site URL
*
* Returns base_url . index_page [. uri_string]
*
* @access public
* @param string the URI string
* @uses CI_Config::_uri_string()
*
* @param string|string[] $uri URI string or an array of segments
* @param string $protocol
* @return string
*/
function site_url($uri = '')
public function site_url($uri = '', $protocol = NULL)
{
if ($uri == '')
$base_url = $this->slash_item('base_url');
if (isset($protocol))
{
return $this->slash_item('base_url').$this->item('index_page');
// For protocol-relative links
if ($protocol === '')
{
$base_url = substr($base_url, strpos($base_url, '//'));
}
else
{
$base_url = $protocol.substr($base_url, strpos($base_url, '://'));
}
}
if ($this->item('enable_query_strings') == FALSE)
if (empty($uri))
{
$suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix;
return $base_url.$this->item('index_page');
}
else
$uri = $this->_uri_string($uri);
if ($this->item('enable_query_strings') === FALSE)
{
return $this->slash_item('base_url').$this->item('index_page').'?'.$this->_uri_string($uri);
$suffix = isset($this->config['url_suffix']) ? $this->config['url_suffix'] : '';
if ($suffix !== '')
{
if (($offset = strpos($uri, '?')) !== FALSE)
{
$uri = substr($uri, 0, $offset).$suffix.substr($uri, $offset);
}
else
{
$uri .= $suffix;
}
}
return $base_url.$this->slash_item('index_page').$uri;
}
elseif (strpos($uri, '?') === FALSE)
{
$uri = '?'.$uri;
}
return $base_url.$this->item('index_page').$uri;
}
// -------------------------------------------------------------
/**
* Base URL
*
* Returns base_url [. uri_string]
*
* @access public
* @param string $uri
* @return string
* @uses CI_Config::_uri_string()
*
* @param string|string[] $uri URI string or an array of segments
* @param string $protocol
* @return string
*/
function base_url($uri = '')
public function base_url($uri = '', $protocol = NULL)
{
return $this->slash_item('base_url').ltrim($this->_uri_string($uri), '/');
$base_url = $this->slash_item('base_url');
if (isset($protocol))
{
// For protocol-relative links
if ($protocol === '')
{
$base_url = substr($base_url, strpos($base_url, '//'));
}
else
{
$base_url = $protocol.substr($base_url, strpos($base_url, '://'));
}
}
return $base_url.ltrim($this->_uri_string($uri), '/');
}
// -------------------------------------------------------------
/**
* Build URI string for use in Config::site_url() and Config::base_url()
* Build URI string
*
* @access protected
* @param $uri
* @return string
* @used-by CI_Config::site_url()
* @used-by CI_Config::base_url()
*
* @param string|string[] $uri URI string or an array of segments
* @return string
*/
protected function _uri_string($uri)
{
if ($this->item('enable_query_strings') == FALSE)
if ($this->item('enable_query_strings') === FALSE)
{
if (is_array($uri))
{
$uri = implode('/', $uri);
}
$uri = trim($uri, '/');
return trim($uri, '/');
}
else
elseif (is_array($uri))
{
if (is_array($uri))
{
$i = 0;
$str = '';
foreach ($uri as $key => $val)
{
$prefix = ($i == 0) ? '' : '&';
$str .= $prefix.$key.'='.$val;
$i++;
}
$uri = $str;
}
return http_build_query($uri);
}
return $uri;
return $uri;
}
// --------------------------------------------------------------------
@ -327,12 +356,12 @@ class CI_Config {
/**
* System URL
*
* @access public
* @deprecated 3.0.0 Encourages insecure practices
* @return string
*/
function system_url()
public function system_url()
{
$x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));
$x = explode('/', preg_replace('|/*(.+?)/*$|', '\\1', BASEPATH));
return $this->slash_item('base_url').end($x).'/';
}
@ -341,42 +370,13 @@ class CI_Config {
/**
* Set a config file item
*
* @access public
* @param string the config item key
* @param string the config item value
* @param string $item Config item key
* @param string $value Config item value
* @return void
*/
function set_item($item, $value)
public function set_item($item, $value)
{
$this->config[$item] = $value;
}
// --------------------------------------------------------------------
/**
* Assign to Config
*
* This function is called by the front controller (CodeIgniter.php)
* after the Config class is instantiated. It permits config items
* to be assigned or overriden by variables contained in the index.php file
*
* @access private
* @param array
* @return void
*/
function _assign_to_config($items = array())
{
if (is_array($items))
{
foreach ($items as $key => $val)
{
$this->set_item($key, $val);
}
}
}
}
// END CI_Config class
/* End of file Config.php */
/* Location: ./system/core/Config.php */

View file

@ -1,23 +1,44 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter Application Controller Class
* Application Controller Class
*
* This class object is the super class that every library in
* CodeIgniter will be assigned to.
@ -26,14 +47,21 @@
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/general/controllers.html
* @link https://codeigniter.com/user_guide/general/controllers.html
*/
class CI_Controller {
/**
* Reference to the CI singleton
*
* @var object
*/
private static $instance;
/**
* Constructor
* Class constructor
*
* @return void
*/
public function __construct()
{
@ -48,18 +76,21 @@ class CI_Controller {
}
$this->load =& load_class('Loader', 'core');
$this->load->initialize();
log_message('debug', "Controller Class Initialized");
log_message('info', 'Controller Class Initialized');
}
// --------------------------------------------------------------------
/**
* Get the CI singleton
*
* @static
* @return object
*/
public static function &get_instance()
{
return self::$instance;
}
}
// END Controller class
/* End of file Controller.php */
/* Location: ./system/core/Controller.php */
}

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Exceptions Class
@ -23,52 +44,46 @@
* @subpackage Libraries
* @category Exceptions
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/exceptions.html
* @link https://codeigniter.com/user_guide/libraries/exceptions.html
*/
class CI_Exceptions {
var $action;
var $severity;
var $message;
var $filename;
var $line;
/**
* Nesting level of the output buffering mechanism
*
* @var int
* @access public
* @var int
*/
var $ob_level;
public $ob_level;
/**
* List if available error levels
* List of available error levels
*
* @var array
* @access public
* @var array
*/
var $levels = array(
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice'
);
public $levels = array(
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice'
);
/**
* Constructor
* Class constructor
*
* @return void
*/
public function __construct()
{
$this->ob_level = ob_get_level();
// Note: Do not log messages from this constructor.
// Note: Do not log messages from this constructor.
}
// --------------------------------------------------------------------
@ -76,45 +91,52 @@ class CI_Exceptions {
/**
* Exception Logger
*
* This function logs PHP generated error messages
* Logs PHP generated error messages
*
* @access private
* @param string the error severity
* @param string the error string
* @param string the error filepath
* @param string the error line number
* @return string
* @param int $severity Log level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return void
*/
function log_exception($severity, $message, $filepath, $line)
public function log_exception($severity, $message, $filepath, $line)
{
$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE);
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
log_message('error', 'Severity: '.$severity.' --> '.$message.' '.$filepath.' '.$line);
}
// --------------------------------------------------------------------
/**
* 404 Page Not Found Handler
* 404 Error Handler
*
* @access private
* @param string the page
* @param bool log error yes/no
* @return string
* @uses CI_Exceptions::show_error()
*
* @param string $page Page URI
* @param bool $log_error Whether to log the error
* @return void
*/
function show_404($page = '', $log_error = TRUE)
public function show_404($page = '', $log_error = TRUE)
{
$heading = "404 Page Not Found";
$message = "The page you requested was not found.";
if (is_cli())
{
$heading = 'Not Found';
$message = 'The controller/method pair you requested was not found.';
}
else
{
$heading = '404 Page Not Found';
$message = 'The page you requested was not found.';
}
// By default we log this, but allow a dev to skip it
if ($log_error)
{
log_message('error', '404 Page Not Found --> '.$page);
log_message('error', $heading.': '.$page);
}
echo $this->show_error($heading, $message, 'error_404', 404);
exit;
exit(4); // EXIT_UNKNOWN_FILE
}
// --------------------------------------------------------------------
@ -122,29 +144,42 @@ class CI_Exceptions {
/**
* General Error Page
*
* This function takes an error message as input
* (either as a string or an array) and displays
* it using the specified template.
* Takes an error message as input (either as a string or an array)
* and displays it using the specified template.
*
* @access private
* @param string the heading
* @param string the message
* @param string the template name
* @param int the status code
* @return string
* @param string $heading Page heading
* @param string|string[] $message Error message
* @param string $template Template name
* @param int $status_code (default: 500)
*
* @return string Error page output
*/
function show_error($heading, $message, $template = 'error_general', $status_code = 500)
public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
set_status_header($status_code);
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
$message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
if (is_cli())
{
$message = "\t".(is_array($message) ? implode("\n\t", $message) : $message);
$template = 'cli'.DIRECTORY_SEPARATOR.$template;
}
else
{
set_status_header($status_code);
$message = '<p>'.(is_array($message) ? implode('</p><p>', $message) : $message).'</p>';
$template = 'html'.DIRECTORY_SEPARATOR.$template;
}
if (ob_get_level() > $this->ob_level + 1)
{
ob_end_flush();
}
ob_start();
include(APPPATH.'errors/'.$template.'.php');
include($templates_path.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
@ -152,27 +187,78 @@ class CI_Exceptions {
// --------------------------------------------------------------------
public function show_exception($exception)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
$message = $exception->getMessage();
if (empty($message))
{
$message = '(null)';
}
if (is_cli())
{
$templates_path .= 'cli'.DIRECTORY_SEPARATOR;
}
else
{
set_status_header(500);
$templates_path .= 'html'.DIRECTORY_SEPARATOR;
}
if (ob_get_level() > $this->ob_level + 1)
{
ob_end_flush();
}
ob_start();
include($templates_path.'error_exception.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
}
// --------------------------------------------------------------------
/**
* Native PHP error handler
*
* @access private
* @param string the error severity
* @param string the error string
* @param string the error filepath
* @param string the error line number
* @return string
* @param int $severity Error level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return string Error page output
*/
function show_php_error($severity, $message, $filepath, $line)
public function show_php_error($severity, $message, $filepath, $line)
{
$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
$filepath = str_replace("\\", "/", $filepath);
// For safety reasons we do not show the full file path
if (FALSE !== strpos($filepath, '/'))
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$x = explode('/', $filepath);
$filepath = $x[count($x)-2].'/'.end($x);
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
// For safety reasons we don't show the full file path in non-CLI requests
if ( ! is_cli())
{
$filepath = str_replace('\\', '/', $filepath);
if (FALSE !== strpos($filepath, '/'))
{
$x = explode('/', $filepath);
$filepath = $x[count($x)-2].'/'.end($x);
}
$template = 'html'.DIRECTORY_SEPARATOR.'error_php';
}
else
{
$template = 'cli'.DIRECTORY_SEPARATOR.'error_php';
}
if (ob_get_level() > $this->ob_level + 1)
@ -180,15 +266,10 @@ class CI_Exceptions {
ob_end_flush();
}
ob_start();
include(APPPATH.'errors/error_php.php');
include($templates_path.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
}
}
// END Exceptions Class
/* End of file Exceptions.php */
/* Location: ./system/core/Exceptions.php */

View file

@ -1,23 +1,44 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter Hooks Class
* Hooks Class
*
* Provides a mechanism to extend the base system without hacking.
*
@ -25,72 +46,69 @@
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/encryption.html
* @link https://codeigniter.com/user_guide/general/hooks.html
*/
class CI_Hooks {
/**
* Determines wether hooks are enabled
* Determines whether hooks are enabled
*
* @var bool
* @var bool
*/
var $enabled = FALSE;
public $enabled = FALSE;
/**
* List of all hooks set in config/hooks.php
*
* @var array
*/
public $hooks = array();
/**
* Array with class objects to use hooks methods
*
* @var array
*/
var $hooks = array();
protected $_objects = array();
/**
* Determines wether hook is in progress, used to prevent infinte loops
* In progress flag
*
* @var bool
* Determines whether hook is in progress, used to prevent infinte loops
*
* @var bool
*/
var $in_progress = FALSE;
protected $_in_progress = FALSE;
/**
* Constructor
* Class constructor
*
*/
function __construct()
{
$this->_initialize();
log_message('debug', "Hooks Class Initialized");
}
// --------------------------------------------------------------------
/**
* Initialize the Hooks Preferences
*
* @access private
* @return void
*/
function _initialize()
public function __construct()
{
$CFG =& load_class('Config', 'core');
log_message('info', 'Hooks Class Initialized');
// If hooks are not enabled in the config file
// there is nothing else to do
if ($CFG->item('enable_hooks') == FALSE)
if ($CFG->item('enable_hooks') === FALSE)
{
return;
}
// Grab the "hooks" definition file.
// If there are no hooks, we're done.
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
}
elseif (is_file(APPPATH.'config/hooks.php'))
if (file_exists(APPPATH.'config/hooks.php'))
{
include(APPPATH.'config/hooks.php');
}
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
}
// If there are no hooks, we're done.
if ( ! isset($hook) OR ! is_array($hook))
{
return;
@ -105,20 +123,21 @@ class CI_Hooks {
/**
* Call Hook
*
* Calls a particular hook
* Calls a particular hook. Called by CodeIgniter.php.
*
* @access private
* @param string the hook name
* @return mixed
* @uses CI_Hooks::_run_hook()
*
* @param string $which Hook name
* @return bool TRUE on success or FALSE on failure
*/
function _call_hook($which = '')
public function call_hook($which = '')
{
if ( ! $this->enabled OR ! isset($this->hooks[$which]))
{
return FALSE;
}
if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function']))
{
foreach ($this->hooks[$which] as $val)
{
@ -140,13 +159,21 @@ class CI_Hooks {
*
* Runs a particular hook
*
* @access private
* @param array the hook details
* @return bool
* @param array $data Hook details
* @return bool TRUE on success or FALSE on failure
*/
function _run_hook($data)
protected function _run_hook($data)
{
if ( ! is_array($data))
// Closures/lambda functions and array($object, 'method') callables
if (is_callable($data))
{
is_array($data)
? $data[0]->{$data[1]}()
: $data();
return TRUE;
}
elseif ( ! is_array($data))
{
return FALSE;
}
@ -157,8 +184,7 @@ class CI_Hooks {
// If the script being called happens to have the same
// hook call within it a loop can happen
if ($this->in_progress == TRUE)
if ($this->_in_progress === TRUE)
{
return;
}
@ -167,7 +193,7 @@ class CI_Hooks {
// Set file path
// -----------------------------------
if ( ! isset($data['filepath']) OR ! isset($data['filename']))
if ( ! isset($data['filepath'], $data['filename']))
{
return FALSE;
}
@ -179,71 +205,62 @@ class CI_Hooks {
return FALSE;
}
// -----------------------------------
// Set class/function name
// -----------------------------------
// Determine and class and/or function names
$class = empty($data['class']) ? FALSE : $data['class'];
$function = empty($data['function']) ? FALSE : $data['function'];
$params = isset($data['params']) ? $data['params'] : '';
$class = FALSE;
$function = FALSE;
$params = '';
if (isset($data['class']) AND $data['class'] != '')
{
$class = $data['class'];
}
if (isset($data['function']))
{
$function = $data['function'];
}
if (isset($data['params']))
{
$params = $data['params'];
}
if ($class === FALSE AND $function === FALSE)
if (empty($function))
{
return FALSE;
}
// -----------------------------------
// Set the in_progress flag
// -----------------------------------
// Set the _in_progress flag
$this->_in_progress = TRUE;
$this->in_progress = TRUE;
// -----------------------------------
// Call the requested class and/or function
// -----------------------------------
if ($class !== FALSE)
{
if ( ! class_exists($class))
// The object is stored?
if (isset($this->_objects[$class]))
{
require($filepath);
if (method_exists($this->_objects[$class], $function))
{
$this->_objects[$class]->$function($params);
}
else
{
return $this->_in_progress = FALSE;
}
}
else
{
class_exists($class, FALSE) OR require_once($filepath);
$HOOK = new $class;
$HOOK->$function($params);
if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function))
{
return $this->_in_progress = FALSE;
}
// Store the object and execute the method
$this->_objects[$class] = new $class();
$this->_objects[$class]->$function($params);
}
}
else
{
function_exists($function) OR require_once($filepath);
if ( ! function_exists($function))
{
require($filepath);
return $this->_in_progress = FALSE;
}
$function($params);
}
$this->in_progress = FALSE;
$this->_in_progress = FALSE;
return TRUE;
}
}
// END CI_Hooks class
/* End of file Hooks.php */
/* Location: ./system/core/Hooks.php */

File diff suppressed because it is too large Load diff

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Language Class
@ -23,31 +44,32 @@
* @subpackage Libraries
* @category Language
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/language.html
* @link https://codeigniter.com/user_guide/libraries/language.html
*/
class CI_Lang {
/**
* List of translations
*
* @var array
* @var array
*/
var $language = array();
public $language = array();
/**
* List of loaded language files
*
* @var array
* @var array
*/
var $is_loaded = array();
public $is_loaded = array();
/**
* Constructor
* Class constructor
*
* @access public
* @return void
*/
function __construct()
public function __construct()
{
log_message('debug', "Language Class Initialized");
log_message('info', 'Language Class Initialized');
}
// --------------------------------------------------------------------
@ -55,98 +77,122 @@ class CI_Lang {
/**
* Load a language file
*
* @access public
* @param mixed the name of the language file to be loaded. Can be an array
* @param string the language (english, etc.)
* @param bool return loaded array of translations
* @param bool add suffix to $langfile
* @param string alternative path to look for language file
* @return mixed
* @param mixed $langfile Language file name
* @param string $idiom Language name (english, etc.)
* @param bool $return Whether to return the loaded array of translations
* @param bool $add_suffix Whether to add suffix to $langfile
* @param string $alt_path Alternative path to look for the language file
*
* @return void|string[] Array containing translations, if $return is set to TRUE
*/
function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
{
if (is_array($langfile))
{
foreach ($langfile as $value)
{
$this->load($value, $idiom, $return, $add_suffix, $alt_path);
}
return;
}
$langfile = str_replace('.php', '', $langfile);
if ($add_suffix == TRUE)
if ($add_suffix === TRUE)
{
$langfile = str_replace('_lang.', '', $langfile).'_lang';
$langfile = preg_replace('/_lang$/', '', $langfile).'_lang';
}
$langfile .= '.php';
if (in_array($langfile, $this->is_loaded, TRUE))
if (empty($idiom) OR ! preg_match('/^[a-z_-]+$/i', $idiom))
{
$config =& get_config();
$idiom = empty($config['language']) ? 'english' : $config['language'];
}
if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom)
{
return;
}
$config =& get_config();
if ($idiom == '')
// Load the base file, so any others found can override it
$basepath = BASEPATH.'language/'.$idiom.'/'.$langfile;
if (($found = file_exists($basepath)) === TRUE)
{
$deft_lang = ( ! isset($config['language'])) ? 'english' : $config['language'];
$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
include($basepath);
}
// Determine where the language file is and load it
if ($alt_path != '' && file_exists($alt_path.'language/'.$idiom.'/'.$langfile))
// Do we have an alternative path to look in?
if ($alt_path !== '')
{
include($alt_path.'language/'.$idiom.'/'.$langfile);
$alt_path .= 'language/'.$idiom.'/'.$langfile;
if (file_exists($alt_path))
{
include($alt_path);
$found = TRUE;
}
}
else
{
$found = FALSE;
foreach (get_instance()->load->get_package_paths(TRUE) as $package_path)
{
if (file_exists($package_path.'language/'.$idiom.'/'.$langfile))
$package_path .= 'language/'.$idiom.'/'.$langfile;
if ($basepath !== $package_path && file_exists($package_path))
{
include($package_path.'language/'.$idiom.'/'.$langfile);
include($package_path);
$found = TRUE;
break;
}
}
if ($found !== TRUE)
{
show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
}
}
if ($found !== TRUE)
{
show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
}
if ( ! isset($lang))
if ( ! isset($lang) OR ! is_array($lang))
{
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
if ($return === TRUE)
{
return array();
}
return;
}
if ($return == TRUE)
if ($return === TRUE)
{
return $lang;
}
$this->is_loaded[] = $langfile;
$this->is_loaded[$langfile] = $idiom;
$this->language = array_merge($this->language, $lang);
unset($lang);
log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
log_message('info', 'Language file loaded: language/'.$idiom.'/'.$langfile);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Fetch a single line of text from the language array
* Language line
*
* @access public
* @param string $line the language line
* @return string
* Fetches a single line of text from the language array
*
* @param string $line Language line key
* @param bool $log_errors Whether to log an error message if the line is not found
* @return string Translation
*/
function line($line = '')
public function line($line, $log_errors = TRUE)
{
$value = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
$value = isset($this->language[$line]) ? $this->language[$line] : FALSE;
// Because killer robots like unicorns!
if ($value === FALSE)
if ($value === FALSE && $log_errors === TRUE)
{
log_message('error', 'Could not find the language line "'.$line.'"');
}
@ -155,7 +201,3 @@ class CI_Lang {
}
}
// END Language Class
/* End of file Lang.php */
/* Location: ./system/core/Lang.php */

File diff suppressed because it is too large Load diff

247
src/system/core/Log.php Normal file
View file

@ -0,0 +1,247 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Logging Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Logging
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/general/errors.html
*/
class CI_Log {
/**
* Path to save log files
*
* @var string
*/
protected $_log_path;
/**
* File permissions
*
* @var int
*/
protected $_file_permissions = 0644;
/**
* Level of logging
*
* @var int
*/
protected $_threshold = 1;
/**
* Array of threshold levels to log
*
* @var array
*/
protected $_threshold_array = array();
/**
* Format of timestamp for log files
*
* @var string
*/
protected $_date_fmt = 'Y-m-d H:i:s';
/**
* Filename extension
*
* @var string
*/
protected $_file_ext;
/**
* Whether or not the logger can write to the log files
*
* @var bool
*/
protected $_enabled = TRUE;
/**
* Predefined logging levels
*
* @var array
*/
protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4);
// --------------------------------------------------------------------
/**
* Class constructor
*
* @return void
*/
public function __construct()
{
$config =& get_config();
$this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/';
$this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '')
? ltrim($config['log_file_extension'], '.') : 'php';
file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE);
if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path))
{
$this->_enabled = FALSE;
}
if (is_numeric($config['log_threshold']))
{
$this->_threshold = (int) $config['log_threshold'];
}
elseif (is_array($config['log_threshold']))
{
$this->_threshold = 0;
$this->_threshold_array = array_flip($config['log_threshold']);
}
if ( ! empty($config['log_date_format']))
{
$this->_date_fmt = $config['log_date_format'];
}
if ( ! empty($config['log_file_permissions']) && is_int($config['log_file_permissions']))
{
$this->_file_permissions = $config['log_file_permissions'];
}
}
// --------------------------------------------------------------------
/**
* Write Log File
*
* Generally this function will be called using the global log_message() function
*
* @param string $level The error level: 'error', 'debug' or 'info'
* @param string $msg The error message
* @return bool
*/
public function write_log($level, $msg)
{
if ($this->_enabled === FALSE)
{
return FALSE;
}
$level = strtoupper($level);
if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
&& ! isset($this->_threshold_array[$this->_levels[$level]]))
{
return FALSE;
}
$filepath = $this->_log_path.'log-'.date('Y-m-d').'.'.$this->_file_ext;
$message = '';
if ( ! file_exists($filepath))
{
$newfile = TRUE;
// Only add protection to php files
if ($this->_file_ext === 'php')
{
$message .= "<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n";
}
}
if ( ! $fp = @fopen($filepath, 'ab'))
{
return FALSE;
}
flock($fp, LOCK_EX);
// Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format
if (strpos($this->_date_fmt, 'u') !== FALSE)
{
$microtime_full = microtime(TRUE);
$microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000);
$date = new DateTime(date('Y-m-d H:i:s.'.$microtime_short, $microtime_full));
$date = $date->format($this->_date_fmt);
}
else
{
$date = date($this->_date_fmt);
}
$message .= $this->_format_line($level, $date, $msg);
for ($written = 0, $length = strlen($message); $written < $length; $written += $result)
{
if (($result = fwrite($fp, substr($message, $written))) === FALSE)
{
break;
}
}
flock($fp, LOCK_UN);
fclose($fp);
if (isset($newfile) && $newfile === TRUE)
{
chmod($filepath, $this->_file_permissions);
}
return is_int($result);
}
// --------------------------------------------------------------------
/**
* Format the log line.
*
* This is for extensibility of log formatting
* If you want to change the log format, extend the CI_Log class and override this method
*
* @param string $level The error level
* @param string $date Formatted date string
* @param string $msg The log message
* @return string Formatted log line with a new line character '\n' at the end
*/
protected function _format_line($level, $date, $message)
{
return $level.' - '.$date.' --> '.$message."\n";
}
}

View file

@ -1,58 +1,80 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter Model Class
* Model Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/config.html
* @link https://codeigniter.com/user_guide/libraries/config.html
*/
class CI_Model {
/**
* Constructor
* Class constructor
*
* @access public
* @return void
*/
function __construct()
public function __construct()
{
log_message('debug', "Model Class Initialized");
log_message('info', 'Model Class Initialized');
}
// --------------------------------------------------------------------
/**
* __get
* __get magic
*
* Allows models to access CI's loaded classes using the same
* syntax as controllers.
*
* @param string
* @access private
* @param string $key
*/
function __get($key)
public function __get($key)
{
$CI =& get_instance();
return $CI->$key;
// Debugging note:
// If you're here because you're getting an error message
// saying 'Undefined Property: system/core/Model.php', it's
// most likely a typo in your model code.
return get_instance()->$key;
}
}
// END Model Class
/* End of file Model.php */
/* Location: ./system/core/Model.php */
}

View file

@ -1,113 +1,147 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Output Class
*
* Responsible for sending final output to browser
* Responsible for sending final output to the browser.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Output
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/output.html
* @link https://codeigniter.com/user_guide/libraries/output.html
*/
class CI_Output {
/**
* Current output string
* Final output string
*
* @var string
* @access protected
* @var string
*/
protected $final_output;
public $final_output;
/**
* Cache expiration time
*
* @var int
* @access protected
* @var int
*/
protected $cache_expiration = 0;
public $cache_expiration = 0;
/**
* List of server headers
*
* @var array
* @access protected
* @var array
*/
protected $headers = array();
public $headers = array();
/**
* List of mime types
*
* @var array
* @access protected
* @var array
*/
protected $mime_types = array();
public $mimes = array();
/**
* Determines wether profiler is enabled
* Mime-type for the current page
*
* @var book
* @access protected
* @var string
*/
protected $enable_profiler = FALSE;
protected $mime_type = 'text/html';
/**
* Determines if output compression is enabled
* Enable Profiler flag
*
* @var bool
* @access protected
* @var bool
*/
protected $_zlib_oc = FALSE;
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
* @access protected
* @var array
*/
protected $_profiler_sections = array();
/**
* Whether or not to parse variables like {elapsed_time} and {memory_usage}
*
* @var bool
* @access protected
*/
protected $parse_exec_vars = TRUE;
protected $_profiler_sections = array();
/**
* Constructor
* Parse markers flag
*
* Whether or not to parse variables like {elapsed_time} and {memory_usage}.
*
* @var bool
*/
function __construct()
public $parse_exec_vars = TRUE;
/**
* Class constructor
*
* Determines whether zLib output compression will be used.
*
* @return void
*/
public function __construct()
{
$this->_zlib_oc = @ini_get('zlib.output_compression');
$this->_zlib_oc = (bool) ini_get('zlib.output_compression');
$this->_compress_output = (
$this->_zlib_oc === FALSE
&& config_item('compress_output') === TRUE
&& extension_loaded('zlib')
);
// Get mime types for later
if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
{
include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
}
else
{
include APPPATH.'config/mimes.php';
}
$this->mimes =& get_mimes();
$this->mime_types = $mimes;
log_message('debug', "Output Class Initialized");
log_message('info', 'Output Class Initialized');
}
// --------------------------------------------------------------------
@ -115,12 +149,11 @@ class CI_Output {
/**
* Get Output
*
* Returns the current output string
* Returns the current output string.
*
* @access public
* @return string
*/
function get_output()
public function get_output()
{
return $this->final_output;
}
@ -130,16 +163,14 @@ class CI_Output {
/**
* Set Output
*
* Sets the output string
* Sets the output string.
*
* @access public
* @param string
* @return void
* @param string $output Output data
* @return CI_Output
*/
function set_output($output)
public function set_output($output)
{
$this->final_output = $output;
return $this;
}
@ -148,23 +179,14 @@ class CI_Output {
/**
* Append Output
*
* Appends data onto the output string
* Appends data onto the output string.
*
* @access public
* @param string
* @return void
* @param string $output Data to append
* @return CI_Output
*/
function append_output($output)
public function append_output($output)
{
if ($this->final_output == '')
{
$this->final_output = $output;
}
else
{
$this->final_output .= $output;
}
$this->final_output .= $output;
return $this;
}
@ -173,52 +195,49 @@ class CI_Output {
/**
* Set Header
*
* Lets you set a server header which will be outputted with the final display.
* 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. We need to figure out
* how to permit header data to be saved with the cache data...
* Note: If a file is cached, headers will not be sent.
* @todo We need to figure out how to permit headers to be cached.
*
* @access public
* @param string
* @param bool
* @return void
* @param string $header Header
* @param bool $replace Whether to replace the old header value, if already set
* @return CI_Output
*/
function set_header($header, $replace = TRUE)
public function set_header($header, $replace = TRUE)
{
// 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)
if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0)
{
return;
return $this;
}
$this->headers[] = array($header, $replace);
return $this;
}
// --------------------------------------------------------------------
/**
* Set Content Type Header
* Set Content-Type Header
*
* @access public
* @param string extension of the file we're outputting
* @return void
* @param string $mime_type Extension of the file we're outputting
* @param string $charset Character set (default: NULL)
* @return CI_Output
*/
function set_content_type($mime_type)
public function set_content_type($mime_type, $charset = NULL)
{
if (strpos($mime_type, '/') === FALSE)
{
$extension = ltrim($mime_type, '.');
// Is this extension supported?
if (isset($this->mime_types[$extension]))
if (isset($this->mimes[$extension]))
{
$mime_type =& $this->mime_types[$extension];
$mime_type =& $this->mimes[$extension];
if (is_array($mime_type))
{
@ -227,28 +246,88 @@ class CI_Output {
}
}
$header = 'Content-Type: '.$mime_type;
$this->mime_type = $mime_type;
if (empty($charset))
{
$charset = config_item('charset');
}
$header = 'Content-Type: '.$mime_type
.(empty($charset) ? '' : '; charset='.$charset);
$this->headers[] = array($header, TRUE);
return $this;
}
// --------------------------------------------------------------------
/**
* Set HTTP Status Header
* moved to Common procedural functions in 1.7.2
* Get Current Content-Type Header
*
* @access public
* @param int the status code
* @param string
* @return void
* @return string 'text/html', if not already set
*/
function set_status_header($code = 200, $text = '')
public function get_content_type()
{
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
*/
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 CI_Output
*/
public function set_status_header($code = 200, $text = '')
{
set_status_header($code, $text);
return $this;
}
@ -257,14 +336,12 @@ class CI_Output {
/**
* Enable/disable Profiler
*
* @access public
* @param bool
* @return void
* @param bool $val TRUE to enable or FALSE to disable
* @return CI_Output
*/
function enable_profiler($val = TRUE)
public function enable_profiler($val = TRUE)
{
$this->enable_profiler = (is_bool($val)) ? $val : TRUE;
$this->enable_profiler = is_bool($val) ? $val : TRUE;
return $this;
}
@ -273,17 +350,23 @@ class CI_Output {
/**
* Set Profiler Sections
*
* Allows override of default / config settings for Profiler section display
* Allows override of default/config settings for
* Profiler section display.
*
* @access public
* @param array
* @return void
* @param array $sections Profiler sections
* @return CI_Output
*/
function set_profiler_sections($sections)
public function set_profiler_sections($sections)
{
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) ? TRUE : FALSE;
$this->_profiler_sections[$section] = ($enable !== FALSE);
}
return $this;
@ -294,14 +377,12 @@ class CI_Output {
/**
* Set Cache
*
* @access public
* @param integer
* @return void
* @param int $time Cache expiration time in minutes
* @return CI_Output
*/
function cache($time)
public function cache($time)
{
$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
$this->cache_expiration = is_numeric($time) ? $time : 0;
return $this;
}
@ -310,27 +391,27 @@ class CI_Output {
/**
* Display Output
*
* All "view" data is automatically put into this variable by the controller class:
* 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.
*
* $this->final_output
* Note: All "view" data is automatically put into $this->final_output
* by controller class.
*
* This function sends the finalized output data to the browser along
* with any server headers and profile data. It also stops the
* benchmark timer so the page rendering speed and memory usage can be shown.
*
* @access public
* @param string
* @return mixed
* @uses CI_Output::$final_output
* @param string $output Output data override
* @return void
*/
function _display($output = '')
public function _display($output = '')
{
// Note: We use globals because we can't use $CI =& get_instance()
// Note: We use load_class() because we can't use $CI =& get_instance()
// since this function is sometimes called by the caching mechanism,
// which happens before the CI super object is available.
global $BM, $CFG;
$BM =& load_class('Benchmark', 'core');
$CFG =& load_class('Config', 'core');
// Grab the super object if we can.
if (class_exists('CI_Controller'))
if (class_exists('CI_Controller', FALSE))
{
$CI =& get_instance();
}
@ -338,14 +419,14 @@ class CI_Output {
// --------------------------------------------------------------------
// Set the output data
if ($output == '')
if ($output === '')
{
$output =& $this->final_output;
}
// --------------------------------------------------------------------
// Do we need to write a cache file? Only if the controller does not have its
// 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 && isset($CI) && ! method_exists($CI, '_output'))
@ -362,24 +443,18 @@ class CI_Output {
if ($this->parse_exec_vars === TRUE)
{
$memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
$output = str_replace('{elapsed_time}', $elapsed, $output);
$output = str_replace('{memory_usage}', $memory, $output);
$memory = round(memory_get_usage() / 1024 / 1024, 2).'MB';
$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
}
// --------------------------------------------------------------------
// Is compression requested?
if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)
if (isset($CI) // 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)
{
if (extension_loaded('zlib'))
{
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
{
ob_start('ob_gzhandler');
}
}
ob_start('ob_gzhandler');
}
// --------------------------------------------------------------------
@ -400,20 +475,34 @@ class CI_Output {
// simply echo out the data and exit.
if ( ! isset($CI))
{
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;
log_message('debug', "Final output sent to browser");
log_message('debug', "Total execution time: ".$elapsed);
return TRUE;
log_message('info', 'Final output sent to browser');
log_message('debug', 'Total execution time: '.$elapsed);
return;
}
// --------------------------------------------------------------------
// Do we need to generate profile data?
// If so, load the Profile class and run it.
if ($this->enable_profiler == TRUE)
if ($this->enable_profiler === TRUE)
{
$CI->load->library('profiler');
if ( ! empty($this->_profiler_sections))
{
$CI->profiler->set_sections($this->_profiler_sections);
@ -421,20 +510,13 @@ class CI_Output {
// If the output data contains closing </body> and </html> tags
// we will remove them and add them back after we insert the profile data
if (preg_match("|</body>.*?</html>|is", $output))
$output = preg_replace('|</body>.*?</html>|is', '', $output, -1, $count).$CI->profiler->run();
if ($count > 0)
{
$output = preg_replace("|</body>.*?</html>|is", '', $output);
$output .= $CI->profiler->run();
$output .= '</body></html>';
}
else
{
$output .= $CI->profiler->run();
}
}
// --------------------------------------------------------------------
// Does the controller contain a function named _output()?
// If so send the output there. Otherwise, echo it.
if (method_exists($CI, '_output'))
@ -443,133 +525,276 @@ class CI_Output {
}
else
{
echo $output; // Send it to the browser!
echo $output; // Send it to the browser!
}
log_message('debug', "Final output sent to browser");
log_message('debug', "Total execution time: ".$elapsed);
log_message('info', 'Final output sent to browser');
log_message('debug', 'Total execution time: '.$elapsed);
}
// --------------------------------------------------------------------
/**
* Write a Cache File
* Write Cache
*
* @access public
* @param string
* @param string $output Output data to cache
* @return void
*/
function _write_cache($output)
public function _write_cache($output)
{
$CI =& get_instance();
$path = $CI->config->item('cache_path');
$cache_path = ($path == '') ? APPPATH.'cache/' : $path;
$cache_path = ($path === '') ? APPPATH.'cache/' : $path;
if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
{
log_message('error', "Unable to write cache file: ".$cache_path);
log_message('error', 'Unable to write cache file: '.$cache_path);
return;
}
$uri = $CI->config->item('base_url').
$CI->config->item('index_page').
$CI->uri->uri_string();
$uri = $CI->config->item('base_url')
.$CI->config->item('index_page')
.$CI->uri->uri_string();
if (($cache_query_string = $CI->config->item('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, FOPEN_WRITE_CREATE_DESTRUCTIVE))
if ( ! $fp = @fopen($cache_path, 'w+b'))
{
log_message('error', "Unable to write cache file: ".$cache_path);
log_message('error', 'Unable to write cache file: '.$cache_path);
return;
}
$expire = time() + ($this->cache_expiration * 60);
if (flock($fp, LOCK_EX))
{
fwrite($fp, $expire.'TS--->'.$output);
// 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
{
log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
log_message('error', 'Unable to secure a file lock for file at: '.$cache_path);
return;
}
fclose($fp);
@chmod($cache_path, FILE_WRITE_MODE);
log_message('debug', "Cache file written: ".$cache_path);
fclose($fp);
if (is_int($result))
{
chmod($cache_path, 0640);
log_message('debug', '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);
log_message('error', 'Unable to write the complete cache content at: '.$cache_path);
}
}
// --------------------------------------------------------------------
/**
* Update/serve a cached file
* Update/serve cached output
*
* @access public
* @param object config class
* @param object uri class
* @return void
* @uses CI_Config
* @uses CI_URI
*
* @param object &$CFG CI_Config class instance
* @param object &$URI CI_URI class instance
* @return bool TRUE on success or FALSE on failure
*/
function _display_cache(&$CFG, &$URI)
public function _display_cache(&$CFG, &$URI)
{
$cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');
$cache_path = ($CFG->item('cache_path') === '') ? APPPATH.'cache/' : $CFG->item('cache_path');
// Build the file path. The file name is an MD5 hash of the full URI
$uri = $CFG->item('base_url').
$CFG->item('index_page').
$URI->uri_string;
// Build the file path. The file name is an MD5 hash of the full URI
$uri = $CFG->item('base_url').$CFG->item('index_page').$URI->uri_string;
if (($cache_query_string = $CFG->item('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))
{
return FALSE;
}
if ( ! $fp = @fopen($filepath, FOPEN_READ))
if ( ! file_exists($filepath) OR ! $fp = @fopen($filepath, 'rb'))
{
return FALSE;
}
flock($fp, LOCK_SH);
$cache = '';
if (filesize($filepath) > 0)
{
$cache = fread($fp, filesize($filepath));
}
$cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : '';
flock($fp, LOCK_UN);
fclose($fp);
// Strip out the embedded timestamp
if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
// Look for embedded serialized file info.
if ( ! preg_match('/^(.*)ENDCI--->/', $cache, $match))
{
return FALSE;
}
// Has the file expired? If so we'll delete it.
if (time() >= trim(str_replace('TS--->', '', $match['1'])))
$cache_info = unserialize($match[1]);
$expire = $cache_info['expire'];
$last_modified = filemtime($filepath);
// Has the file expired?
if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))
{
if (is_really_writable($cache_path))
{
@unlink($filepath);
log_message('debug', "Cache file has expired. File deleted");
return FALSE;
}
// If so we'll delete it.
@unlink($filepath);
log_message('debug', '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(str_replace($match['0'], '', $cache));
log_message('debug', "Cache file is current. Sending it to browser.");
$this->_display(substr($cache, strlen($match[0])));
log_message('debug', 'Cache file is current. Sending it to browser.');
return TRUE;
}
// --------------------------------------------------------------------
/**
* Delete cache
*
* @param string $uri URI string
* @return bool
*/
public function delete_cache($uri = '')
{
$CI =& get_instance();
$cache_path = $CI->config->item('cache_path');
if ($cache_path === '')
{
$cache_path = APPPATH.'cache/';
}
if ( ! is_dir($cache_path))
{
log_message('error', 'Unable to find cache path: '.$cache_path);
return FALSE;
}
if (empty($uri))
{
$uri = $CI->uri->uri_string();
if (($cache_query_string = $CI->config->item('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($CI->config->item('base_url').$CI->config->item('index_page').ltrim($uri, '/'));
if ( ! @unlink($cache_path))
{
log_message('error', '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');
}
}
}
// END Output Class
/* End of file Output.php */
/* Location: ./system/core/Output.php */

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Router Class
@ -23,389 +44,394 @@
*
* @package CodeIgniter
* @subpackage Libraries
* @author EllisLab Dev Team
* @category Libraries
* @link http://codeigniter.com/user_guide/general/routing.html
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/general/routing.html
*/
class CI_Router {
/**
* Config class
* CI_Config class object
*
* @var object
* @access public
* @var object
*/
var $config;
public $config;
/**
* List of routes
*
* @var array
* @access public
* @var array
*/
var $routes = array();
/**
* List of error routes
*
* @var array
* @access public
*/
var $error_routes = array();
public $routes = array();
/**
* Current class name
*
* @var string
* @access public
* @var string
*/
var $class = '';
public $class = '';
/**
* Current method name
*
* @var string
* @access public
* @var string
*/
var $method = 'index';
public $method = 'index';
/**
* Sub-directory that contains the requested controller class
*
* @var string
* @access public
* @var string
*/
var $directory = '';
public $directory;
/**
* Default controller (and method if specific)
*
* @var string
* @access public
* @var string
*/
var $default_controller;
public $default_controller;
/**
* Constructor
* Translate URI dashes
*
* Determines whether dashes in controller & method segments
* should be automatically replaced by underscores.
*
* @var bool
*/
public $translate_uri_dashes = FALSE;
/**
* Enable query strings flag
*
* Determines whether to use GET parameters or segment URIs
*
* @var bool
*/
public $enable_query_strings = FALSE;
// --------------------------------------------------------------------
/**
* Class constructor
*
* Runs the route mapping function.
*
* @param array $routing
* @return void
*/
function __construct()
public function __construct($routing = NULL)
{
$this->config =& load_class('Config', 'core');
$this->uri =& load_class('URI', 'core');
log_message('debug', "Router Class Initialized");
$this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE);
// If a directory override is configured, it has to be set before any dynamic routing logic
is_array($routing) && isset($routing['directory']) && $this->set_directory($routing['directory']);
$this->_set_routing();
// Set any routing overrides that may exist in the main index file
if (is_array($routing))
{
empty($routing['controller']) OR $this->set_class($routing['controller']);
empty($routing['function']) OR $this->set_method($routing['function']);
}
log_message('info', 'Router Class Initialized');
}
// --------------------------------------------------------------------
/**
* Set the route mapping
* Set route mapping
*
* This function determines what should be served based on the URI request,
* Determines what should be served based on the URI request,
* as well as any "routes" that have been set in the routing config file.
*
* @access private
* @return void
*/
function _set_routing()
protected function _set_routing()
{
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
// since URI segments are more search-engine friendly, but they can optionally be used.
// If this feature is enabled, we will gather the directory/class/method a little differently
$segments = array();
if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
{
if (isset($_GET[$this->config->item('directory_trigger')]))
{
$this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')])));
$segments[] = $this->fetch_directory();
}
if (isset($_GET[$this->config->item('controller_trigger')]))
{
$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
$segments[] = $this->fetch_class();
}
if (isset($_GET[$this->config->item('function_trigger')]))
{
$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
$segments[] = $this->fetch_method();
}
}
// Load the routes.php file.
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
}
elseif (is_file(APPPATH.'config/routes.php'))
// Load the routes.php file. It would be great if we could
// skip this for enable_query_strings = TRUE, but then
// default_controller would be empty ...
if (file_exists(APPPATH.'config/routes.php'))
{
include(APPPATH.'config/routes.php');
}
$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
unset($route);
// Set the default controller so we can display it in the event
// the URI doesn't correlated to a valid controller.
$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);
// Were there any query string segments? If so, we'll validate them and bail out since we're done.
if (count($segments) > 0)
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
{
return $this->_validate_request($segments);
include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
}
// Fetch the complete URI string
$this->uri->_fetch_uri_string();
// Is there a URI string? If not, the default controller specified in the "routes" file will be shown.
if ($this->uri->uri_string == '')
// Validate & get reserved routes
if (isset($route) && is_array($route))
{
return $this->_set_default_controller();
isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
unset($route['default_controller'], $route['translate_uri_dashes']);
$this->routes = $route;
}
// Do we need to remove the URL suffix?
$this->uri->_remove_url_suffix();
// Compile the segments into an array
$this->uri->_explode_segments();
// Parse any custom routing that may exist
$this->_parse_routes();
// Re-index the segment array so that it starts with 1 rather than 0
$this->uri->_reindex_segments();
}
// --------------------------------------------------------------------
/**
* Set the default controller
*
* @access private
* @return void
*/
function _set_default_controller()
{
if ($this->default_controller === FALSE)
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
// since URI segments are more search-engine friendly, but they can optionally be used.
// If this feature is enabled, we will gather the directory/class/method a little differently
if ($this->enable_query_strings)
{
show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");
// If the directory is set at this time, it means an override exists, so skip the checks
if ( ! isset($this->directory))
{
$_d = $this->config->item('directory_trigger');
$_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : '';
if ($_d !== '')
{
$this->uri->filter_uri($_d);
$this->set_directory($_d);
}
}
$_c = trim($this->config->item('controller_trigger'));
if ( ! empty($_GET[$_c]))
{
$this->uri->filter_uri($_GET[$_c]);
$this->set_class($_GET[$_c]);
$_f = trim($this->config->item('function_trigger'));
if ( ! empty($_GET[$_f]))
{
$this->uri->filter_uri($_GET[$_f]);
$this->set_method($_GET[$_f]);
}
$this->uri->rsegments = array(
1 => $this->class,
2 => $this->method
);
}
else
{
$this->_set_default_controller();
}
// Routing rules don't apply to query strings and we don't need to detect
// directories, so we're done here
return;
}
// Is the method being specified?
if (strpos($this->default_controller, '/') !== FALSE)
{
$x = explode('/', $this->default_controller);
$this->set_class($x[0]);
$this->set_method($x[1]);
$this->_set_request($x);
// Is there anything to parse?
if ($this->uri->uri_string !== '')
{
$this->_parse_routes();
}
else
{
$this->set_class($this->default_controller);
$this->set_method('index');
$this->_set_request(array($this->default_controller, 'index'));
$this->_set_default_controller();
}
// re-index the routed segments array so it starts with 1 rather than 0
$this->uri->_reindex_segments();
log_message('debug', "No URI present. Default controller set.");
}
// --------------------------------------------------------------------
/**
* Set the Route
* Set request route
*
* This function takes an array of URI segments as
* input, and sets the current class/method
* Takes an array of URI segments as input and sets the class/method
* to be called.
*
* @access private
* @param array
* @param bool
* @used-by CI_Router::_parse_routes()
* @param array $segments URI segments
* @return void
*/
function _set_request($segments = array())
protected function _set_request($segments = array())
{
$segments = $this->_validate_request($segments);
if (count($segments) == 0)
// If we don't have any segments left - try the default controller;
// WARNING: Directories get shifted out of the segments array!
if (empty($segments))
{
return $this->_set_default_controller();
$this->_set_default_controller();
return;
}
if ($this->translate_uri_dashes === TRUE)
{
$segments[0] = str_replace('-', '_', $segments[0]);
if (isset($segments[1]))
{
$segments[1] = str_replace('-', '_', $segments[1]);
}
}
$this->set_class($segments[0]);
if (isset($segments[1]))
{
// A standard method request
$this->set_method($segments[1]);
}
else
{
// This lets the "routed" segment array identify that the default
// index method is being used.
$segments[1] = 'index';
}
// Update our "routed" segment array to contain the segments.
// Note: If there is no custom routing, this array will be
// identical to $this->uri->segments
array_unshift($segments, NULL);
unset($segments[0]);
$this->uri->rsegments = $segments;
}
// --------------------------------------------------------------------
/**
* Validates the supplied segments. Attempts to determine the path to
* the controller.
* Set default controller
*
* @access private
* @param array
* @return array
* @return void
*/
function _validate_request($segments)
protected function _set_default_controller()
{
if (count($segments) == 0)
if (empty($this->default_controller))
{
return $segments;
show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
}
// Does the requested controller exist in the root folder?
if (file_exists(APPPATH.'controllers/'.$segments[0].'.php'))
// Is the method being specified?
if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
{
return $segments;
$method = 'index';
}
// Is the controller in a sub-folder?
if (is_dir(APPPATH.'controllers/'.$segments[0]))
if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php'))
{
// Set the directory and remove it from the segment array
$this->set_directory($segments[0]);
$segments = array_slice($segments, 1);
if (count($segments) > 0)
{
// Does the requested controller exist in the sub-folder?
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php'))
{
if ( ! empty($this->routes['404_override']))
{
$x = explode('/', $this->routes['404_override']);
$this->set_directory('');
$this->set_class($x[0]);
$this->set_method(isset($x[1]) ? $x[1] : 'index');
return $x;
}
else
{
show_404($this->fetch_directory().$segments[0]);
}
}
}
else
{
// Is the method being specified in the route?
if (strpos($this->default_controller, '/') !== FALSE)
{
$x = explode('/', $this->default_controller);
$this->set_class($x[0]);
$this->set_method($x[1]);
}
else
{
$this->set_class($this->default_controller);
$this->set_method('index');
}
// Does the default controller exist in the sub-folder?
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php'))
{
$this->directory = '';
return array();
}
}
return $segments;
// This will trigger 404 later
return;
}
$this->set_class($class);
$this->set_method($method);
// If we've gotten this far it means that the URI does not correlate to a valid
// controller class. We will now see if there is an override
if ( ! empty($this->routes['404_override']))
{
$x = explode('/', $this->routes['404_override']);
// Assign routed segments, index starting from 1
$this->uri->rsegments = array(
1 => $class,
2 => $method
);
$this->set_class($x[0]);
$this->set_method(isset($x[1]) ? $x[1] : 'index');
return $x;
}
// Nothing else to do at this point but show a 404
show_404($segments[0]);
log_message('debug', 'No URI present. Default controller set.');
}
// --------------------------------------------------------------------
/**
* Parse Routes
* Validate request
*
* This function matches any routes that may exist in
* the config/routes.php file against the URI to
* determine if the class/method need to be remapped.
* Attempts validate the URI request and determine the controller path.
*
* @used-by CI_Router::_set_request()
* @param array $segments URI segments
* @return mixed URI segments
*/
protected function _validate_request($segments)
{
$c = count($segments);
$directory_override = isset($this->directory);
// Loop through our segments and return as soon as a controller
// is found or when such a directory doesn't exist
while ($c-- > 0)
{
$test = $this->directory
.ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
if ( ! file_exists(APPPATH.'controllers/'.$test.'.php')
&& $directory_override === FALSE
&& is_dir(APPPATH.'controllers/'.$this->directory.$segments[0])
)
{
$this->set_directory(array_shift($segments), TRUE);
continue;
}
return $segments;
}
// This means that all segments were actually directories
return $segments;
}
// --------------------------------------------------------------------
/**
* Parse Routes
*
* Matches any routes that may exist in the config/routes.php file
* against the URI to determine if the class/method need to be remapped.
*
* @access private
* @return void
*/
function _parse_routes()
protected function _parse_routes()
{
// Turn the segment array into a URI string
$uri = implode('/', $this->uri->segments);
// Is there a literal match? If so we're done
if (isset($this->routes[$uri]))
{
return $this->_set_request(explode('/', $this->routes[$uri]));
}
// Get HTTP verb
$http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli';
// Loop through the route array looking for wild-cards
// Loop through the route array looking for wildcards
foreach ($this->routes as $key => $val)
{
// Convert wild-cards to RegEx
$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
// Check if route format is using HTTP verbs
if (is_array($val))
{
$val = array_change_key_case($val, CASE_LOWER);
if (isset($val[$http_verb]))
{
$val = $val[$http_verb];
}
else
{
continue;
}
}
// Convert wildcards to RegEx
$key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);
// Does the RegEx match?
if (preg_match('#^'.$key.'$#', $uri))
if (preg_match('#^'.$key.'$#', $uri, $matches))
{
// Do we have a back-reference?
if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
// Are we using callbacks to process back-references?
if ( ! is_string($val) && is_callable($val))
{
// Remove the original string from the matches array.
array_shift($matches);
// Execute the callback using the values in matches as its parameters.
$val = call_user_func_array($val, $matches);
}
// Are we using the default routing method for back-references?
elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
{
$val = preg_replace('#^'.$key.'$#', $val, $uri);
}
return $this->_set_request(explode('/', $val));
$this->_set_request(explode('/', $val));
return;
}
}
// If we got this far it means we didn't encounter a
// matching route so we'll set the site default route
$this->_set_request($this->uri->segments);
$this->_set_request(array_values($this->uri->segments));
}
// --------------------------------------------------------------------
/**
* Set the class name
* Set class name
*
* @access public
* @param string
* @param string $class Class name
* @return void
*/
function set_class($class)
public function set_class($class)
{
$this->class = str_replace(array('/', '.'), '', $class);
}
@ -415,10 +441,10 @@ class CI_Router {
/**
* Fetch the current class
*
* @access public
* @deprecated 3.0.0 Read the 'class' property instead
* @return string
*/
function fetch_class()
public function fetch_class()
{
return $this->class;
}
@ -426,13 +452,12 @@ class CI_Router {
// --------------------------------------------------------------------
/**
* Set the method name
* Set method name
*
* @access public
* @param string
* @param string $method Method name
* @return void
*/
function set_method($method)
public function set_method($method)
{
$this->method = $method;
}
@ -440,84 +465,51 @@ class CI_Router {
// --------------------------------------------------------------------
/**
* Fetch the current method
* Fetch the current method
*
* @access public
* @deprecated 3.0.0 Read the 'method' property instead
* @return string
*/
function fetch_method()
public function fetch_method()
{
if ($this->method == $this->fetch_class())
{
return 'index';
}
return $this->method;
}
// --------------------------------------------------------------------
/**
* Set the directory name
* Set directory name
*
* @access public
* @param string
* @param string $dir Directory name
* @param bool $append Whether we're appending rather than setting the full value
* @return void
*/
function set_directory($dir)
public function set_directory($dir, $append = FALSE)
{
$this->directory = str_replace(array('/', '.'), '', $dir).'/';
if ($append !== TRUE OR empty($this->directory))
{
$this->directory = str_replace('.', '', trim($dir, '/')).'/';
}
else
{
$this->directory .= str_replace('.', '', trim($dir, '/')).'/';
}
}
// --------------------------------------------------------------------
/**
* Fetch the sub-directory (if any) that contains the requested controller class
* Fetch directory
*
* @access public
* Feches the sub-directory (if any) that contains the requested
* controller class.
*
* @deprecated 3.0.0 Read the 'directory' property instead
* @return string
*/
function fetch_directory()
public function fetch_directory()
{
return $this->directory;
}
// --------------------------------------------------------------------
/**
* Set the controller overrides
*
* @access public
* @param array
* @return null
*/
function _set_overrides($routing)
{
if ( ! is_array($routing))
{
return;
}
if (isset($routing['directory']))
{
$this->set_directory($routing['directory']);
}
if (isset($routing['controller']) AND $routing['controller'] != '')
{
$this->set_class($routing['controller']);
}
if (isset($routing['function']))
{
$routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function'];
$this->set_method($routing['function']);
}
}
}
// END Router Class
/* End of file Router.php */
/* Location: ./system/core/Router.php */

File diff suppressed because it is too large Load diff

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* URI Class
@ -25,381 +46,367 @@
* @subpackage Libraries
* @category URI
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/uri.html
* @link https://codeigniter.com/user_guide/libraries/uri.html
*/
class CI_URI {
/**
* List of cached uri segments
* List of cached URI segments
*
* @var array
* @access public
* @var array
*/
var $keyval = array();
/**
* Current uri string
*
* @var string
* @access public
*/
var $uri_string;
/**
* List of uri segments
*
* @var array
* @access public
*/
var $segments = array();
/**
* Re-indexed list of uri segments
* Starts at 1 instead of 0
*
* @var array
* @access public
*/
var $rsegments = array();
public $keyval = array();
/**
* Constructor
* Current URI string
*
* Simply globalizes the $RTR object. The front
* loads the Router class early on so it's not available
* normally as other classes are.
*
* @access public
* @var string
*/
function __construct()
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;
/**
* Class constructor
*
* @return void
*/
public function __construct()
{
$this->config =& load_class('Config', 'core');
log_message('debug', "URI Class Initialized");
}
// --------------------------------------------------------------------
/**
* Get the URI String
*
* @access private
* @return string
*/
function _fetch_uri_string()
{
if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
// If query strings are enabled, we don't need to parse any segments.
// However, they don't make sense under CLI.
if (is_cli() OR $this->config->item('enable_query_strings') !== TRUE)
{
// Is the request coming from the command line?
if (php_sapi_name() == 'cli' or defined('STDIN'))
$this->_permitted_uri_chars = $this->config->item('permitted_uri_chars');
// If it's a CLI request, ignore the configuration
if (is_cli())
{
$this->_set_uri_string($this->_parse_cli_args());
return;
$uri = $this->_parse_argv();
}
else
{
$protocol = $this->config->item('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':
default:
$uri = isset($_SERVER[$protocol])
? $_SERVER[$protocol]
: $this->_parse_request_uri();
break;
}
}
// Let's try the REQUEST_URI first, this will work in most situations
if ($uri = $this->_detect_uri())
{
$this->_set_uri_string($uri);
return;
}
// Is there a PATH_INFO variable?
// Note: some servers seem to have trouble with getenv() so we'll test it two ways
$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
if (trim($path, '/') != '' && $path != "/".SELF)
{
$this->_set_uri_string($path);
return;
}
// No PATH_INFO?... What about QUERY_STRING?
$path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path, '/') != '')
{
$this->_set_uri_string($path);
return;
}
// As a last ditch effort lets try using the $_GET array
if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
{
$this->_set_uri_string(key($_GET));
return;
}
// We've exhausted all our options...
$this->uri_string = '';
return;
$this->_set_uri_string($uri);
}
$uri = strtoupper($this->config->item('uri_protocol'));
if ($uri == 'REQUEST_URI')
{
$this->_set_uri_string($this->_detect_uri());
return;
}
elseif ($uri == 'CLI')
{
$this->_set_uri_string($this->_parse_cli_args());
return;
}
$path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
$this->_set_uri_string($path);
log_message('info', 'URI Class Initialized');
}
// --------------------------------------------------------------------
/**
* Set the URI String
* Set URI String
*
* @access public
* @param string
* @return string
* @param string $str
* @return void
*/
function _set_uri_string($str)
protected function _set_uri_string($str)
{
// Filter out control characters
$str = remove_invisible_characters($str, FALSE);
// Filter out control characters and trim slashes
$this->uri_string = trim(remove_invisible_characters($str, FALSE), '/');
// If the URI contains only a slash we'll kill it
$this->uri_string = ($str == '/') ? '' : $str;
if ($this->uri_string !== '')
{
// Remove the URL suffix, if present
if (($suffix = (string) $this->config->item('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;
// Populate the segments array
foreach (explode('/', trim($this->uri_string, '/')) as $val)
{
$val = trim($val);
// Filter segments for security
$this->filter_uri($val);
if ($val !== '')
{
$this->segments[] = $val;
}
}
unset($this->segments[0]);
}
}
// --------------------------------------------------------------------
/**
* Detects the URI
* Parse REQUEST_URI
*
* This function will detect the URI automatically and fix the query string
* if necessary.
* Will parse REQUEST_URI and automatically detect the URI from it,
* while fixing the query string if necessary.
*
* @access private
* @return string
*/
private function _detect_uri()
protected function _parse_request_uri()
{
if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
{
return '';
}
$uri = $_SERVER['REQUEST_URI'];
if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
// 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]))
{
$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
}
elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
{
$uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
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 (strncmp($uri, '?/', 2) === 0)
if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0)
{
$uri = substr($uri, 2);
}
$parts = preg_split('#\?#i', $uri, 2);
$uri = $parts[0];
if (isset($parts[1]))
{
$_SERVER['QUERY_STRING'] = $parts[1];
parse_str($_SERVER['QUERY_STRING'], $_GET);
$query = explode('?', $query, 2);
$uri = $query[0];
$_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : '';
}
else
{
$_SERVER['QUERY_STRING'] = '';
$_GET = array();
$_SERVER['QUERY_STRING'] = $query;
}
if ($uri == '/' || empty($uri))
parse_str($_SERVER['QUERY_STRING'], $_GET);
if ($uri === '/' OR $uri === '')
{
return '/';
}
$uri = parse_url($uri, PHP_URL_PATH);
// Do some final cleaning of the URI and return it
return str_replace(array('//', '../'), '/', trim($uri, '/'));
return $this->_remove_relative_directory($uri);
}
// --------------------------------------------------------------------
/**
* Parse cli arguments
* Parse QUERY_STRING
*
* Will parse QUERY_STRING and automatically detect the URI from it.
*
* @return string
*/
protected function _parse_query_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.
*
* @access private
* @return string
*/
private function _parse_cli_args()
protected function _parse_argv()
{
$args = array_slice($_SERVER['argv'], 1);
return $args ? '/' . implode('/', $args) : '';
return $args ? implode('/', $args) : '';
}
// --------------------------------------------------------------------
/**
* Filter segments for malicious characters
* Remove relative directory (../) and multi slashes (///)
*
* @access private
* @param string
* Do some final cleaning of the URI and return it, currently only used in self::_parse_request_uri()
*
* @param string $uri
* @return string
*/
function _filter_uri($str)
protected function _remove_relative_directory($uri)
{
if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
$uris = array();
$tok = strtok($uri, '/');
while ($tok !== FALSE)
{
// preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
// compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str))
if (( ! empty($tok) OR $tok === '0') && $tok !== '..')
{
show_error('The URI you submitted has disallowed characters.', 400);
$uris[] = $tok;
}
$tok = strtok('/');
}
// Convert programatic characters to entities
$bad = array('$', '(', ')', '%28', '%29');
$good = array('&#36;', '&#40;', '&#41;', '&#40;', '&#41;');
return str_replace($bad, $good, $str);
return implode('/', $uris);
}
// --------------------------------------------------------------------
/**
* Remove the suffix from the URL if needed
* Filter URI
*
* @access private
* Filters segments for malicious characters.
*
* @param string $str
* @return void
*/
function _remove_url_suffix()
public function filter_uri(&$str)
{
if ($this->config->item('url_suffix') != "")
if ( ! empty($str) && ! empty($this->_permitted_uri_chars) && ! preg_match('/^['.$this->_permitted_uri_chars.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $str))
{
$this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);
show_error('The URI you submitted has disallowed characters.', 400);
}
}
// --------------------------------------------------------------------
/**
* Explode the URI Segments. The individual segments will
* be stored in the $this->segments array.
* Fetch URI Segment
*
* @access private
* @return void
* @see CI_URI::$segments
* @param int $n Index
* @param mixed $no_result What to return if the segment index is not found
* @return mixed
*/
function _explode_segments()
public function segment($n, $no_result = NULL)
{
foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
{
// Filter segments for security
$val = trim($this->_filter_uri($val));
if ($val != '')
{
$this->segments[] = $val;
}
}
}
// --------------------------------------------------------------------
/**
* Re-index Segments
*
* This function re-indexes the $this->segment array so that it
* starts at 1 rather than 0. Doing so makes it simpler to
* use functions like $this->uri->segment(n) since there is
* a 1:1 relationship between the segment array and the actual segments.
*
* @access private
* @return void
*/
function _reindex_segments()
{
array_unshift($this->segments, NULL);
array_unshift($this->rsegments, NULL);
unset($this->segments[0]);
unset($this->rsegments[0]);
return isset($this->segments[$n]) ? $this->segments[$n] : $no_result;
}
// --------------------------------------------------------------------
/**
* Fetch a URI Segment
* Fetch URI "routed" Segment
*
* This function returns the URI segment based on the number provided.
* 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 CI_URI::segment().
*
* @access public
* @param integer
* @param bool
* @return string
* @see CI_URI::$rsegments
* @see CI_URI::segment()
* @param int $n Index
* @param mixed $no_result What to return if the segment index is not found
* @return mixed
*/
function segment($n, $no_result = FALSE)
public function rsegment($n, $no_result = NULL)
{
return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
return isset($this->rsegments[$n]) ? $this->rsegments[$n] : $no_result;
}
// --------------------------------------------------------------------
/**
* Fetch a URI "routed" Segment
* URI to assoc
*
* This function returns the re-routed URI segment (assuming routing rules are used)
* based on the number provided. If there is no routing this function returns the
* same result as $this->segment()
*
* @access public
* @param integer
* @param bool
* @return string
*/
function rsegment($n, $no_result = FALSE)
{
return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
}
// --------------------------------------------------------------------
/**
* Generate a key value pair from the URI string
*
* This function generates and associative array of URI data starting
* at the supplied segment. For example, if this is your URI:
* 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 function to generate an array with this prototype:
* You can use this method to generate an array with this prototype:
*
* array (
* name => joe
* location => UK
* gender => male
* )
* array (
* name => joe
* location => UK
* gender => male
* )
*
* @access public
* @param integer the starting segment number
* @param array an array of default values
* @param int $n Index (default: 3)
* @param array $default Default values
* @return array
*/
function uri_to_assoc($n = 3, $default = array())
public function uri_to_assoc($n = 3, $default = array())
{
return $this->_uri_to_assoc($n, $default, 'segment');
}
// --------------------------------------------------------------------
/**
* Identical to above only it uses the re-routed segment array
* Routed URI to assoc
*
* @access public
* @param integer the starting segment number
* @param array an array of default values
* Identical to CI_URI::uri_to_assoc(), only it uses the re-routed
* segment array.
*
* @see CI_URI::uri_to_assoc()
* @param int $n Index (default: 3)
* @param array $default Default values
* @return array
*
*/
function ruri_to_assoc($n = 3, $default = array())
public function ruri_to_assoc($n = 3, $default = array())
{
return $this->_uri_to_assoc($n, $default, 'rsegment');
}
@ -407,57 +414,43 @@ class CI_URI {
// --------------------------------------------------------------------
/**
* Generate a key value pair from the URI string or Re-routed URI string
* Internal URI-to-assoc
*
* @access private
* @param integer the starting segment number
* @param array an array of default values
* @param string which array we should use
* Generates a key/value pair from the URI string or re-routed URI string.
*
* @used-by CI_URI::uri_to_assoc()
* @used-by CI_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
*/
function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
{
if ($which == 'segment')
{
$total_segments = 'total_segments';
$segment_array = 'segment_array';
}
else
{
$total_segments = 'total_rsegments';
$segment_array = 'rsegment_array';
}
if ( ! is_numeric($n))
{
return $default;
}
if (isset($this->keyval[$n]))
if (isset($this->keyval[$which], $this->keyval[$which][$n]))
{
return $this->keyval[$n];
return $this->keyval[$which][$n];
}
$total_segments = "total_{$which}s";
$segment_array = "{$which}_array";
if ($this->$total_segments() < $n)
{
if (count($default) == 0)
{
return array();
}
$retval = array();
foreach ($default as $val)
{
$retval[$val] = FALSE;
}
return $retval;
return (count($default) === 0)
? array()
: array_fill_keys($default, NULL);
}
$segments = array_slice($this->$segment_array(), ($n - 1));
$i = 0;
$lastval = '';
$retval = array();
$retval = array();
foreach ($segments as $seg)
{
if ($i % 2)
@ -466,7 +459,7 @@ class CI_URI {
}
else
{
$retval[$seg] = FALSE;
$retval[$seg] = NULL;
$lastval = $seg;
}
@ -479,30 +472,31 @@ class CI_URI {
{
if ( ! array_key_exists($val, $retval))
{
$retval[$val] = FALSE;
$retval[$val] = NULL;
}
}
}
// Cache the array for reuse
$this->keyval[$n] = $retval;
isset($this->keyval[$which]) OR $this->keyval[$which] = array();
$this->keyval[$which][$n] = $retval;
return $retval;
}
// --------------------------------------------------------------------
/**
* Generate a URI string from an associative array
* Assoc to URI
*
* Generates a URI string from an associative array.
*
* @access public
* @param array an associative array of key/values
* @return array
* @param array $array Input array of key/value pairs
* @return string URI string
*/
function assoc_to_uri($array)
public function assoc_to_uri($array)
{
$temp = array();
foreach ((array)$array as $key => $val)
foreach ((array) $array as $key => $val)
{
$temp[] = $key;
$temp[] = $val;
@ -514,14 +508,15 @@ class CI_URI {
// --------------------------------------------------------------------
/**
* Fetch a URI Segment and add a trailing slash
* Slash segment
*
* @access public
* @param integer
* @param string
* Fetches an URI segment with a slash.
*
* @param int $n Index
* @param string $where Where to add the slash ('trailing' or 'leading')
* @return string
*/
function slash_segment($n, $where = 'trailing')
public function slash_segment($n, $where = 'trailing')
{
return $this->_slash_segment($n, $where, 'segment');
}
@ -529,14 +524,15 @@ class CI_URI {
// --------------------------------------------------------------------
/**
* Fetch a URI Segment and add a trailing slash
* Slash routed segment
*
* @access public
* @param integer
* @param string
* 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
*/
function slash_rsegment($n, $where = 'trailing')
public function slash_rsegment($n, $where = 'trailing')
{
return $this->_slash_segment($n, $where, 'rsegment');
}
@ -544,24 +540,27 @@ class CI_URI {
// --------------------------------------------------------------------
/**
* Fetch a URI Segment and add a trailing slash - helper function
* Internal Slash segment
*
* @access private
* @param integer
* @param string
* @param string
* Fetches an URI Segment and adds a slash to it.
*
* @used-by CI_URI::slash_segment()
* @used-by CI_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
*/
function _slash_segment($n, $where = 'trailing', $which = 'segment')
protected function _slash_segment($n, $where = 'trailing', $which = 'segment')
{
$leading = '/';
$trailing = '/';
$leading = $trailing = '/';
if ($where == 'trailing')
if ($where === 'trailing')
{
$leading = '';
}
elseif ($where == 'leading')
elseif ($where === 'leading')
{
$trailing = '';
}
@ -574,10 +573,9 @@ class CI_URI {
/**
* Segment Array
*
* @access public
* @return array
* @return array CI_URI::$segments
*/
function segment_array()
public function segment_array()
{
return $this->segments;
}
@ -587,10 +585,9 @@ class CI_URI {
/**
* Routed Segment Array
*
* @access public
* @return array
* @return array CI_URI::$rsegments
*/
function rsegment_array()
public function rsegment_array()
{
return $this->rsegments;
}
@ -600,10 +597,9 @@ class CI_URI {
/**
* Total number of segments
*
* @access public
* @return integer
* @return int
*/
function total_segments()
public function total_segments()
{
return count($this->segments);
}
@ -613,10 +609,9 @@ class CI_URI {
/**
* Total number of routed segments
*
* @access public
* @return integer
* @return int
*/
function total_rsegments()
public function total_rsegments()
{
return count($this->rsegments);
}
@ -624,32 +619,25 @@ class CI_URI {
// --------------------------------------------------------------------
/**
* Fetch the entire URI string
* Fetch URI string
*
* @access public
* @return string
* @return string CI_URI::$uri_string
*/
function uri_string()
public function uri_string()
{
return $this->uri_string;
}
// --------------------------------------------------------------------
/**
* Fetch the entire Re-routed URI string
* Fetch Re-routed URI string
*
* @access public
* @return string
*/
function ruri_string()
public function ruri_string()
{
return '/'.implode('/', $this->rsegment_array());
return ltrim(load_class('Router', 'core')->directory, '/').implode('/', $this->rsegments);
}
}
// END URI Class
/* End of file URI.php */
/* Location: ./system/core/URI.php */

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 2.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 2.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Utf8 Class
@ -25,51 +46,35 @@
* @subpackage Libraries
* @category UTF-8
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/utf8.html
* @link https://codeigniter.com/user_guide/libraries/utf8.html
*/
class CI_Utf8 {
/**
* Constructor
* Class constructor
*
* Determines if UTF-8 support is to be enabled
* Determines if UTF-8 support is to be enabled.
*
* @return void
*/
function __construct()
public function __construct()
{
log_message('debug', "Utf8 Class Initialized");
global $CFG;
if (
preg_match('/./u', 'é') === 1 // PCRE must support UTF-8
AND function_exists('iconv') // iconv must be installed
AND ini_get('mbstring.func_overload') != 1 // Multibyte string function overloading cannot be enabled
AND $CFG->item('charset') == 'UTF-8' // Application charset must be UTF-8
defined('PREG_BAD_UTF8_ERROR') // PCRE must support UTF-8
&& (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) // iconv or mbstring must be installed
&& strtoupper(config_item('charset')) === 'UTF-8' // Application charset must be UTF-8
)
{
log_message('debug', "UTF-8 Support Enabled");
define('UTF8_ENABLED', TRUE);
// set internal encoding for multibyte string functions if necessary
// and set a flag so we don't have to repeatedly use extension_loaded()
// or function_exists()
if (extension_loaded('mbstring'))
{
define('MB_ENABLED', TRUE);
mb_internal_encoding('UTF-8');
}
else
{
define('MB_ENABLED', FALSE);
}
log_message('debug', 'UTF-8 Support Enabled');
}
else
{
log_message('debug', "UTF-8 Support Disabled");
define('UTF8_ENABLED', FALSE);
log_message('debug', 'UTF-8 Support Disabled');
}
log_message('info', 'Utf8 Class Initialized');
}
// --------------------------------------------------------------------
@ -77,17 +82,23 @@ class CI_Utf8 {
/**
* Clean UTF-8 strings
*
* Ensures strings are UTF-8
* Ensures strings contain only valid UTF-8 characters.
*
* @access public
* @param string
* @param string $str String to clean
* @return string
*/
function clean_string($str)
public function clean_string($str)
{
if ($this->_is_ascii($str) === FALSE)
if ($this->is_ascii($str) === FALSE)
{
$str = @iconv('UTF-8', 'UTF-8//IGNORE', $str);
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;
@ -100,13 +111,12 @@ class CI_Utf8 {
*
* Removes all ASCII control characters except horizontal tabs,
* line feeds, and carriage returns, as all others can cause
* problems in XML
* problems in XML.
*
* @access public
* @param string
* @param string $str String to clean
* @return string
*/
function safe_ascii_for_xml($str)
public function safe_ascii_for_xml($str)
{
return remove_invisible_characters($str, FALSE);
}
@ -116,29 +126,24 @@ class CI_Utf8 {
/**
* Convert to UTF-8
*
* Attempts to convert a string to UTF-8
* Attempts to convert a string to UTF-8.
*
* @access public
* @param string
* @param string - input encoding
* @return string
* @param string $str Input string
* @param string $encoding Input encoding
* @return string $str encoded in UTF-8 or FALSE on failure
*/
function convert_to_utf8($str, $encoding)
public function convert_to_utf8($str, $encoding)
{
if (function_exists('iconv'))
if (MB_ENABLED)
{
$str = @iconv($encoding, 'UTF-8', $str);
return mb_convert_encoding($str, 'UTF-8', $encoding);
}
elseif (function_exists('mb_convert_encoding'))
elseif (ICONV_ENABLED)
{
$str = @mb_convert_encoding($str, 'UTF-8', $encoding);
}
else
{
return FALSE;
return @iconv($encoding, 'UTF-8', $str);
}
return $str;
return FALSE;
}
// --------------------------------------------------------------------
@ -146,21 +151,14 @@ class CI_Utf8 {
/**
* Is ASCII?
*
* Tests if a string is standard 7-bit ASCII or not
* Tests if a string is standard 7-bit ASCII or not.
*
* @access public
* @param string
* @param string $str String to check
* @return bool
*/
function _is_ascii($str)
public function is_ascii($str)
{
return (preg_match('/[^\x00-\x7F]/S', $str) == 0);
return (preg_match('/[^\x00-\x7F]/S', $str) === 0);
}
// --------------------------------------------------------------------
}
// End Utf8 Class
/* End of file Utf8.php */
/* Location: ./system/core/Utf8.php */

View file

@ -0,0 +1,245 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/hash compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
* @link http://php.net/hash
*/
// ------------------------------------------------------------------------
if (is_php('5.6'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('hash_equals'))
{
/**
* hash_equals()
*
* @link http://php.net/hash_equals
* @param string $known_string
* @param string $user_string
* @return bool
*/
function hash_equals($known_string, $user_string)
{
if ( ! is_string($known_string))
{
trigger_error('hash_equals(): Expected known_string to be a string, '.strtolower(gettype($known_string)).' given', E_USER_WARNING);
return FALSE;
}
elseif ( ! is_string($user_string))
{
trigger_error('hash_equals(): Expected user_string to be a string, '.strtolower(gettype($user_string)).' given', E_USER_WARNING);
return FALSE;
}
elseif (($length = strlen($known_string)) !== strlen($user_string))
{
return FALSE;
}
$diff = 0;
for ($i = 0; $i < $length; $i++)
{
$diff |= ord($known_string[$i]) ^ ord($user_string[$i]);
}
return ($diff === 0);
}
}
// ------------------------------------------------------------------------
if (is_php('5.5'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('hash_pbkdf2'))
{
/**
* hash_pbkdf2()
*
* @link http://php.net/hash_pbkdf2
* @param string $algo
* @param string $password
* @param string $salt
* @param int $iterations
* @param int $length
* @param bool $raw_output
* @return string
*/
function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = FALSE)
{
if ( ! in_array($algo, hash_algos(), TRUE))
{
trigger_error('hash_pbkdf2(): Unknown hashing algorithm: '.$algo, E_USER_WARNING);
return FALSE;
}
if (($type = gettype($iterations)) !== 'integer')
{
if ($type === 'object' && method_exists($iterations, '__toString'))
{
$iterations = (string) $iterations;
}
if (is_string($iterations) && is_numeric($iterations))
{
$iterations = (int) $iterations;
}
else
{
trigger_error('hash_pbkdf2() expects parameter 4 to be long, '.$type.' given', E_USER_WARNING);
return NULL;
}
}
if ($iterations < 1)
{
trigger_error('hash_pbkdf2(): Iterations must be a positive integer: '.$iterations, E_USER_WARNING);
return FALSE;
}
if (($type = gettype($length)) !== 'integer')
{
if ($type === 'object' && method_exists($length, '__toString'))
{
$length = (string) $length;
}
if (is_string($length) && is_numeric($length))
{
$length = (int) $length;
}
else
{
trigger_error('hash_pbkdf2() expects parameter 5 to be long, '.$type.' given', E_USER_WARNING);
return NULL;
}
}
if ($length < 0)
{
trigger_error('hash_pbkdf2(): Length must be greater than or equal to 0: '.$length, E_USER_WARNING);
return FALSE;
}
$hash_length = strlen(hash($algo, NULL, TRUE));
empty($length) && $length = $hash_length;
// Pre-hash password inputs longer than the algorithm's block size
// (i.e. prepare HMAC key) to mitigate potential DoS attacks.
static $block_sizes;
empty($block_sizes) && $block_sizes = array(
'gost' => 32,
'haval128,3' => 128,
'haval160,3' => 128,
'haval192,3' => 128,
'haval224,3' => 128,
'haval256,3' => 128,
'haval128,4' => 128,
'haval160,4' => 128,
'haval192,4' => 128,
'haval224,4' => 128,
'haval256,4' => 128,
'haval128,5' => 128,
'haval160,5' => 128,
'haval192,5' => 128,
'haval224,5' => 128,
'haval256,5' => 128,
'md2' => 16,
'md4' => 64,
'md5' => 64,
'ripemd128' => 64,
'ripemd160' => 64,
'ripemd256' => 64,
'ripemd320' => 64,
'salsa10' => 64,
'salsa20' => 64,
'sha1' => 64,
'sha224' => 64,
'sha256' => 64,
'sha384' => 128,
'sha512' => 128,
'snefru' => 32,
'snefru256' => 32,
'tiger128,3' => 64,
'tiger160,3' => 64,
'tiger192,3' => 64,
'tiger128,4' => 64,
'tiger160,4' => 64,
'tiger192,4' => 64,
'whirlpool' => 64
);
if (isset($block_sizes[$algo]) && strlen($password) > $block_sizes[$algo])
{
$password = hash($algo, $password, TRUE);
}
$hash = '';
// Note: Blocks are NOT 0-indexed
for ($bc = ceil($length / $hash_length), $bi = 1; $bi <= $bc; $bi++)
{
$key = $derived_key = hash_hmac($algo, $salt.pack('N', $bi), $password, TRUE);
for ($i = 1; $i < $iterations; $i++)
{
$derived_key ^= $key = hash_hmac($algo, $key, $password, TRUE);
}
$hash .= $derived_key;
}
// This is not RFC-compatible, but we're aiming for natural PHP compatibility
return substr($raw_output ? $hash : bin2hex($hash), 0, $length);
}
}

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View file

@ -0,0 +1,149 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/mbstring compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
* @link http://php.net/mbstring
*/
// ------------------------------------------------------------------------
if (MB_ENABLED === TRUE)
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('mb_strlen'))
{
/**
* mb_strlen()
*
* WARNING: This function WILL fall-back to strlen()
* if iconv is not available!
*
* @link http://php.net/mb_strlen
* @param string $str
* @param string $encoding
* @return string
*/
function mb_strlen($str, $encoding = NULL)
{
if (ICONV_ENABLED === TRUE)
{
return iconv_strlen($str, isset($encoding) ? $encoding : config_item('charset'));
}
log_message('debug', 'Compatibility (mbstring): iconv_strlen() is not available, falling back to strlen().');
return strlen($str);
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('mb_strpos'))
{
/**
* mb_strpos()
*
* WARNING: This function WILL fall-back to strpos()
* if iconv is not available!
*
* @link http://php.net/mb_strpos
* @param string $haystack
* @param string $needle
* @param int $offset
* @param string $encoding
* @return mixed
*/
function mb_strpos($haystack, $needle, $offset = 0, $encoding = NULL)
{
if (ICONV_ENABLED === TRUE)
{
return iconv_strpos($haystack, $needle, $offset, isset($encoding) ? $encoding : config_item('charset'));
}
log_message('debug', 'Compatibility (mbstring): iconv_strpos() is not available, falling back to strpos().');
return strpos($haystack, $needle, $offset);
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('mb_substr'))
{
/**
* mb_substr()
*
* WARNING: This function WILL fall-back to substr()
* if iconv is not available.
*
* @link http://php.net/mb_substr
* @param string $str
* @param int $start
* @param int $length
* @param string $encoding
* @return string
*/
function mb_substr($str, $start, $length = NULL, $encoding = NULL)
{
if (ICONV_ENABLED === TRUE)
{
isset($encoding) OR $encoding = config_item('charset');
return iconv_substr(
$str,
$start,
isset($length) ? $length : iconv_strlen($str, $encoding), // NULL doesn't work
$encoding
);
}
log_message('debug', 'Compatibility (mbstring): iconv_substr() is not available, falling back to substr().');
return isset($length)
? substr($str, $start, $length)
: substr($str, $start);
}
}

View file

@ -0,0 +1,233 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/standard/password compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
* @link http://php.net/password
*/
// ------------------------------------------------------------------------
if (is_php('5.5') OR ! is_php('5.3.7') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1 OR defined('HHVM_VERSION'))
{
return;
}
// ------------------------------------------------------------------------
defined('PASSWORD_BCRYPT') OR define('PASSWORD_BCRYPT', 1);
defined('PASSWORD_DEFAULT') OR define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
// ------------------------------------------------------------------------
if ( ! function_exists('password_get_info'))
{
/**
* password_get_info()
*
* @link http://php.net/password_get_info
* @param string $hash
* @return array
*/
function password_get_info($hash)
{
return (strlen($hash) < 60 OR sscanf($hash, '$2y$%d', $hash) !== 1)
? array('algo' => 0, 'algoName' => 'unknown', 'options' => array())
: array('algo' => 1, 'algoName' => 'bcrypt', 'options' => array('cost' => $hash));
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('password_hash'))
{
/**
* password_hash()
*
* @link http://php.net/password_hash
* @param string $password
* @param int $algo
* @param array $options
* @return mixed
*/
function password_hash($password, $algo, array $options = array())
{
static $func_override;
isset($func_override) OR $func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override'));
if ($algo !== 1)
{
trigger_error('password_hash(): Unknown hashing algorithm: '.(int) $algo, E_USER_WARNING);
return NULL;
}
if (isset($options['cost']) && ($options['cost'] < 4 OR $options['cost'] > 31))
{
trigger_error('password_hash(): Invalid bcrypt cost parameter specified: '.(int) $options['cost'], E_USER_WARNING);
return NULL;
}
if (isset($options['salt']) && ($saltlen = ($func_override ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))) < 22)
{
trigger_error('password_hash(): Provided salt is too short: '.$saltlen.' expecting 22', E_USER_WARNING);
return NULL;
}
elseif ( ! isset($options['salt']))
{
if (defined('MCRYPT_DEV_URANDOM'))
{
$options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
}
elseif (function_exists('openssl_random_pseudo_bytes'))
{
$options['salt'] = openssl_random_pseudo_bytes(16);
}
elseif (DIRECTORY_SEPARATOR === '/' && (is_readable($dev = '/dev/arandom') OR is_readable($dev = '/dev/urandom')))
{
if (($fp = fopen($dev, 'rb')) === FALSE)
{
log_message('error', 'compat/password: Unable to open '.$dev.' for reading.');
return FALSE;
}
// Try not to waste entropy ...
is_php('5.4') && stream_set_chunk_size($fp, 16);
$options['salt'] = '';
for ($read = 0; $read < 16; $read = ($func_override) ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))
{
if (($read = fread($fp, 16 - $read)) === FALSE)
{
log_message('error', 'compat/password: Error while reading from '.$dev.'.');
return FALSE;
}
$options['salt'] .= $read;
}
fclose($fp);
}
else
{
log_message('error', 'compat/password: No CSPRNG available.');
return FALSE;
}
$options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
}
elseif ( ! preg_match('#^[a-zA-Z0-9./]+$#D', $options['salt']))
{
$options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
}
isset($options['cost']) OR $options['cost'] = 10;
return (strlen($password = crypt($password, sprintf('$2y$%02d$%s', $options['cost'], $options['salt']))) === 60)
? $password
: FALSE;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('password_needs_rehash'))
{
/**
* password_needs_rehash()
*
* @link http://php.net/password_needs_rehash
* @param string $hash
* @param int $algo
* @param array $options
* @return bool
*/
function password_needs_rehash($hash, $algo, array $options = array())
{
$info = password_get_info($hash);
if ($algo !== $info['algo'])
{
return TRUE;
}
elseif ($algo === 1)
{
$options['cost'] = isset($options['cost']) ? (int) $options['cost'] : 10;
return ($info['options']['cost'] !== $options['cost']);
}
// Odd at first glance, but according to a comment in PHP's own unit tests,
// because it is an unknown algorithm - it's valid and therefore doesn't
// need rehashing.
return FALSE;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('password_verify'))
{
/**
* password_verify()
*
* @link http://php.net/password_verify
* @param string $password
* @param string $hash
* @return bool
*/
function password_verify($password, $hash)
{
if (strlen($hash) !== 60 OR strlen($password = crypt($password, $hash)) !== 60)
{
return FALSE;
}
$compare = 0;
for ($i = 0; $i < 60; $i++)
{
$compare |= (ord($password[$i]) ^ ord($hash[$i]));
}
return ($compare === 0);
}
}

View file

@ -0,0 +1,389 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/standard compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
*/
// ------------------------------------------------------------------------
if (is_php('5.5'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('array_column'))
{
/**
* array_column()
*
* @link http://php.net/array_column
* @param string $array
* @param mixed $column_key
* @param mixed $index_key
* @return array
*/
function array_column(array $array, $column_key, $index_key = NULL)
{
if ( ! in_array($type = gettype($column_key), array('integer', 'string', 'NULL'), TRUE))
{
if ($type === 'double')
{
$column_key = (int) $column_key;
}
elseif ($type === 'object' && method_exists($column_key, '__toString'))
{
$column_key = (string) $column_key;
}
else
{
trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
return FALSE;
}
}
if ( ! in_array($type = gettype($index_key), array('integer', 'string', 'NULL'), TRUE))
{
if ($type === 'double')
{
$index_key = (int) $index_key;
}
elseif ($type === 'object' && method_exists($index_key, '__toString'))
{
$index_key = (string) $index_key;
}
else
{
trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
return FALSE;
}
}
$result = array();
foreach ($array as &$a)
{
if ($column_key === NULL)
{
$value = $a;
}
elseif (is_array($a) && array_key_exists($column_key, $a))
{
$value = $a[$column_key];
}
else
{
continue;
}
if ($index_key === NULL OR ! array_key_exists($index_key, $a))
{
$result[] = $value;
}
else
{
$result[$a[$index_key]] = $value;
}
}
return $result;
}
}
// ------------------------------------------------------------------------
if (is_php('5.4'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('hex2bin'))
{
/**
* hex2bin()
*
* @link http://php.net/hex2bin
* @param string $data
* @return string
*/
function hex2bin($data)
{
if (in_array($type = gettype($data), array('array', 'double', 'object'), TRUE))
{
if ($type === 'object' && method_exists($data, '__toString'))
{
$data = (string) $data;
}
else
{
trigger_error('hex2bin() expects parameter 1 to be string, '.$type.' given', E_USER_WARNING);
return NULL;
}
}
if (strlen($data) % 2 !== 0)
{
trigger_error('Hexadecimal input string must have an even length', E_USER_WARNING);
return FALSE;
}
elseif ( ! preg_match('/^[0-9a-f]*$/i', $data))
{
trigger_error('Input string must be hexadecimal string', E_USER_WARNING);
return FALSE;
}
return pack('H*', $data);
}
}
// ------------------------------------------------------------------------
if (is_php('5.3'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('array_replace'))
{
/**
* array_replace()
*
* @link http://php.net/array_replace
* @return array
*/
function array_replace()
{
$arrays = func_get_args();
if (($c = count($arrays)) === 0)
{
trigger_error('array_replace() expects at least 1 parameter, 0 given', E_USER_WARNING);
return NULL;
}
elseif ($c === 1)
{
if ( ! is_array($arrays[0]))
{
trigger_error('array_replace(): Argument #1 is not an array', E_USER_WARNING);
return NULL;
}
return $arrays[0];
}
$array = array_shift($arrays);
$c--;
for ($i = 0; $i < $c; $i++)
{
if ( ! is_array($arrays[$i]))
{
trigger_error('array_replace(): Argument #'.($i + 2).' is not an array', E_USER_WARNING);
return NULL;
}
elseif (empty($arrays[$i]))
{
continue;
}
foreach (array_keys($arrays[$i]) as $key)
{
$array[$key] = $arrays[$i][$key];
}
}
return $array;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('array_replace_recursive'))
{
/**
* array_replace_recursive()
*
* @link http://php.net/array_replace_recursive
* @return array
*/
function array_replace_recursive()
{
$arrays = func_get_args();
if (($c = count($arrays)) === 0)
{
trigger_error('array_replace_recursive() expects at least 1 parameter, 0 given', E_USER_WARNING);
return NULL;
}
elseif ($c === 1)
{
if ( ! is_array($arrays[0]))
{
trigger_error('array_replace_recursive(): Argument #1 is not an array', E_USER_WARNING);
return NULL;
}
return $arrays[0];
}
$array = array_shift($arrays);
$c--;
for ($i = 0; $i < $c; $i++)
{
if ( ! is_array($arrays[$i]))
{
trigger_error('array_replace_recursive(): Argument #'.($i + 2).' is not an array', E_USER_WARNING);
return NULL;
}
elseif (empty($arrays[$i]))
{
continue;
}
foreach (array_keys($arrays[$i]) as $key)
{
$array[$key] = (is_array($arrays[$i][$key]) && isset($array[$key]) && is_array($array[$key]))
? array_replace_recursive($array[$key], $arrays[$i][$key])
: $arrays[$i][$key];
}
}
return $array;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('quoted_printable_encode'))
{
/**
* quoted_printable_encode()
*
* @link http://php.net/quoted_printable_encode
* @param string $str
* @return string
*/
function quoted_printable_encode($str)
{
if (strlen($str) === 0)
{
return '';
}
elseif (in_array($type = gettype($str), array('array', 'object'), TRUE))
{
if ($type === 'object' && method_exists($str, '__toString'))
{
$str = (string) $str;
}
else
{
trigger_error('quoted_printable_encode() expects parameter 1 to be string, '.$type.' given', E_USER_WARNING);
return NULL;
}
}
if (function_exists('imap_8bit'))
{
return imap_8bit($str);
}
$i = $lp = 0;
$output = '';
$hex = '0123456789ABCDEF';
$length = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'))
? mb_strlen($str, '8bit')
: strlen($str);
while ($length--)
{
if ((($c = $str[$i++]) === "\015") && isset($str[$i]) && ($str[$i] === "\012") && $length > 0)
{
$output .= "\015".$str[$i++];
$length--;
$lp = 0;
continue;
}
if (
ctype_cntrl($c)
OR (ord($c) === 0x7f)
OR (ord($c) & 0x80)
OR ($c === '=')
OR ($c === ' ' && isset($str[$i]) && $str[$i] === "\015")
)
{
if (
(($lp += 3) > 75 && ord($c) <= 0x7f)
OR (ord($c) > 0x7f && ord($c) <= 0xdf && ($lp + 3) > 75)
OR (ord($c) > 0xdf && ord($c) <= 0xef && ($lp + 6) > 75)
OR (ord($c) > 0xef && ord($c) <= 0xf4 && ($lp + 9) > 75)
)
{
$output .= "=\015\012";
$lp = 3;
}
$output .= '='.$hex[ord($c) >> 4].$hex[ord($c) & 0xf];
continue;
}
if ((++$lp) > 75)
{
$output .= "=\015\012";
$lp = 1;
}
$output .= $c;
}
return $output;
}
}

View file

@ -1,3 +1,4 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
@ -7,4 +8,4 @@
<p>Directory access is forbidden.</p>
</body>
</html>
</html>

View file

@ -1,101 +1,141 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Initialize the database
*
* @category Database
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/database/
* @param string
* @param bool Determines if active record should be used or not
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
*
* @param string|string[] $params
* @param bool $query_builder_override
* Determines if query builder should be used or not
*/
function &DB($params = '', $active_record_override = NULL)
function &DB($params = '', $query_builder_override = NULL)
{
// Load the DB config file if a DSN string wasn't passed
if (is_string($params) AND strpos($params, '://') === FALSE)
if (is_string($params) && strpos($params, '://') === FALSE)
{
// Is the config file in the environment folder?
if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php'))
if ( ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php')
&& ! file_exists($file_path = APPPATH.'config/database.php'))
{
if ( ! file_exists($file_path = APPPATH.'config/database.php'))
{
show_error('The configuration file database.php does not exist.');
}
show_error('The configuration file database.php does not exist.');
}
include($file_path);
if ( ! isset($db) OR count($db) == 0)
// Make packages contain database config files,
// given that the controller instance already exists
if (class_exists('CI_Controller', FALSE))
{
foreach (get_instance()->load->get_package_paths() as $path)
{
if ($path !== APPPATH)
{
if (file_exists($file_path = $path.'config/'.ENVIRONMENT.'/database.php'))
{
include($file_path);
}
elseif (file_exists($file_path = $path.'config/database.php'))
{
include($file_path);
}
}
}
}
if ( ! isset($db) OR count($db) === 0)
{
show_error('No database connection settings were found in the database config file.');
}
if ($params != '')
if ($params !== '')
{
$active_group = $params;
}
if ( ! isset($active_group) OR ! isset($db[$active_group]))
if ( ! isset($active_group))
{
show_error('You have specified an invalid database connection group.');
show_error('You have not specified a database connection group via $active_group in your config/database.php file.');
}
elseif ( ! isset($db[$active_group]))
{
show_error('You have specified an invalid database connection group ('.$active_group.') in your config/database.php file.');
}
$params = $db[$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';
/**
* 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 (($dns = @parse_url($params)) === FALSE)
if (($dsn = @parse_url($params)) === FALSE)
{
show_error('Invalid DB Connection String');
}
$params = array(
'dbdriver' => $dns['scheme'],
'hostname' => (isset($dns['host'])) ? rawurldecode($dns['host']) : '',
'username' => (isset($dns['user'])) ? rawurldecode($dns['user']) : '',
'password' => (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',
'database' => (isset($dns['path'])) ? rawurldecode(substr($dns['path'], 1)) : ''
);
'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($dns['query']))
// Were additional config items set?
if (isset($dsn['query']))
{
parse_str($dns['query'], $extra);
parse_str($dsn['query'], $extra);
foreach ($extra as $key => $val)
{
// booleans please
if (strtoupper($val) == "TRUE")
if (is_string($val) && in_array(strtoupper($val), array('TRUE', 'FALSE', 'NULL')))
{
$val = TRUE;
}
elseif (strtoupper($val) == "FALSE")
{
$val = FALSE;
$val = var_export($val, TRUE);
}
$params[$key] = $val;
@ -103,61 +143,76 @@ function &DB($params = '', $active_record_override = NULL)
}
}
// No DB specified yet? Beat them senseless...
if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
// No DB specified yet? Beat them senseless...
if (empty($params['dbdriver']))
{
show_error('You have not selected a database type to connect to.');
}
// Load the DB classes. Note: Since the active record class is optional
// 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 active record class or not.
// Kudos to Paul for discovering this clever use of eval()
if ($active_record_override !== NULL)
// based on whether we're using the query builder class or not.
if ($query_builder_override !== NULL)
{
$active_record = $active_record_override;
$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(BASEPATH.'database/DB_driver.php');
if ( ! isset($active_record) OR $active_record == TRUE)
if ( ! isset($query_builder) OR $query_builder === TRUE)
{
require_once(BASEPATH.'database/DB_active_rec.php');
if ( ! class_exists('CI_DB'))
require_once(BASEPATH.'database/DB_query_builder.php');
if ( ! class_exists('CI_DB', FALSE))
{
eval('class CI_DB extends CI_DB_active_record { }');
/**
* CI_DB
*
* Acts as an alias for both CI_DB_driver and CI_DB_query_builder.
*
* @see CI_DB_query_builder
* @see CI_DB_driver
*/
class CI_DB extends CI_DB_query_builder { }
}
}
else
elseif ( ! class_exists('CI_DB', FALSE))
{
if ( ! class_exists('CI_DB'))
{
eval('class CI_DB extends CI_DB_driver { }');
}
/**
* @ignore
*/
class CI_DB extends CI_DB_driver { }
}
require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php');
// Load the DB driver
$driver_file = BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php';
file_exists($driver_file) OR show_error('Invalid DB driver');
require_once($driver_file);
// Instantiate the DB adapter
$driver = 'CI_DB_'.$params['dbdriver'].'_driver';
$DB = new $driver($params);
if ($DB->autoinit == TRUE)
// Check for a subdriver
if ( ! empty($DB->subdriver))
{
$DB->initialize();
}
if (isset($params['stricton']) && $params['stricton'] == TRUE)
{
$DB->query('SET SESSION sql_mode="STRICT_ALL_TABLES"');
$driver_file = BASEPATH.'database/drivers/'.$DB->dbdriver.'/subdrivers/'.$DB->dbdriver.'_'.$DB->subdriver.'_driver.php';
if (file_exists($driver_file))
{
require_once($driver_file);
$driver = 'CI_DB_'.$DB->dbdriver.'_'.$DB->subdriver.'_driver';
$DB = new $driver($params);
}
}
$DB->initialize();
return $DB;
}
/* End of file DB.php */
/* Location: ./system/database/DB.php */

File diff suppressed because it is too large Load diff

View file

@ -1,46 +1,84 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Database Cache Class
*
* @category Database
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/database/
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_Cache {
var $CI;
var $db; // allows passing of db object so that multiple database connections and returned db objects can be supported
/**
* CI Singleton
*
* @var object
*/
public $CI;
/**
* Database object
*
* Allows passing of DB object so that multiple database connections
* and returned DB objects can be supported.
*
* @var object
*/
public $db;
// --------------------------------------------------------------------
/**
* Constructor
*
* Grabs the CI super object instance so we can access it.
*
* @param object &$db
* @return void
*/
function __construct(&$db)
public function __construct(&$db)
{
// Assign the main CI object to $this->CI
// and load the file helper since we use it a lot
// Assign the main CI object to $this->CI and load the file helper since we use it a lot
$this->CI =& get_instance();
$this->db =& $db;
$this->CI->load->helper('file');
$this->check_path();
}
// --------------------------------------------------------------------
@ -48,15 +86,14 @@ class CI_DB_Cache {
/**
* Set Cache Directory Path
*
* @access public
* @param string the path to the cache directory
* @param string $path Path to the cache directory
* @return bool
*/
function check_path($path = '')
public function check_path($path = '')
{
if ($path == '')
if ($path === '')
{
if ($this->db->cachedir == '')
if ($this->db->cachedir === '')
{
return $this->db->cache_off();
}
@ -65,14 +102,26 @@ class CI_DB_Cache {
}
// Add a trailing slash to the path if needed
$path = preg_replace("/(.+?)\/*$/", "\\1/", $path);
$path = realpath($path)
? rtrim(realpath($path), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR
: rtrim($path, '/').'/';
if ( ! is_dir($path) OR ! is_really_writable($path))
if ( ! is_dir($path))
{
log_message('debug', 'DB cache path error: '.$path);
// If the path is wrong we'll turn off caching
return $this->db->cache_off();
}
if ( ! is_really_writable($path))
{
log_message('debug', '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;
}
@ -83,25 +132,18 @@ class CI_DB_Cache {
* 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
* An MD5 hash of the SQL statement will become the cache file name.
*
* @access public
* @param string $sql
* @return string
*/
function read($sql)
public function read($sql)
{
if ( ! $this->check_path())
{
return $this->db->cache_off();
}
$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
$filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql);
if (FALSE === ($cachedata = read_file($filepath)))
if (FALSE === ($cachedata = @file_get_contents($filepath)))
{
return FALSE;
}
@ -114,32 +156,20 @@ class CI_DB_Cache {
/**
* Write a query to a cache file
*
* @access public
* @param string $sql
* @param object $object
* @return bool
*/
function write($sql, $object)
public function write($sql, $object)
{
if ( ! $this->check_path())
{
return $this->db->cache_off();
}
$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
$filename = md5($sql);
if ( ! @is_dir($dir_path))
if ( ! is_dir($dir_path) && ! @mkdir($dir_path, 0750))
{
if ( ! @mkdir($dir_path, DIR_WRITE_MODE))
{
return FALSE;
}
@chmod($dir_path, DIR_WRITE_MODE);
return FALSE;
}
if (write_file($dir_path.$filename, serialize($object)) === FALSE)
@ -147,7 +177,7 @@ class CI_DB_Cache {
return FALSE;
}
@chmod($dir_path.$filename, FILE_WRITE_MODE);
chmod($dir_path.$filename, 0640);
return TRUE;
}
@ -156,23 +186,23 @@ class CI_DB_Cache {
/**
* Delete cache files within a particular directory
*
* @access public
* @return bool
* @param string $segment_one
* @param string $segment_two
* @return void
*/
function delete($segment_one = '', $segment_two = '')
public function delete($segment_one = '', $segment_two = '')
{
if ($segment_one == '')
if ($segment_one === '')
{
$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
}
if ($segment_two == '')
if ($segment_two === '')
{
$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
}
$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
delete_files($dir_path, TRUE);
}
@ -181,16 +211,11 @@ class CI_DB_Cache {
/**
* Delete all existing cache files
*
* @access public
* @return bool
* @return void
*/
function delete_all()
public function delete_all()
{
delete_files($this->db->cachedir, TRUE);
delete_files($this->db->cachedir, TRUE, TRUE);
}
}
/* End of file DB_cache.php */
/* Location: ./system/database/DB_cache.php */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Database Result Class
@ -25,32 +46,127 @@
*
* @category Database
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/database/
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_result {
var $conn_id = NULL;
var $result_id = NULL;
var $result_array = array();
var $result_object = array();
var $custom_result_object = array();
var $current_row = 0;
var $num_rows = 0;
var $row_data = NULL;
/**
* Connection ID
*
* @var resource|object
*/
public $conn_id;
/**
* Query result. Acts as a wrapper function for the following functions.
* Result ID
*
* @access public
* @param string can be "object" or "array"
* @return mixed either a result object or array
* @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();
else if ($type == 'object') return $this->result_object();
else return $this->custom_result_object($type);
if ($type === 'array')
{
return $this->result_array();
}
elseif ($type === 'object')
{
return $this->result_object();
}
else
{
return $this->custom_result_object($type);
}
}
// --------------------------------------------------------------------
@ -58,48 +174,63 @@ class CI_DB_result {
/**
* Custom query result.
*
* @param class_name A string that represents the type of object you want back
* @return array of objects
* @param string $class_name
* @return array
*/
public function custom_result_object($class_name)
{
if (array_key_exists($class_name, $this->custom_result_object))
if (isset($this->custom_result_object[$class_name]))
{
return $this->custom_result_object[$class_name];
}
if ($this->result_id === FALSE OR $this->num_rows() == 0)
elseif ( ! $this->result_id OR $this->num_rows === 0)
{
return array();
}
// add the data to the object
$this->_data_seek(0);
$result_object = array();
while ($row = $this->_fetch_object())
// Don't fetch the result set again if we already have it
$_data = NULL;
if (($c = count($this->result_array)) > 0)
{
$object = new $class_name();
foreach ($row as $key => $value)
{
$object->$key = $value;
}
$result_object[] = $object;
$_data = 'result_array';
}
elseif (($c = count($this->result_object)) > 0)
{
$_data = 'result_object';
}
// return the array
return $this->custom_result_object[$class_name] = $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.
* Query result. "object" version.
*
* @access public
* @return object
* @return array
*/
public function result_object()
{
@ -108,15 +239,25 @@ class CI_DB_result {
return $this->result_object;
}
// In the event that query caching is on the result_id variable
// will return FALSE since there isn't a valid SQL resource so
// we'll simply return an empty array.
if ($this->result_id === FALSE OR $this->num_rows() == 0)
// 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();
}
$this->_data_seek(0);
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;
@ -128,9 +269,8 @@ class CI_DB_result {
// --------------------------------------------------------------------
/**
* Query result. "array" version.
* Query result. "array" version.
*
* @access public
* @return array
*/
public function result_array()
@ -140,15 +280,25 @@ class CI_DB_result {
return $this->result_array;
}
// In the event that query caching is on the result_id variable
// will return FALSE since there isn't a valid SQL resource so
// we'll simply return an empty array.
if ($this->result_id === FALSE OR $this->num_rows() == 0)
// 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();
}
$this->_data_seek(0);
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;
@ -160,34 +310,32 @@ class CI_DB_result {
// --------------------------------------------------------------------
/**
* Query result. Acts as a wrapper function for the following functions.
* Row
*
* @access public
* @param string
* @param string can be "object" or "array"
* @return mixed either a result object or array
* 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
if ( ! is_array($this->row_data))
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))
{
$this->row_data = $this->row_array(0);
return NULL;
}
// array_key_exists() instead of isset() to allow for MySQL NULL values
if (array_key_exists($n, $this->row_data))
{
return $this->row_data[$n];
}
// reset the $n variable if the result was not achieved
$n = 0;
return $this->row_data[$n];
}
if ($type == 'object') return $this->row_object($n);
else if ($type == 'array') return $this->row_array($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);
}
@ -196,8 +344,9 @@ class CI_DB_result {
/**
* Assigns an item into a particular column slot
*
* @access public
* @return object
* @param mixed $key
* @param mixed $value
* @return void
*/
public function set_row($key, $value = NULL)
{
@ -213,11 +362,10 @@ class CI_DB_result {
{
$this->row_data[$k] = $v;
}
return;
}
if ($key != '' AND ! is_null($value))
if ($key !== '' && $value !== NULL)
{
$this->row_data[$key] = $value;
}
@ -228,42 +376,44 @@ class CI_DB_result {
/**
* Returns a single result row - custom object version
*
* @access public
* @param int $n
* @param string $type
* @return object
*/
public function custom_row_object($n, $type)
{
$result = $this->custom_result_object($type);
isset($this->custom_result_object[$type]) OR $this->custom_result_object($type);
if (count($result) == 0)
if (count($this->custom_result_object[$type]) === 0)
{
return $result;
return NULL;
}
if ($n != $this->current_row AND isset($result[$n]))
if ($n !== $this->current_row && isset($this->custom_result_object[$type][$n]))
{
$this->current_row = $n;
}
return $result[$this->current_row];
return $this->custom_result_object[$type][$this->current_row];
}
// --------------------------------------------------------------------
/**
* Returns a single result row - object version
*
* @access public
* @param int $n
* @return object
*/
public function row_object($n = 0)
{
$result = $this->result_object();
if (count($result) == 0)
if (count($result) === 0)
{
return $result;
return NULL;
}
if ($n != $this->current_row AND isset($result[$n]))
if ($n !== $this->current_row && isset($result[$n]))
{
$this->current_row = $n;
}
@ -276,19 +426,18 @@ class CI_DB_result {
/**
* Returns a single result row - array version
*
* @access public
* @param int $n
* @return array
*/
public function row_array($n = 0)
{
$result = $this->result_array();
if (count($result) == 0)
if (count($result) === 0)
{
return $result;
return NULL;
}
if ($n != $this->current_row AND isset($result[$n]))
if ($n !== $this->current_row && isset($result[$n]))
{
$this->current_row = $n;
}
@ -296,24 +445,18 @@ class CI_DB_result {
return $result[$this->current_row];
}
// --------------------------------------------------------------------
/**
* Returns the "first" row
*
* @access public
* @return object
* @param string $type
* @return mixed
*/
public function first_row($type = 'object')
{
$result = $this->result($type);
if (count($result) == 0)
{
return $result;
}
return $result[0];
return (count($result) === 0) ? NULL : $result[0];
}
// --------------------------------------------------------------------
@ -321,18 +464,13 @@ class CI_DB_result {
/**
* Returns the "last" row
*
* @access public
* @return object
* @param string $type
* @return mixed
*/
public function last_row($type = 'object')
{
$result = $this->result($type);
if (count($result) == 0)
{
return $result;
}
return $result[count($result) -1];
return (count($result) === 0) ? NULL : $result[count($result) - 1];
}
// --------------------------------------------------------------------
@ -340,24 +478,20 @@ class CI_DB_result {
/**
* Returns the "next" row
*
* @access public
* @return object
* @param string $type
* @return mixed
*/
public function next_row($type = 'object')
{
$result = $this->result($type);
if (count($result) == 0)
if (count($result) === 0)
{
return $result;
return NULL;
}
if (isset($result[$this->current_row + 1]))
{
++$this->current_row;
}
return $result[$this->current_row];
return isset($result[$this->current_row + 1])
? $result[++$this->current_row]
: NULL;
}
// --------------------------------------------------------------------
@ -365,16 +499,15 @@ class CI_DB_result {
/**
* Returns the "previous" row
*
* @access public
* @return object
* @param string $type
* @return mixed
*/
public function previous_row($type = 'object')
{
$result = $this->result($type);
if (count($result) == 0)
if (count($result) === 0)
{
return $result;
return NULL;
}
if (isset($result[$this->current_row - 1]))
@ -387,25 +520,147 @@ class CI_DB_result {
// --------------------------------------------------------------------
/**
* The following functions are normally overloaded by the identically named
* 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.
* 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
* 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.
*/
public function num_rows() { return $this->num_rows; }
public function num_fields() { return 0; }
public function list_fields() { return array(); }
public function field_data() { return array(); }
public function free_result() { return TRUE; }
protected function _data_seek() { return TRUE; }
protected function _fetch_assoc() { return array(); }
protected function _fetch_object() { return array(); }
// --------------------------------------------------------------------
/**
* 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();
}
}
// END DB_result class
/* End of file DB_result.php */
/* Location: ./system/database/DB_result.php */

View file

@ -1,46 +1,93 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Database Utility Class
*
* @category Database
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/database/
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_utility extends CI_DB_forge {
var $db;
var $data_cache = array();
abstract class CI_DB_utility {
/**
* Constructor
*
* Grabs the CI super object instance so we can access it.
* Database object
*
* @var object
*/
function __construct()
{
// Assign the main database object to $this->db
$CI =& get_instance();
$this->db =& $CI->db;
protected $db;
log_message('debug', "Database Utility Class Initialized");
// --------------------------------------------------------------------
/**
* 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;
// --------------------------------------------------------------------
/**
* Class constructor
*
* @param object &$db Database object
* @return void
*/
public function __construct(&$db)
{
$this->db =& $db;
log_message('info', 'Database Utility Class Initialized');
}
// --------------------------------------------------------------------
@ -48,29 +95,34 @@ class CI_DB_utility extends CI_DB_forge {
/**
* List databases
*
* @access public
* @return bool
* @return array
*/
function list_databases()
public function list_databases()
{
// Is there a cached result?
if (isset($this->data_cache['db_names']))
if (isset($this->db->data_cache['db_names']))
{
return $this->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;
}
$query = $this->db->query($this->_list_databases());
$dbs = array();
if ($query->num_rows() > 0)
$this->db->data_cache['db_names'] = array();
$query = $this->db->query($this->_list_databases);
if ($query === FALSE)
{
foreach ($query->result_array() as $row)
{
$dbs[] = current($row);
}
return $this->db->data_cache['db_names'];
}
$this->data_cache['db_names'] = $dbs;
return $this->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'];
}
// --------------------------------------------------------------------
@ -78,50 +130,37 @@ class CI_DB_utility extends CI_DB_forge {
/**
* Determine if a particular database exists
*
* @access public
* @param string
* @return boolean
* @param string $database_name
* @return bool
*/
function database_exists($database_name)
public function database_exists($database_name)
{
// Some databases won't have access to the list_databases() function, so
// this is intended to allow them to override with their own functions as
// defined in $driver_utility.php
if (method_exists($this, '_database_exists'))
{
return $this->_database_exists($database_name);
}
else
{
return ( ! in_array($database_name, $this->list_databases())) ? FALSE : TRUE;
}
return in_array($database_name, $this->list_databases());
}
// --------------------------------------------------------------------
/**
* Optimize Table
*
* @access public
* @param string the table name
* @return bool
* @param string $table_name
* @return mixed
*/
function optimize_table($table_name)
public function optimize_table($table_name)
{
$sql = $this->_optimize_table($table_name);
if (is_bool($sql))
if ($this->_optimize_table === FALSE)
{
show_error('db_must_use_set');
return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE;
}
$query = $this->db->query($sql);
$res = $query->result_array();
$query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
if ($query !== FALSE)
{
$query = $query->result_array();
return current($query);
}
// Note: Due to a bug in current() that affects some versions
// of PHP we can not pass function call directly into it
return current($res);
return FALSE;
}
// --------------------------------------------------------------------
@ -129,27 +168,26 @@ class CI_DB_utility extends CI_DB_forge {
/**
* Optimize Database
*
* @access public
* @return array
* @return mixed
*/
function optimize_database()
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)
{
$sql = $this->_optimize_table($table_name);
if (is_bool($sql))
$res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
if (is_bool($res))
{
return $sql;
return $res;
}
$query = $this->db->query($sql);
// Build the result array...
// Note: Due to a bug in current() that affects some versions
// of PHP we can not pass function call directly into it
$res = $query->result_array();
$res = $res->result_array();
$res = current($res);
$key = str_replace($this->db->database.'.', '', current($res));
$keys = array_keys($res);
@ -166,25 +204,24 @@ class CI_DB_utility extends CI_DB_forge {
/**
* Repair Table
*
* @access public
* @param string the table name
* @return bool
* @param string $table_name
* @return mixed
*/
function repair_table($table_name)
public function repair_table($table_name)
{
$sql = $this->_repair_table($table_name);
if (is_bool($sql))
if ($this->_repair_table === FALSE)
{
return $sql;
return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE;
}
$query = $this->db->query($sql);
$query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
if (is_bool($query))
{
return $query;
}
// Note: Due to a bug in current() that affects some versions
// of PHP we can not pass function call directly into it
$res = $query->result_array();
return current($res);
$query = $query->result_array();
return current($query);
}
// --------------------------------------------------------------------
@ -192,14 +229,13 @@ class CI_DB_utility extends CI_DB_forge {
/**
* Generate CSV from a query result object
*
* @access public
* @param object The query result object
* @param string The delimiter - comma by default
* @param string The newline character - \n by default
* @param string The enclosure - double quote by default
* @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
*/
function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')
public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
{
if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
{
@ -207,25 +243,23 @@ class CI_DB_utility extends CI_DB_forge {
}
$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 = rtrim($out);
$out .= $newline;
$out = substr($out, 0, -strlen($delim)).$newline;
// Next blast through the result array and build out the rows
foreach ($query->result_array() as $row)
while ($row = $query->unbuffered_row('array'))
{
$line = array();
foreach ($row as $item)
{
$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
$line[] = $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure;
}
$out = rtrim($out);
$out .= $newline;
$out .= implode($delim, $line).$newline;
}
return $out;
@ -236,12 +270,11 @@ class CI_DB_utility extends CI_DB_forge {
/**
* Generate XML data from a query result object
*
* @access public
* @param object The query result object
* @param array Any preferences
* @param object $query Query result object
* @param array $params Any preferences
* @return string
*/
function xml_from_result($query, $params = array())
public function xml_from_result($query, $params = array())
{
if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
{
@ -261,24 +294,21 @@ class CI_DB_utility extends CI_DB_forge {
extract($params);
// Load the xml helper
$CI =& get_instance();
$CI->load->helper('xml');
get_instance()->load->helper('xml');
// Generate the result
$xml = "<{$root}>".$newline;
foreach ($query->result_array() as $row)
$xml = '<'.$root.'>'.$newline;
while ($row = $query->unbuffered_row())
{
$xml .= $tab."<{$element}>".$newline;
$xml .= $tab.'<'.$element.'>'.$newline;
foreach ($row as $key => $val)
{
$xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
$xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
}
$xml .= $tab."</{$element}>".$newline;
$xml .= $tab.'</'.$element.'>'.$newline;
}
$xml .= "</$root>".$newline;
return $xml;
return $xml.'</'.$root.'>'.$newline;
}
// --------------------------------------------------------------------
@ -286,10 +316,10 @@ class CI_DB_utility extends CI_DB_forge {
/**
* Database Backup
*
* @access public
* @return void
* @param array $params
* @return string
*/
function backup($params = array())
public function backup($params = array())
{
// If the parameters have not been submitted as an
// array then we know that it is simply the table
@ -299,18 +329,17 @@ class CI_DB_utility extends CI_DB_forge {
$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"
);
'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)
@ -324,92 +353,72 @@ class CI_DB_utility extends CI_DB_forge {
}
}
// ------------------------------------------------------
// 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)
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
// 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' AND ! @function_exists('gzencode'))
OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress')))
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_unsuported_compression');
return $this->db->display_error('db_unsupported_compression');
}
$prefs['format'] = 'txt';
}
// ------------------------------------------------------
// Set the filename if not provided - Only needed with Zip files
if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
{
$prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
$prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
}
// ------------------------------------------------------
// Was a Gzip file requested?
if ($prefs['format'] == 'gzip')
{
return gzencode($this->_backup($prefs));
}
// ------------------------------------------------------
// Was a text file requested?
if ($prefs['format'] == 'txt')
{
return $this->_backup($prefs);
}
// ------------------------------------------------------
// Was a Zip file requested?
if ($prefs['format'] == 'zip')
if ($prefs['format'] === 'zip')
{
// If they included the .zip file extension we'll remove it
if (preg_match("|.+?\.zip$|", $prefs['filename']))
// Set the filename if not provided (only needed with Zip files)
if ($prefs['filename'] === '')
{
$prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
$prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
.date('Y-m-d_H-i', time()).'.sql';
}
// Tack on the ".sql" file extension if needed
if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
else
{
$prefs['filename'] .= '.sql';
// 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
$CI =& get_instance();
$CI->load->library('zip');
$CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
return $CI->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;
}
}
/* End of file DB_utility.php */
/* Location: ./system/database/DB_utility.php */

View file

@ -1,109 +1,135 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 2.0.2
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 2.1.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CUBRID Database Adapter Class
*
* Note: _DB is an extender class that the app controller
* creates dynamically based on whether the active record
* creates dynamically based on whether the query builder
* class is being used or not.
*
* @package CodeIgniter
* @subpackage Drivers
* @category Database
* @author Esen Sagynov
* @link http://codeigniter.com/user_guide/database/
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_cubrid_driver extends CI_DB {
// Default CUBRID Broker port. Will be used unless user
// explicitly specifies another one.
const DEFAULT_PORT = 33000;
var $dbdriver = 'cubrid';
// The character used for escaping - no need in CUBRID
var $_escape_char = '';
// clause and character used for LIKE escape sequences - not used in CUBRID
var $_like_escape_str = '';
var $_like_escape_chr = '';
/**
* The syntax to count rows is slightly different across different
* database engines, so this string appears in each driver and is
* used for the count_all() and count_all_results() functions.
*/
var $_count_string = 'SELECT COUNT(*) AS ';
var $_random_keyword = ' RAND()'; // database specific random keyword
/**
* Non-persistent database connection
* Database driver
*
* @access private called by the base class
* @return resource
* @var string
*/
function db_connect()
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)
{
// If no port is defined by the user, use the default value
if ($this->port == '')
{
$this->port = self::DEFAULT_PORT;
}
parent::__construct($params);
$conn = cubrid_connect($this->hostname, $this->port, $this->database, $this->username, $this->password);
if ($conn)
if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:[^:]*:[^:]*:(\?.+)?$/', $this->dsn, $matches))
{
// Check if a user wants to run queries in dry, i.e. run the
// queries but not commit them.
if (isset($this->auto_commit) && ! $this->auto_commit)
if (stripos($matches[2], 'autocommit=off') !== FALSE)
{
cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_FALSE);
}
else
{
cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_TRUE);
$this->auto_commit = TRUE;
$this->auto_commit = FALSE;
}
}
return $conn;
else
{
// If no port is defined by the user, use the default value
empty($this->port) OR $this->port = 33000;
}
}
// --------------------------------------------------------------------
/**
* Persistent database connection
* In CUBRID persistent DB connection is supported natively in CUBRID
* engine which can be configured in the CUBRID Broker configuration
* file by setting the CCI_PCONNECT parameter to ON. In that case, all
* connections established between the client application and the
* server will become persistent. This is calling the same
* @cubrid_connect function will establish persisten connection
* considering that the CCI_PCONNECT is ON.
* Non-persistent database connection
*
* @access private called by the base class
* @param bool $persistent
* @return resource
*/
function db_pconnect()
public function db_connect($persistent = FALSE)
{
return $this->db_connect();
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);
}
// --------------------------------------------------------------------
@ -114,10 +140,9 @@ class CI_DB_cubrid_driver extends CI_DB {
* Keep / reestablish the db connection if no queries have been
* sent for a length of time exceeding the server's idle timeout
*
* @access public
* @return void
*/
function reconnect()
public function reconnect()
{
if (cubrid_ping($this->conn_id) === FALSE)
{
@ -128,54 +153,20 @@ class CI_DB_cubrid_driver extends CI_DB {
// --------------------------------------------------------------------
/**
* Select the database
* Database version number
*
* @access private called by the base class
* @return resource
*/
function db_select()
{
// In CUBRID there is no need to select a database as the database
// is chosen at the connection time.
// So, to determine if the database is "selected", all we have to
// do is ping the server and return that value.
return cubrid_ping($this->conn_id);
}
// --------------------------------------------------------------------
/**
* Set client character set
*
* @access public
* @param string
* @param string
* @return resource
*/
function db_set_charset($charset, $collation)
{
// In CUBRID, there is no need to set charset or collation.
// This is why returning true will allow the application continue
// its normal process.
return TRUE;
}
// --------------------------------------------------------------------
/**
* Version number query string
*
* @access public
* @return string
*/
function _version()
public function version()
{
// To obtain the CUBRID Server version, no need to run the SQL query.
// CUBRID PHP API provides a function to determin this value.
// This is why we also need to add 'cubrid' value to the list of
// $driver_version_exceptions array in DB_driver class in
// version() function.
return cubrid_get_server_info($this->conn_id);
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;
}
// --------------------------------------------------------------------
@ -183,31 +174,12 @@ class CI_DB_cubrid_driver extends CI_DB {
/**
* Execute the query
*
* @access private called by the base class
* @param string an SQL query
* @param string $sql an SQL query
* @return resource
*/
function _execute($sql)
protected function _execute($sql)
{
$sql = $this->_prep_query($sql);
return @cubrid_query($sql, $this->conn_id);
}
// --------------------------------------------------------------------
/**
* Prep the query
*
* If needed, each database adapter can prep the query string
*
* @access private called by execute()
* @param string an SQL query
* @return string
*/
function _prep_query($sql)
{
// No need to prepare
return $sql;
return cubrid_query($sql, $this->conn_id);
}
// --------------------------------------------------------------------
@ -215,30 +187,17 @@ class CI_DB_cubrid_driver extends CI_DB {
/**
* Begin Transaction
*
* @access public
* @return bool
*/
function trans_begin($test_mode = FALSE)
protected function _trans_begin()
{
if ( ! $this->trans_enabled)
if (($autocommit = cubrid_get_autocommit($this->conn_id)) === NULL)
{
return TRUE;
return FALSE;
}
// When transactions are nested we only begin/commit/rollback the outermost ones
if ($this->_trans_depth > 0)
elseif ($autocommit === TRUE)
{
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) ? TRUE : FALSE;
if (cubrid_get_autocommit($this->conn_id))
{
cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
}
return TRUE;
@ -249,27 +208,18 @@ class CI_DB_cubrid_driver extends CI_DB {
/**
* Commit Transaction
*
* @access public
* @return bool
*/
function trans_commit()
protected function _trans_commit()
{
if ( ! $this->trans_enabled)
if ( ! cubrid_commit($this->conn_id))
{
return TRUE;
return FALSE;
}
// When transactions are nested we only begin/commit/rollback the outermost ones
if ($this->_trans_depth > 0)
{
return TRUE;
}
cubrid_commit($this->conn_id);
if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
{
cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
}
return TRUE;
@ -280,24 +230,15 @@ class CI_DB_cubrid_driver extends CI_DB {
/**
* Rollback Transaction
*
* @access public
* @return bool
*/
function trans_rollback()
protected function _trans_rollback()
{
if ( ! $this->trans_enabled)
if ( ! cubrid_rollback($this->conn_id))
{
return TRUE;
return FALSE;
}
// When transactions are nested we only begin/commit/rollback the outermost ones
if ($this->_trans_depth > 0)
{
return TRUE;
}
cubrid_rollback($this->conn_id);
if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
{
cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
@ -309,41 +250,14 @@ class CI_DB_cubrid_driver extends CI_DB {
// --------------------------------------------------------------------
/**
* Escape String
* Platform-dependant string escape
*
* @access public
* @param string
* @param bool whether or not the string will be used in a LIKE condition
* @return string
*/
function escape_str($str, $like = FALSE)
protected function _escape_str($str)
{
if (is_array($str))
{
foreach ($str as $key => $val)
{
$str[$key] = $this->escape_str($val, $like);
}
return $str;
}
if (function_exists('cubrid_real_escape_string') AND is_resource($this->conn_id))
{
$str = cubrid_real_escape_string($str, $this->conn_id);
}
else
{
$str = addslashes($str);
}
// escape LIKE condition wildcards
if ($like === TRUE)
{
$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
}
return $str;
return cubrid_real_escape_string($str, $this->conn_id);
}
// --------------------------------------------------------------------
@ -351,12 +265,11 @@ class CI_DB_cubrid_driver extends CI_DB {
/**
* Affected Rows
*
* @access public
* @return integer
* @return int
*/
function affected_rows()
public function affected_rows()
{
return @cubrid_affected_rows($this->conn_id);
return cubrid_affected_rows();
}
// --------------------------------------------------------------------
@ -364,43 +277,11 @@ class CI_DB_cubrid_driver extends CI_DB {
/**
* Insert ID
*
* @access public
* @return integer
* @return int
*/
function insert_id()
public function insert_id()
{
return @cubrid_insert_id($this->conn_id);
}
// --------------------------------------------------------------------
/**
* "Count All" query
*
* Generates a platform-specific query string that counts all records in
* the specified table
*
* @access public
* @param string
* @return string
*/
function count_all($table = '')
{
if ($table == '')
{
return 0;
}
$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
if ($query->num_rows() == 0)
{
return 0;
}
$row = $query->row();
$this->_reset_select();
return (int) $row->numrows;
return cubrid_insert_id($this->conn_id);
}
// --------------------------------------------------------------------
@ -410,17 +291,16 @@ class CI_DB_cubrid_driver extends CI_DB {
*
* Generates a platform-specific query string so that the table names can be fetched
*
* @access private
* @param boolean
* @param bool $prefix_limit
* @return string
*/
function _list_tables($prefix_limit = FALSE)
protected function _list_tables($prefix_limit = FALSE)
{
$sql = "SHOW TABLES";
$sql = 'SHOW TABLES';
if ($prefix_limit !== FALSE AND $this->dbprefix != '')
if ($prefix_limit !== FALSE && $this->dbprefix !== '')
{
$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'";
}
return $sql;
@ -433,343 +313,81 @@ class CI_DB_cubrid_driver extends CI_DB {
*
* Generates a platform-specific query string so that the column names can be fetched
*
* @access public
* @param string the table name
* @param string $table
* @return string
*/
function _list_columns($table = '')
protected function _list_columns($table = '')
{
return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE);
}
// --------------------------------------------------------------------
/**
* Field data query
* Returns an object with field data
*
* Generates a platform-specific query so that the column data can be retrieved
*
* @access public
* @param string the table name
* @return object
* @param string $table
* @return array
*/
function _field_data($table)
public function field_data($table)
{
return "SELECT * FROM ".$table." LIMIT 1";
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;
}
// --------------------------------------------------------------------
/**
* The error message string
* 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.
*
* @access private
* @return string
*/
function _error_message()
protected function _from_tables()
{
return cubrid_error($this->conn_id);
}
// --------------------------------------------------------------------
/**
* The error message number
*
* @access private
* @return integer
*/
function _error_number()
{
return cubrid_errno($this->conn_id);
}
// --------------------------------------------------------------------
/**
* Escape the SQL Identifiers
*
* This function escapes column and table names
*
* @access private
* @param string
* @return string
*/
function _escape_identifiers($item)
{
if ($this->_escape_char == '')
if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
{
return $item;
return '('.implode(', ', $this->qb_from).')';
}
foreach ($this->_reserved_identifiers as $id)
{
if (strpos($item, '.'.$id) !== FALSE)
{
$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
// remove duplicates if the user already included the escape
return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
}
}
if (strpos($item, '.') !== FALSE)
{
$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
}
else
{
$str = $this->_escape_char.$item.$this->_escape_char;
}
// remove duplicates if the user already included the escape
return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
}
// --------------------------------------------------------------------
/**
* From Tables
*
* This function implicitly groups FROM tables so there is no confusion
* about operator precedence in harmony with SQL standards
*
* @access public
* @param type
* @return type
*/
function _from_tables($tables)
{
if ( ! is_array($tables))
{
$tables = array($tables);
}
return '('.implode(', ', $tables).')';
}
// --------------------------------------------------------------------
/**
* Insert statement
*
* Generates a platform-specific insert string from the supplied data
*
* @access public
* @param string the table name
* @param array the insert keys
* @param array the insert values
* @return string
*/
function _insert($table, $keys, $values)
{
return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
}
// --------------------------------------------------------------------
/**
* Replace statement
*
* Generates a platform-specific replace string from the supplied data
*
* @access public
* @param string the table name
* @param array the insert keys
* @param array the insert values
* @return string
*/
function _replace($table, $keys, $values)
{
return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
}
// --------------------------------------------------------------------
/**
* Insert_batch statement
*
* Generates a platform-specific insert string from the supplied data
*
* @access public
* @param string the table name
* @param array the insert keys
* @param array the insert values
* @return string
*/
function _insert_batch($table, $keys, $values)
{
return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
}
// --------------------------------------------------------------------
/**
* Update statement
*
* Generates a platform-specific update string from the supplied data
*
* @access public
* @param string the table name
* @param array the update data
* @param array the where clause
* @param array the orderby clause
* @param array the limit clause
* @return string
*/
function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
{
foreach ($values as $key => $val)
{
$valstr[] = sprintf('"%s" = %s', $key, $val);
}
$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
$sql .= $orderby.$limit;
return $sql;
}
// --------------------------------------------------------------------
/**
* Update_Batch statement
*
* Generates a platform-specific batch update string from the supplied data
*
* @access public
* @param string the table name
* @param array the update data
* @param array the where clause
* @return string
*/
function _update_batch($table, $values, $index, $where = NULL)
{
$ids = array();
$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
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];
}
}
}
$sql = "UPDATE ".$table." SET ";
$cases = '';
foreach ($final as $k => $v)
{
$cases .= $k.' = CASE '."\n";
foreach ($v as $row)
{
$cases .= $row."\n";
}
$cases .= 'ELSE '.$k.' END, ';
}
$sql .= substr($cases, 0, -2);
$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
return $sql;
}
// --------------------------------------------------------------------
/**
* Truncate statement
*
* Generates a platform-specific truncate string from the supplied data
* If the database does not support the truncate() command
* This function maps to "DELETE FROM table"
*
* @access public
* @param string the table name
* @return string
*/
function _truncate($table)
{
return "TRUNCATE ".$table;
}
// --------------------------------------------------------------------
/**
* Delete statement
*
* Generates a platform-specific delete string from the supplied data
*
* @access public
* @param string the table name
* @param array the where clause
* @param string the limit clause
* @return string
*/
function _delete($table, $where = array(), $like = array(), $limit = FALSE)
{
$conditions = '';
if (count($where) > 0 OR count($like) > 0)
{
$conditions = "\nWHERE ";
$conditions .= implode("\n", $this->ar_where);
if (count($where) > 0 && count($like) > 0)
{
$conditions .= " AND ";
}
$conditions .= implode("\n", $like);
}
$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
return "DELETE FROM ".$table.$conditions.$limit;
}
// --------------------------------------------------------------------
/**
* Limit string
*
* Generates a platform-specific LIMIT clause
*
* @access public
* @param string the sql query string
* @param integer the number of rows to limit the query to
* @param integer the offset value
* @return string
*/
function _limit($sql, $limit, $offset)
{
if ($offset == 0)
{
$offset = '';
}
else
{
$offset .= ", ";
}
return $sql."LIMIT ".$offset.$limit;
return implode(', ', $this->qb_from);
}
// --------------------------------------------------------------------
@ -777,17 +395,11 @@ class CI_DB_cubrid_driver extends CI_DB {
/**
* Close DB Connection
*
* @access public
* @param resource
* @return void
*/
function _close($conn_id)
protected function _close()
{
@cubrid_close($conn_id);
cubrid_close($this->conn_id);
}
}
/* End of file cubrid_driver.php */
/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */

View file

@ -1,289 +1,227 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 2.1.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CUBRID Forge Class
*
* @category Database
* @author Esen Sagynov
* @link http://codeigniter.com/user_guide/database/
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_cubrid_forge extends CI_DB_forge {
/**
* Create database
* CREATE DATABASE statement
*
* @access private
* @param string the database name
* @return bool
* @var string
*/
function _create_database($name)
{
// CUBRID does not allow to create a database in SQL. The GUI tools
// have to be used for this purpose.
return FALSE;
}
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'
);
// --------------------------------------------------------------------
/**
* Drop database
* ALTER TABLE
*
* @access private
* @param string the database name
* @return bool
* @param string $alter_type ALTER type
* @param string $table Table name
* @param mixed $field Column definition
* @return string|string[]
*/
function _drop_database($name)
protected function _alter_table($alter_type, $table, $field)
{
// CUBRID does not allow to drop a database in SQL. The GUI tools
// have to be used for this purpose.
return FALSE;
}
// --------------------------------------------------------------------
/**
* Process Fields
*
* @access private
* @param mixed the fields
* @return string
*/
function _process_fields($fields)
{
$current_field_count = 0;
$sql = '';
foreach ($fields as $field=>$attributes)
if (in_array($alter_type, array('DROP', 'ADD'), TRUE))
{
// Numeric field names aren't allowed in databases, so if the key is
// numeric, we know it was assigned by PHP and the developer manually
// entered the field information, so we'll simply add it to the list
if (is_numeric($field))
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)
{
$sql .= "\n\t$attributes";
$sqls[] = $sql.' CHANGE '.$field[$i]['_literal'];
}
else
{
$attributes = array_change_key_case($attributes, CASE_UPPER);
$alter_type = empty($field[$i]['new_name']) ? ' MODIFY ' : ' CHANGE ';
$sqls[] = $sql.$alter_type.$this->_process_column($field[$i]);
}
}
$sql .= "\n\t\"" . $this->db->_protect_identifiers($field) . "\"";
return $sqls;
}
if (array_key_exists('NAME', $attributes))
// --------------------------------------------------------------------
/**
* 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++)
{
$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';
}
if (array_key_exists('TYPE', $attributes))
{
$sql .= ' '.$attributes['TYPE'];
if (array_key_exists('CONSTRAINT', $attributes))
if ( ! isset($this->fields[$this->keys[$i][$i2]]))
{
switch ($attributes['TYPE'])
{
case 'decimal':
case 'float':
case 'numeric':
$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
break;
case 'enum': // As of version 8.4.0 CUBRID does not support
// enum data type.
break;
case 'set':
$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
break;
default:
$sql .= '('.$attributes['CONSTRAINT'].')';
}
unset($this->keys[$i][$i2]);
continue;
}
}
if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
{
//$sql .= ' UNSIGNED';
// As of version 8.4.0 CUBRID does not support UNSIGNED INTEGER data type.
// Will be supported in the next release as a part of MySQL Compatibility.
}
if (array_key_exists('DEFAULT', $attributes))
{
$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
}
if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
{
$sql .= ' NULL';
}
else
{
$sql .= ' NOT NULL';
}
if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
{
$sql .= ' AUTO_INCREMENT';
}
if (array_key_exists('UNIQUE', $attributes) && $attributes['UNIQUE'] === TRUE)
{
$sql .= ' UNIQUE';
}
}
// don't add a comma on the end of the last field
if (++$current_field_count < count($fields))
elseif ( ! isset($this->fields[$this->keys[$i]]))
{
$sql .= ',';
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])).')';
}
return $sql;
}
$this->keys = array();
// --------------------------------------------------------------------
/**
* Create Table
*
* @access private
* @param string the table name
* @param mixed the fields
* @param mixed primary key(s)
* @param mixed key(s)
* @param boolean should 'IF NOT EXISTS' be added to the SQL
* @return bool
*/
function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
{
$sql = 'CREATE TABLE ';
if ($if_not_exists === TRUE)
{
//$sql .= 'IF NOT EXISTS ';
// As of version 8.4.0 CUBRID does not support this SQL syntax.
}
$sql .= $this->db->_escape_identifiers($table)." (";
$sql .= $this->_process_fields($fields);
// If there is a PK defined
if (count($primary_keys) > 0)
{
$key_name = "pk_" . $table . "_" .
$this->db->_protect_identifiers(implode('_', $primary_keys));
$primary_keys = $this->db->_protect_identifiers($primary_keys);
$sql .= ",\n\tCONSTRAINT " . $key_name . " PRIMARY KEY(" . implode(', ', $primary_keys) . ")";
}
if (is_array($keys) && count($keys) > 0)
{
foreach ($keys as $key)
{
if (is_array($key))
{
$key_name = $this->db->_protect_identifiers(implode('_', $key));
$key = $this->db->_protect_identifiers($key);
}
else
{
$key_name = $this->db->_protect_identifiers($key);
$key = array($key_name);
}
$sql .= ",\n\tKEY \"{$key_name}\" (" . implode(', ', $key) . ")";
}
}
$sql .= "\n);";
return $sql;
}
// --------------------------------------------------------------------
/**
* Drop Table
*
* @access private
* @return string
*/
function _drop_table($table)
{
return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
}
// --------------------------------------------------------------------
/**
* Alter table query
*
* Generates a platform-specific query so that a table can be altered
* Called by add_column(), drop_column(), and column_alter(),
*
* @access private
* @param string the ALTER type (ADD, DROP, CHANGE)
* @param string the column name
* @param array fields
* @param string the field after which we should add the new field
* @return object
*/
function _alter_table($alter_type, $table, $fields, $after_field = '')
{
$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";
// DROP has everything it needs now.
if ($alter_type == 'DROP')
{
return $sql.$this->db->_protect_identifiers($fields);
}
$sql .= $this->_process_fields($fields);
if ($after_field != '')
{
$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
}
return $sql;
}
// --------------------------------------------------------------------
/**
* Rename a table
*
* Generates a platform-specific query so that a table can be renamed
*
* @access private
* @param string the old table name
* @param string the new table name
* @return string
*/
function _rename_table($table_name, $new_table_name)
{
$sql = 'RENAME TABLE '.$this->db->_protect_identifiers($table_name)." AS ".$this->db->_protect_identifiers($new_table_name);
return $sql;
}
}
/* End of file cubrid_forge.php */
/* Location: ./system/database/drivers/cubrid/cubrid_forge.php */

View file

@ -1,20 +1,41 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 2.0.2
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 2.1.0
* @filesource
*/
// --------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CUBRID Result Class
@ -23,19 +44,20 @@
*
* @category Database
* @author Esen Sagynov
* @link http://codeigniter.com/user_guide/database/
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_cubrid_result extends CI_DB_result {
/**
* Number of rows in the result set
*
* @access public
* @return integer
* @return int
*/
function num_rows()
public function num_rows()
{
return @cubrid_num_rows($this->result_id);
return is_int($this->num_rows)
? $this->num_rows
: $this->num_rows = cubrid_num_rows($this->result_id);
}
// --------------------------------------------------------------------
@ -43,12 +65,11 @@ class CI_DB_cubrid_result extends CI_DB_result {
/**
* Number of fields in the result set
*
* @access public
* @return integer
* @return int
*/
function num_fields()
public function num_fields()
{
return @cubrid_num_fields($this->result_id);
return cubrid_num_fields($this->result_id);
}
// --------------------------------------------------------------------
@ -58,10 +79,9 @@ class CI_DB_cubrid_result extends CI_DB_result {
*
* Generates an array of column names
*
* @access public
* @return array
*/
function list_fields()
public function list_fields()
{
return cubrid_column_names($this->result_id);
}
@ -73,59 +93,19 @@ class CI_DB_cubrid_result extends CI_DB_result {
*
* Generates an array of objects containing field meta-data
*
* @access public
* @return array
*/
function field_data()
public function field_data()
{
$retval = array();
$tablePrimaryKeys = array();
while ($field = cubrid_fetch_field($this->result_id))
for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
{
$F = new stdClass();
$F->name = $field->name;
$F->type = $field->type;
$F->default = $field->def;
$F->max_length = $field->max_length;
// At this moment primary_key property is not returned when
// cubrid_fetch_field is called. The following code will
// provide a patch for it. primary_key property will be added
// in the next release.
// TODO: later version of CUBRID will provide primary_key
// property.
// When PK is defined in CUBRID, an index is automatically
// created in the db_index system table in the form of
// pk_tblname_fieldname. So the following will count how many
// columns are there which satisfy this format.
// The query will search for exact single columns, thus
// compound PK is not supported.
$res = cubrid_query($this->conn_id,
"SELECT COUNT(*) FROM db_index WHERE class_name = '" . $field->table .
"' AND is_primary_key = 'YES' AND index_name = 'pk_" .
$field->table . "_" . $field->name . "'"
);
if ($res)
{
$row = cubrid_fetch_array($res, CUBRID_NUM);
$F->primary_key = ($row[0] > 0 ? 1 : null);
}
else
{
$F->primary_key = null;
}
if (is_resource($res))
{
cubrid_close_request($res);
$this->result_id = FALSE;
}
$retval[] = $F;
$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;
@ -136,13 +116,12 @@ class CI_DB_cubrid_result extends CI_DB_result {
/**
* Free the result
*
* @return null
* @return void
*/
function free_result()
public function free_result()
{
if(is_resource($this->result_id) ||
get_resource_type($this->result_id) == "Unknown" &&
preg_match('/Resource id #/', strval($this->result_id)))
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;
@ -156,12 +135,12 @@ class CI_DB_cubrid_result extends CI_DB_result {
*
* Moves the internal pointer to the desired offset. We call
* this internally before fetching results to make sure the
* result set starts at zero
* result set starts at zero.
*
* @access private
* @return array
* @param int $n
* @return bool
*/
function _data_seek($n = 0)
public function data_seek($n = 0)
{
return cubrid_data_seek($this->result_id, $n);
}
@ -173,10 +152,9 @@ class CI_DB_cubrid_result extends CI_DB_result {
*
* Returns the result set as an array
*
* @access private
* @return array
*/
function _fetch_assoc()
protected function _fetch_assoc()
{
return cubrid_fetch_assoc($this->result_id);
}
@ -188,16 +166,12 @@ class CI_DB_cubrid_result extends CI_DB_result {
*
* Returns the result set as an object
*
* @access private
* @param string $class_name
* @return object
*/
function _fetch_object()
protected function _fetch_object($class_name = 'stdClass')
{
return cubrid_fetch_object($this->result_id);
return cubrid_fetch_object($this->result_id, $class_name);
}
}
/* End of file cubrid_result.php */
/* Location: ./system/database/drivers/cubrid/cubrid_result.php */

View file

@ -1,109 +1,79 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
* An open source application development framework for PHP
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 2.1.0
* @filesource
*/
// ------------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CUBRID Utility Class
*
* @category Database
* @author Esen Sagynov
* @link http://codeigniter.com/user_guide/database/
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_cubrid_utility extends CI_DB_utility {
/**
* List databases
*
* @access private
* @return array
*/
function _list_databases()
public function list_databases()
{
// CUBRID does not allow to see the list of all databases on the
// server. It is the way its architecture is designed. Every
// database is independent and isolated.
// For this reason we can return only the name of the currect
// connected database.
if ($this->conn_id)
if (isset($this->db->data_cache['db_names']))
{
return "SELECT '" . $this->database . "'";
}
else
{
return FALSE;
return $this->db->data_cache['db_names'];
}
return $this->db->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
}
// --------------------------------------------------------------------
/**
* Optimize table query
*
* Generates a platform-specific query so that a table can be optimized
*
* @access private
* @param string the table name
* @return object
* @link http://www.cubrid.org/manual/840/en/Optimize%20Database
*/
function _optimize_table($table)
{
// No SQL based support in CUBRID as of version 8.4.0. Database or
// table optimization can be performed using CUBRID Manager
// database administration tool. See the link above for more info.
return FALSE;
}
// --------------------------------------------------------------------
/**
* Repair table query
*
* Generates a platform-specific query so that a table can be repaired
*
* @access private
* @param string the table name
* @return object
* @link http://www.cubrid.org/manual/840/en/Checking%20Database%20Consistency
*/
function _repair_table($table)
{
// Not supported in CUBRID as of version 8.4.0. Database or
// table consistency can be checked using CUBRID Manager
// database administration tool. See the link above for more info.
return FALSE;
}
// --------------------------------------------------------------------
/**
* CUBRID Export
*
* @access private
* @param array Preferences
* @return mixed
*/
function _backup($params = array())
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_unsuported_feature');
return $this->db->display_error('db_unsupported_feature');
}
}
/* End of file cubrid_utility.php */
/* Location: ./system/database/drivers/cubrid/cubrid_utility.php */

View file

@ -1,3 +1,4 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
@ -7,4 +8,4 @@
<p>Directory access is forbidden.</p>
</body>
</html>
</html>

View file

@ -0,0 +1,396 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 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.
*
* @package CodeIgniter
* @subpackage Drivers
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_ibase_driver extends CI_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);
}
}

View file

@ -0,0 +1,251 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Interbase/Firebird Forge Class
*
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_ibase_forge extends CI_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
}
}

View file

@ -0,0 +1,161 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Interbase/Firebird Result Class
*
* This class extends the parent result class: CI_DB_result
*
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_ibase_result extends CI_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;
}
}

View file

@ -0,0 +1,69 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2016, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @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/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Interbase/Firebird Utility Class
*
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
*/
class CI_DB_ibase_utility extends CI_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;
}
}

Some files were not shown because too many files have changed in this diff Show more