diff --git a/.gitignore b/.gitignore index 501d9c4f..1032cd58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,20 @@ -.idea -.tmp-package -composer -easyappointments.zip -node_modules +.idea/ +.tmp-package/ +composer/ +*.zip +node_modules/ npm-debug.log src/storage/cache/* !src/storage/cache/.htaccess !src/storage/cache/index.html src/storage/logs/* !src/storage/logs/index.html +src/storage/sessions/* +!src/storage/sessions/.htaccess +!src/storage/sessions/index.html src/storage/uploads/* !src/storage/uploads/index.html src/config.php -doc/apigen -doc/jsdoc -doc/plato +doc/apigen/ +doc/jsdoc/ +doc/plato/ diff --git a/CHANGELOG.md b/CHANGELOG.md index fc40d0a7..db01daa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,11 @@ # Easy!Appointments - Changelog -This file contains the code changes that were introduced into each release -(starting from v1.1.0) so that is easy for developers to maintain and readjust -their custom modifications on the main project codebase. +This file contains the code changes that were introduced into each release (starting from v1.1.0) so that is easy for +developers to maintain and readjust their custom modifications on the main project codebase. +### Version 1.2.1 + +- #241: Set default sessions save_path directory because many servers do not have this option set. +- #306: Back-end login does not work with PHP 7.1. ### Version 1.2.0 - #185: Enable fixed availabilities setting for services. @@ -24,11 +27,13 @@ their custom modifications on the main project codebase. - #22: Google Calendar Sync - Time Zone Issue ### Version 1.1.1 + - #116: Book advance timeout not taken into account for proposed appointments. - #118: Google Calendar and notification mail problem bug. - #120: Invalid appointment date set after editing an existing appointment. ### Version 1.1.0 + - #4: Raising more useful exceptions and enable error logging by default. - #6: Business Logic created is not getting assigned to service provider. - #10: Unable to use address tags in email address. diff --git a/README.md b/README.md index 15f925a5..b23151b5 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ your existing website, because it can be installed in a single folder of the ser both sites can share the same database. ### Features + The project was designed to be flexible and reliable so as to be able to meet the needs of any kind of enterprise. You can read the main features of the system below: @@ -26,12 +27,14 @@ kind of enterprise. You can read the main features of the system below: * User community support. ### Installation + Since Easy!Appointments is a web application, it runs on a web server and thus you will need to perform the following steps in order to install the system on your server: * Make sure that your server has Apache, PHP and MySQL installed. * Create a new database (or use an existing). * Copy the "easyappointments" source folder on your server. +* Ensure that the "storage" directory is writable. * Rename the "config-sample.php" file to "config.php" and set your server properties. * Open your browser on the Easy!Appointments URL and follow the installation guide. * That's it! You can now use Easy!Appointments at your will. @@ -44,12 +47,14 @@ You can also report problems on the [issues page](https://github.com/alextselegi and help the development progress. ### User Feedback + Whether it is new ideas or defects, your feedback is highly appreciated and will be taken into consideration for the following releases of the project. Share your experience and discuss your thoughts with other users through communities. Create issues with suggestions on new features or bug reports. ### Translate Easy!Appointments + As of version 1.0 Easy!Appointments supports translated user interface. If you want to contribute to the translation process read the [get involved](https://github.com/alextselegidis/easyappointments/wiki/Get-Involved!) page for additional information. diff --git a/composer.json b/composer.json index 90e80895..d5fd7c0b 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "vendor-dir": "composer" }, "require-dev": { - "codeigniter/framework": "^3.0", + "codeigniter/framework": "~3.1.4", "phpunit/phpunit": "^5.6" }, "require": { diff --git a/composer.lock b/composer.lock index f6365add..055117ce 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "52a00fed1a89eb4d3d6321de418669f0", - "content-hash": "fe4302679c1523cf63192337d8f4a61f", + "content-hash": "25bac256233b0471e7cc3b8922e61b61", "packages": [ { "name": "gregwar/captcha", @@ -53,32 +52,47 @@ "captcha", "spam" ], - "time": "2015-09-11 15:23:20" + "time": "2015-09-11T15:23:20+00:00" }, { "name": "phpmailer/phpmailer", - "version": "v5.2.14", + "version": "v5.2.23", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "e774bc9152de85547336e22b8926189e582ece95" + "reference": "7115df4a6f76281109ebe352900c42403b728bb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e774bc9152de85547336e22b8926189e582ece95", - "reference": "e774bc9152de85547336e22b8926189e582ece95", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/7115df4a6f76281109ebe352900c42403b728bb4", + "reference": "7115df4a6f76281109ebe352900c42403b728bb4", "shasum": "" }, "require": { "php": ">=5.0.0" }, "require-dev": { - "phpdocumentor/phpdocumentor": "*", - "phpunit/phpunit": "4.7.*" + "doctrine/annotations": "1.2.*", + "jms/serializer": "0.16.*", + "phpdocumentor/phpdocumentor": "2.*", + "phpunit/phpunit": "4.8.*", + "symfony/debug": "2.8.*", + "symfony/filesystem": "2.8.*", + "symfony/translation": "2.8.*", + "symfony/yaml": "2.8.*", + "zendframework/zend-cache": "2.5.1", + "zendframework/zend-config": "2.5.1", + "zendframework/zend-eventmanager": "2.5.1", + "zendframework/zend-filter": "2.5.1", + "zendframework/zend-i18n": "2.5.1", + "zendframework/zend-json": "2.5.1", + "zendframework/zend-math": "2.5.1", + "zendframework/zend-serializer": "2.5.*", + "zendframework/zend-servicemanager": "2.5.*", + "zendframework/zend-stdlib": "2.5.1" }, "suggest": { - "league/oauth2-client": "Needed for XOAUTH2 authentication", - "league/oauth2-google": "Needed for Gmail XOAUTH2" + "league/oauth2-google": "Needed for Google XOAUTH2 authentication" }, "type": "library", "autoload": { @@ -114,29 +128,30 @@ } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "time": "2015-11-01 10:15:28" + "time": "2017-03-15T19:32:56+00:00" } ], "packages-dev": [ { "name": "codeigniter/framework", - "version": "3.0.6", + "version": "3.1.4", "source": { "type": "git", "url": "https://github.com/bcit-ci/CodeIgniter.git", - "reference": "8082544c5b4b33175790f505587e202e3ca9e488" + "reference": "873608df8be83420474e3cf9fc749a8ed12a6c09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/8082544c5b4b33175790f505587e202e3ca9e488", - "reference": "8082544c5b4b33175790f505587e202e3ca9e488", + "url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/873608df8be83420474e3cf9fc749a8ed12a6c09", + "reference": "873608df8be83420474e3cf9fc749a8ed12a6c09", "shasum": "" }, "require": { "php": ">=5.2.4" }, "require-dev": { - "mikey179/vfsstream": "1.1.*" + "mikey179/vfsstream": "1.1.*", + "phpunit/phpunit": "4.* || 5.*" }, "suggest": { "paragonie/random_compat": "Provides better randomness in PHP 5.x" @@ -148,7 +163,7 @@ ], "description": "The CodeIgniter framework", "homepage": "https://codeigniter.com", - "time": "2016-03-21 16:26:30" + "time": "2017-03-20T15:51:08+00:00" }, { "name": "doctrine/instantiator", @@ -202,7 +217,7 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "myclabs/deep-copy", @@ -244,7 +259,7 @@ "object", "object graph" ], - "time": "2016-10-31 17:19:45" + "time": "2016-10-31T17:19:45+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -298,7 +313,7 @@ "reflection", "static analysis" ], - "time": "2015-12-27 11:43:31" + "time": "2015-12-27T11:43:31+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -343,7 +358,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-09-30 07:12:33" + "time": "2016-09-30T07:12:33+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -390,7 +405,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-06-10 07:14:17" + "time": "2016-06-10T07:14:17+00:00" }, { "name": "phpspec/prophecy", @@ -452,7 +467,7 @@ "spy", "stub" ], - "time": "2016-06-07 08:13:47" + "time": "2016-06-07T08:13:47+00:00" }, { "name": "phpunit/php-code-coverage", @@ -515,7 +530,7 @@ "testing", "xunit" ], - "time": "2016-11-01 05:06:24" + "time": "2016-11-01T05:06:24+00:00" }, { "name": "phpunit/php-file-iterator", @@ -562,7 +577,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2015-06-21T13:08:43+00:00" }, { "name": "phpunit/php-text-template", @@ -603,7 +618,7 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", @@ -647,7 +662,7 @@ "keywords": [ "timer" ], - "time": "2016-05-12 18:03:57" + "time": "2016-05-12T18:03:57+00:00" }, { "name": "phpunit/php-token-stream", @@ -696,7 +711,7 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2015-09-15T10:49:45+00:00" }, { "name": "phpunit/phpunit", @@ -778,7 +793,7 @@ "testing", "xunit" ], - "time": "2016-10-25 07:40:25" + "time": "2016-10-25T07:40:25+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -837,7 +852,7 @@ "mock", "xunit" ], - "time": "2016-10-09 07:01:45" + "time": "2016-10-09T07:01:45+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -882,7 +897,7 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2016-02-13 06:45:14" + "time": "2016-02-13T06:45:14+00:00" }, { "name": "sebastian/comparator", @@ -946,7 +961,7 @@ "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2015-07-26T15:48:44+00:00" }, { "name": "sebastian/diff", @@ -998,7 +1013,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08 07:14:41" + "time": "2015-12-08T07:14:41+00:00" }, { "name": "sebastian/environment", @@ -1048,7 +1063,7 @@ "environment", "hhvm" ], - "time": "2016-08-18 05:49:44" + "time": "2016-08-18T05:49:44+00:00" }, { "name": "sebastian/exporter", @@ -1115,7 +1130,7 @@ "export", "exporter" ], - "time": "2016-06-17 09:04:28" + "time": "2016-06-17T09:04:28+00:00" }, { "name": "sebastian/global-state", @@ -1166,7 +1181,7 @@ "keywords": [ "global state" ], - "time": "2015-10-12 03:26:01" + "time": "2015-10-12T03:26:01+00:00" }, { "name": "sebastian/object-enumerator", @@ -1212,7 +1227,7 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2016-01-28 13:25:10" + "time": "2016-01-28T13:25:10+00:00" }, { "name": "sebastian/recursion-context", @@ -1265,7 +1280,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" + "time": "2015-11-11T19:50:13+00:00" }, { "name": "sebastian/resource-operations", @@ -1307,7 +1322,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28 20:34:47" + "time": "2015-07-28T20:34:47+00:00" }, { "name": "sebastian/version", @@ -1350,7 +1365,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-02-04 12:56:52" + "time": "2016-02-04T12:56:52+00:00" }, { "name": "symfony/yaml", @@ -1399,7 +1414,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-10-24 18:41:13" + "time": "2016-10-24T18:41:13+00:00" }, { "name": "webmozart/assert", @@ -1449,7 +1464,7 @@ "check", "validate" ], - "time": "2016-08-09 15:02:57" + "time": "2016-08-09T15:02:57+00:00" } ], "aliases": [], diff --git a/doc/faq.md b/doc/faq.md index 1ed854cb..8b9f72fb 100644 --- a/doc/faq.md +++ b/doc/faq.md @@ -45,6 +45,6 @@ The following link points to a common question that many users ask. The default (https://groups.google.com/d/msg/easy-appointments/Mdt98fbF8hE/9CEjOvW7FAAJ) -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. [Back](readme.md) diff --git a/doc/get-involved.md b/doc/get-involved.md index 1d39509a..e3c0b545 100644 --- a/doc/get-involved.md +++ b/doc/get-involved.md @@ -5,17 +5,21 @@ Easy!Appointments is an open source project and thus the connection with the users community is stronger than commercial projects. People can contribute in the development and spread of this project and make it even better so that they, themselves can take advantage of it in order to fulfill their business needs. Bellow are described the ways that you can help Easy!Appointments get better. ### Testing + The most important goal of Easy!Appointments is performance and stability and that means that **everything must work as expected**. Even though the project has been tested thoroughly during its Beta phase it is important that bugs are tracked down and are fixed as soon as possible. ### Suggestions + Everything you might suggest about the project will be taken into concern and is highly appreciated. Your ideas of new features and enhancements are very important and will help Easy!Appointments become even better. So do not hesitate to submit your suggestions and feature requests to [E!A Submission Form](http://easyappointments.org/submission.php) ### Translation + You are more than welcome to help with the translation progress of the user interface. The application is already translated into a big variety of languages but as new features are added new strings need to be translated. You can send your translations with a pull request in GitHub or per email to [alextselegidis@gmail.com](mailto:alextselegidis@gmail.com) ### User Feedback + It would be much appreciated if you would take 5 minutes of your time to fill this small form on your experience with Easy!Appointments. User feedback is very important and will help with the future planning of the project. Fill the [E!A Feedback Form](https://docs.google.com/forms/d/15dw1jl7lUgw4q-XXMn13Gx_e8zJxAiyWYMOdqtZqIHU/viewform). -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. [Back](readme.md) diff --git a/doc/google-calendar-sync.md b/doc/google-calendar-sync.md index 05abdcbc..6156f176 100644 --- a/doc/google-calendar-sync.md +++ b/doc/google-calendar-sync.md @@ -49,6 +49,6 @@ Google Developers – https://developers.google.com/google-apps/calendar E!A Support Group – https://groups.google.com/forum/#!forum/easy-appointments -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. [Back](readme.md) diff --git a/doc/installation-guide.md b/doc/installation-guide.md index 67e4a0f0..1604cc33 100644 --- a/doc/installation-guide.md +++ b/doc/installation-guide.md @@ -6,13 +6,14 @@ Easy!Appointments is a web appointment scheduler that can be installed and run in web servers. Users will be able to reach the application through their web browsers by using an active internet connection, just like visiting a normal website. The installation process is very similar to other popular web systems like WordPress and Joomla, so it is very likely that you will be familiar with the next steps. Follow this article strictly in order to complete the installation with no problems. After that, read the "Configuration" section for adjusting the system to fit your needs. ### Installation -There are 5 steps you must follow during the installation process. +There are 6 steps you must follow during the installation process. - 1. **Make sure that your server has at least the following applications/tools installed: Apache(v2.4), PHP(v5.4) and MySQL(v5.5).** Easy!Appointments needs these programs to run. Most of the web hosting companies provide these tools within their Linux hosting plans. If you want to install Easy!Appointments on your local server use one of the pre-made bundles available on the web (XAMPP, MAMP, WAMP ...), all of which are free to use. If you plan to use the Google Calendar synchronization you will need the **php_curl** extension installed and enabled as well. + 1. **Make sure that your server has at least the following applications/tools installed: Apache(v2.4), PHP(v5.6) and MySQL(v5.5).** Easy!Appointments needs these programs to run. Most of the web hosting companies provide these tools within their Linux hosting plans. If you want to install Easy!Appointments on your local server use one of the pre-made bundles available on the web (XAMPP, MAMP, WAMP ...), all of which are free to use. If you plan to use the Google Calendar synchronization you will need the **php_curl** extension installed and enabled as well. 2. **Create a new database (or use an existing one).** The database is necessary for storing the system data. Therefore your hosting plan must include at least one MySQL database. You must also get the database administration credentials because they will be needed later on. - 3. **Upload the Easy!Appointments source files to your server.** You can place the files into a directory with named "easyappointments" or "appointments" or "book" etc. Make sure that you mark the Easy!Appointments folder URL because it will be needed in the following step. For example if the system files are placed in the this directory ".../httpdocs/easyappointments/" then the URL to this folder will be "http://your-domain.com/easyappointments". This URL will be needed in the following step. - 4. **Edit the "config.php" file and set your server properties.** Like other web systems Easy!Appointments needs to know how to connect to the database and the base URL of the installation. You can also provide the Google Calendar API keys in this file, if you want to use the Google Calendar Sync feature. NOTE that you will need to create an API key before that in the Google Cloud Console. - 5. **Open a web browser and head to the Easy!Appointments installation folder URL.** The first time you open this page an installation guide will be shown. Fill in the administrator user and company settings and press the "Install" button. That's it! You can now use the application at your own will. + 3. **Upload the Easy!Appointments source files to your server.** You can place the files into a directory with named "easyappointments" or "appointments" or "book" etc. Make sure that you mark the Easy!Appointments folder URL because it will be needed in the following step. For example if the system files are placed in the this directory ".../httpdocs/easyappointments/" then the URL to this folder will be "http://your-domain.com/easyappointments". This URL will be needed in the following steps. + 4. **Ensure that the "storage" directory is writable.** Session information, logs and any other kind of files will land into the "storage" directory so make sure that it has the correct permissions and that is writable. + 5. **Edit the "config.php" file and set your server properties.** Like other web systems Easy!Appointments needs to know how to connect to the database and the base URL of the installation. You can also provide the Google Calendar API keys in this file, if you want to use the Google Calendar Sync feature. NOTE that you will need to create an API key before that in the Google Cloud Console. + 6. **Open a web browser and head to the Easy!Appointments installation folder URL.** The first time you open this page an installation guide will be shown. Fill in the administrator user and company settings and press the "Install" button. That's it! You can now use the application at your own will. ### Configuration @@ -28,6 +29,6 @@ Finally just add a link in your website that points to your Easy!Appointments in Happy Bookin'! -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. [Back](readme.md) diff --git a/doc/manage-translations.md b/doc/manage-translations.md index a548147a..08b9740d 100644 --- a/doc/manage-translations.md +++ b/doc/manage-translations.md @@ -14,6 +14,6 @@ Easy!Appointments is based upon CodeIgniter (PHP Framework) and it uses its buil Follow these steps in order to add or adjust your translations and modify the message of the user interface of Easy!Appointments. If you want contribute to the translation process of Easy!Appointments please read the [Get Involved](https://github.com/alextselegidis/easyappointments/wiki/Get-Involved!) wiki page for more information. Please share your translations with the user community. -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. [Back](readme.md) diff --git a/doc/readme.md b/doc/readme.md index 65acc666..92f72be3 100644 --- a/doc/readme.md +++ b/doc/readme.md @@ -10,4 +10,4 @@ Welcome to the documentation pages of Easy!Appointments. Navigate through the av - [Get Involved!](get-involved.md) - [FAQ](faq.md) -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. diff --git a/doc/rest-api.md b/doc/rest-api.md index 502f76f8..9941b4c5 100644 --- a/doc/rest-api.md +++ b/doc/rest-api.md @@ -433,6 +433,6 @@ fastcgi_param PHP_AUTH_PW $http_authorization; [[Source]](http://serverfault.com/a/520943) -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. [Back](readme.md) diff --git a/doc/update-guide.md b/doc/update-guide.md index fedaca90..9b0c9288 100644 --- a/doc/update-guide.md +++ b/doc/update-guide.md @@ -8,10 +8,14 @@ This page will guide you through the update procedure of your Easy!Appointments If by chance you get a 500 Internal Server Error message then you must check the error log files of your server. These kind of errors comes mostly due to problematic server configuration (permissions, credentials etc). +### Updating from v1.1.x to v1.2.x + +Version v1.2 introduces two new folders in the root directory of the project, the "engine" and the "storage" directory. Ensure that the storage directory is writable and has the correct permissions. + ### Updating from v1.0 to v1.1.x Many core files were changed in v1.1 and it would be better if you replace all the Easy!Appointments files of version 1.0 with the new ones. Use the data of the old `configuration.php` file in the new `config.php` and open the `http://url-to-ea-installation/index.php/backend/update` as already mentioned. Your new version should work just fine! -*This document applies to Easy!Appointments v1.2*. +*This document applies to Easy!Appointments v1.2.1*. [Back](readme.md) diff --git a/gulpfile.js b/gulpfile.js index 18cb6deb..fb62bb76 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -51,8 +51,26 @@ gulp.task('build', function(done) { fs.copySync('LICENSE', '.tmp-package/LICENSE'); del.sync([ - '.tmp-package/application/logs/*', - '!.tmp-package/application/logs/index.html' + '.tmp-package/storage/uploads/*', + '!.tmp-package/storage/uploads/index.html' + ]); + + del.sync([ + '.tmp-package/storage/logs/*', + '!.tmp-package/storage/logs/.htaccess', + '!.tmp-package/storage/logs/index.html' + ]); + + del.sync([ + '.tmp-package/storage/sessions/*', + '!.tmp-package/storage/sessions/.htaccess', + '!.tmp-package/storage/sessions/index.html' + ]); + + del.sync([ + '.tmp-package/storage/cache/*', + '!.tmp-package/storage/cache/.htaccess', + '!.tmp-package/storage/cache/index.html' ]); zip('.tmp-package', { saveTo: 'easyappointments.zip' }, function (err, buffer) { diff --git a/package.json b/package.json index 6b3063aa..50cbca02 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "easyappointments", - "version": "1.2.0", + "version": "1.2.1", "description": "Open Source Web Scheduler", "repository": { "type": "git", diff --git a/src/application/config/config.php b/src/application/config/config.php index 3572a706..ab7ce035 100644 --- a/src/application/config/config.php +++ b/src/application/config/config.php @@ -8,7 +8,7 @@ | Declare some of the global config values of Easy!Appointments. | */ -$config['version'] = '1.2'; // This must be changed manually. +$config['version'] = '1.2.1'; // This must be changed manually. $config['release_label'] = ''; // Leave empty for no title or add Alpha, Beta etc ... $config['google_sync_feature'] = Config::GOOGLE_SYNC_FEATURE; @@ -292,9 +292,9 @@ $config['encryption_key'] = Config::BASE_URL; | */ $config['sess_driver'] = 'files'; -$config['sess_cookie_name'] = 'ci_session'; +$config['sess_cookie_name'] = 'ea_session'; $config['sess_expiration'] = 7200; -$config['sess_save_path'] = NULL; +$config['sess_save_path'] = __DIR__ . '/../../storage/sessions'; $config['sess_match_ip'] = FALSE; $config['sess_time_to_update'] = 300; $config['sess_regenerate_destroy'] = FALSE; diff --git a/src/index.php b/src/index.php index 9b6b86be..c270d274 100644 --- a/src/index.php +++ b/src/index.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 diff --git a/src/storage/sessions/.htaccess b/src/storage/sessions/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/src/storage/sessions/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/src/storage/sessions/index.html b/src/storage/sessions/index.html new file mode 100644 index 00000000..c942a79c --- /dev/null +++ b/src/storage/sessions/index.html @@ -0,0 +1,10 @@ + +
+Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/src/system/core/Benchmark.php b/src/system/core/Benchmark.php index b1d74f78..b3ac79c6 100644 --- a/src/system/core/Benchmark.php +++ b/src/system/core/Benchmark.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 diff --git a/src/system/core/CodeIgniter.php b/src/system/core/CodeIgniter.php index 3eb3e057..880abab5 100644 --- a/src/system/core/CodeIgniter.php +++ b/src/system/core/CodeIgniter.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -55,7 +55,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @var string * */ - define('CI_VERSION', '3.0.6'); + const CI_VERSION = '3.1.4'; /* * ------------------------------------------------------ @@ -67,7 +67,10 @@ defined('BASEPATH') OR exit('No direct script access allowed'); require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); } - require_once(APPPATH.'config/constants.php'); + if (file_exists(APPPATH.'config/constants.php')) + { + require_once(APPPATH.'config/constants.php'); + } /* * ------------------------------------------------------ @@ -416,14 +419,29 @@ if ( ! is_php('5.4')) $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)) + elseif ( ! method_exists($class, $method)) { $e404 = TRUE; } + /** + * DO NOT CHANGE THIS, NOTHING ELSE WORKS! + * + * - method_exists() returns true for non-public methods, which passes the previous elseif + * - is_callable() returns false for PHP 4-style constructors, even if there's a __construct() + * - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited + * - People will only complain if this doesn't work, even though it is documented that it shouldn't. + * + * ReflectionMethod::isConstructor() is the ONLY reliable check, + * knowing which method will be executed as a constructor. + */ + elseif ( ! is_callable(array($class, $method)) && strcasecmp($class, $method) === 0) + { + $reflection = new ReflectionMethod($class, $method); + if ( ! $reflection->isPublic() OR $reflection->isConstructor()) + { + $e404 = TRUE; + } + } } if ($e404) diff --git a/src/system/core/Common.php b/src/system/core/Common.php index b87ce4d6..2fd5c580 100644 --- a/src/system/core/Common.php +++ b/src/system/core/Common.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -319,17 +319,13 @@ if ( ! function_exists('get_mimes')) if (empty($_mimes)) { + $_mimes = file_exists(APPPATH.'config/mimes.php') + ? include(APPPATH.'config/mimes.php') + : array(); + if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) { - $_mimes = include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); - } - elseif (file_exists(APPPATH.'config/mimes.php')) - { - $_mimes = include(APPPATH.'config/mimes.php'); - } - else - { - $_mimes = array(); + $_mimes = array_merge($_mimes, include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')); } } @@ -355,7 +351,7 @@ if ( ! function_exists('is_https')) { return TRUE; } - elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') + elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') { return TRUE; } @@ -410,11 +406,6 @@ if ( ! function_exists('show_error')) if ($status_code < 100) { $exit_status = $status_code + 9; // 9 is EXIT__AUTO_MIN - if ($exit_status > 125) // 125 is EXIT__AUTO_MAX - { - $exit_status = 1; // EXIT_ERROR - } - $status_code = 500; } else @@ -544,13 +535,18 @@ if ( ! function_exists('set_status_header')) 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 422 => 'Unprocessable Entity', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported' + 505 => 'HTTP Version Not Supported', + 511 => 'Network Authentication Required', ); if (isset($stati[$code])) @@ -566,12 +562,12 @@ if ( ! function_exists('set_status_header')) if (strpos(PHP_SAPI, 'cgi') === 0) { header('Status: '.$code.' '.$text, TRUE); + return; } - else - { - $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; - header($server_protocol.' '.$code.' '.$text, TRUE, $code); - } + + $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2'), TRUE)) + ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; + header($server_protocol.' '.$code.' '.$text, TRUE, $code); } } @@ -598,7 +594,7 @@ if ( ! function_exists('_error_handler')) */ function _error_handler($severity, $message, $filepath, $line) { - $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); + $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); // When an error occurred, set the status header to '500 Internal Server Error' // to indicate to the client something went wrong. @@ -656,6 +652,7 @@ if ( ! function_exists('_exception_handler')) $_error =& load_class('Exceptions', 'core'); $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine()); + is_cli() OR set_status_header(500); // Should we display the error? if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) { @@ -716,8 +713,9 @@ if ( ! function_exists('remove_invisible_characters')) // carriage return (dec 13) and horizontal tab (dec 09) if ($url_encoded) { - $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 - $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31 + $non_displayables[] = '/%0[0-8bcef]/i'; // url encoded 00-08, 11, 12, 14, 15 + $non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31 + $non_displayables[] = '/%7f/i'; // url encoded 127 } $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 @@ -821,7 +819,7 @@ if ( ! function_exists('function_usable')) * terminate script execution if a disabled function is executed. * * The above described behavior turned out to be a bug in Suhosin, - * but even though a fix was commited for 0.9.34 on 2012-02-12, + * but even though a fix was committed for 0.9.34 on 2012-02-12, * that version is yet to be released. This function will therefore * be just temporary, but would probably be kept for a few years. * diff --git a/src/system/core/Config.php b/src/system/core/Config.php index ca6fb379..cda62241 100644 --- a/src/system/core/Config.php +++ b/src/system/core/Config.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -319,7 +319,7 @@ class CI_Config { } } - return $base_url.ltrim($this->_uri_string($uri), '/'); + return $base_url.$this->_uri_string($uri); } // ------------------------------------------------------------- @@ -337,11 +337,8 @@ class CI_Config { { if ($this->item('enable_query_strings') === FALSE) { - if (is_array($uri)) - { - $uri = implode('/', $uri); - } - return trim($uri, '/'); + is_array($uri) && $uri = implode('/', $uri); + return ltrim($uri, '/'); } elseif (is_array($uri)) { diff --git a/src/system/core/Controller.php b/src/system/core/Controller.php index 83b3df26..59a91673 100644 --- a/src/system/core/Controller.php +++ b/src/system/core/Controller.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 diff --git a/src/system/core/Exceptions.php b/src/system/core/Exceptions.php index a1c6a197..47d153f4 100644 --- a/src/system/core/Exceptions.php +++ b/src/system/core/Exceptions.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -207,7 +207,6 @@ class CI_Exceptions { } else { - set_status_header(500); $templates_path .= 'html'.DIRECTORY_SEPARATOR; } diff --git a/src/system/core/Hooks.php b/src/system/core/Hooks.php index 856795cb..f2d6f21c 100644 --- a/src/system/core/Hooks.php +++ b/src/system/core/Hooks.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 diff --git a/src/system/core/Input.php b/src/system/core/Input.php index a7c9ecd0..af4f87c1 100644 --- a/src/system/core/Input.php +++ b/src/system/core/Input.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -359,7 +359,7 @@ class CI_Input { * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) * @return void */ - public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) + public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL) { if (is_array($name)) { @@ -388,15 +388,13 @@ class CI_Input { $path = config_item('cookie_path'); } - if ($secure === FALSE && config_item('cookie_secure') === TRUE) - { - $secure = config_item('cookie_secure'); - } + $secure = ($secure === NULL && config_item('cookie_secure') !== NULL) + ? (bool) config_item('cookie_secure') + : (bool) $secure; - if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE) - { - $httponly = config_item('cookie_httponly'); - } + $httponly = ($httponly === NULL && config_item('cookie_httponly') !== NULL) + ? (bool) config_item('cookie_httponly') + : (bool) $httponly; if ( ! is_numeric($expire)) { @@ -519,9 +517,9 @@ class CI_Input { if ($separator === ':') { $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); - for ($i = 0; $i < 8; $i++) + for ($j = 0; $j < 8; $j++) { - $netaddr[$i] = intval($netaddr[$i], 16); + $netaddr[$j] = intval($netaddr[$j], 16); } } else @@ -760,30 +758,32 @@ class CI_Input { // If header is already defined, return it immediately if ( ! empty($this->headers)) { - return $this->headers; + return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // In Apache, you can simply call apache_request_headers() if (function_exists('apache_request_headers')) { - return $this->headers = apache_request_headers(); + $this->headers = apache_request_headers(); } - - $this->headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE'); - - foreach ($_SERVER as $key => $val) + else { - if (sscanf($key, 'HTTP_%s', $header) === 1) - { - // take SOME_HEADER and turn it into Some-Header - $header = str_replace('_', ' ', strtolower($header)); - $header = str_replace(' ', '-', ucwords($header)); + isset($_SERVER['CONTENT_TYPE']) && $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE']; - $this->headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean); + foreach ($_SERVER as $key => $val) + { + if (sscanf($key, 'HTTP_%s', $header) === 1) + { + // take SOME_HEADER and turn it into Some-Header + $header = str_replace('_', ' ', strtolower($header)); + $header = str_replace(' ', '-', ucwords($header)); + + $this->headers[$header] = $_SERVER[$key]; + } } } - return $this->headers; + return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // -------------------------------------------------------------------- diff --git a/src/system/core/Lang.php b/src/system/core/Lang.php index 1fcff078..569b0236 100644 --- a/src/system/core/Lang.php +++ b/src/system/core/Lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 diff --git a/src/system/core/Loader.php b/src/system/core/Loader.php index c742ae71..5ed6adb4 100644 --- a/src/system/core/Loader.php +++ b/src/system/core/Loader.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -486,7 +486,7 @@ class CI_Loader { */ public function view($view, $vars = array(), $return = FALSE) { - return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); + return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return)); } // -------------------------------------------------------------------- @@ -519,19 +519,13 @@ class CI_Loader { */ public function vars($vars, $val = '') { - if (is_string($vars)) - { - $vars = array($vars => $val); - } + $vars = is_string($vars) + ? array($vars => $val) + : $this->_ci_prepare_view_vars($vars); - $vars = $this->_ci_object_to_array($vars); - - if (is_array($vars) && count($vars) > 0) + foreach ($vars as $key => $val) { - foreach ($vars as $key => $val) - { - $this->_ci_cached_vars[$key] = $val; - } + $this->_ci_cached_vars[$key] = $val; } return $this; @@ -591,15 +585,21 @@ class CI_Loader { */ public function helper($helpers = array()) { - foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper) + is_array($helpers) OR $helpers = array($helpers); + foreach ($helpers as &$helper) { + $filename = basename($helper); + $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); + $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper'; + $helper = $filepath.$filename; + if (isset($this->_ci_helpers[$helper])) { continue; } // Is this a helper extension request? - $ext_helper = config_item('subclass_prefix').$helper; + $ext_helper = config_item('subclass_prefix').$filename; $ext_loaded = FALSE; foreach ($this->_ci_helper_paths as $path) { @@ -934,18 +934,7 @@ class CI_Loader { * the two types and cache them so that views that are embedded within * other views can have access to these variables. */ - if (is_array($_ci_vars)) - { - foreach (array_keys($_ci_vars) as $key) - { - if (strncmp($key, '_ci_', 4) === 0) - { - unset($_ci_vars[$key]); - } - } - - $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); - } + empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); extract($this->_ci_cached_vars); /* @@ -1106,7 +1095,7 @@ class CI_Loader { * @used-by CI_Loader::_ci_load_library() * @uses CI_Loader::_ci_init_library() * - * @param string $library Library name to load + * @param string $library_name Library name to load * @param string $file_path Path to the library filename, relative to libraries/ * @param mixed $params Optional parameters to pass to the class constructor * @param string $object_name Optional object name to assign to @@ -1376,17 +1365,32 @@ class CI_Loader { // -------------------------------------------------------------------- /** - * CI Object to Array translator + * Prepare variables for _ci_vars, to be later extract()-ed inside views * - * Takes an object as input and converts the class variables to - * an associative array with key/value pairs. + * Converts objects to associative arrays and filters-out internal + * variable names (i.e. keys prefixed with '_ci_'). * - * @param object $object Object data to translate + * @param mixed $vars * @return array */ - protected function _ci_object_to_array($object) + protected function _ci_prepare_view_vars($vars) { - return is_object($object) ? get_object_vars($object) : $object; + if ( ! is_array($vars)) + { + $vars = is_object($vars) + ? get_object_vars($vars) + : array(); + } + + foreach (array_keys($vars) as $key) + { + if (strncmp($key, '_ci_', 4) === 0) + { + unset($vars[$key]); + } + } + + return $vars; } // -------------------------------------------------------------------- @@ -1404,34 +1408,4 @@ class CI_Loader { $CI =& get_instance(); return $CI->$component; } - - // -------------------------------------------------------------------- - - /** - * Prep filename - * - * This function prepares filenames of various items to - * make their loading more reliable. - * - * @param string|string[] $filename Filename(s) - * @param string $extension Filename extension - * @return array - */ - protected function _ci_prep_filename($filename, $extension) - { - if ( ! is_array($filename)) - { - return array(strtolower(str_replace(array($extension, '.php'), '', $filename).$extension)); - } - else - { - foreach ($filename as $key => $val) - { - $filename[$key] = strtolower(str_replace(array($extension, '.php'), '', $val).$extension); - } - - return $filename; - } - } - } diff --git a/src/system/core/Log.php b/src/system/core/Log.php index 1abdaa00..d443aedb 100644 --- a/src/system/core/Log.php +++ b/src/system/core/Log.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -104,6 +104,13 @@ class CI_Log { */ protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4); + /** + * mbstring.func_overload flag + * + * @var bool + */ + protected static $func_overload; + // -------------------------------------------------------------------- /** @@ -115,6 +122,8 @@ class CI_Log { { $config =& get_config(); + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + $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'; @@ -208,9 +217,9 @@ class CI_Log { $message .= $this->_format_line($level, $date, $msg); - for ($written = 0, $length = strlen($message); $written < $length; $written += $result) + for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result) { - if (($result = fwrite($fp, substr($message, $written))) === FALSE) + if (($result = fwrite($fp, self::substr($message, $written))) === FALSE) { break; } @@ -237,11 +246,51 @@ class CI_Log { * * @param string $level The error level * @param string $date Formatted date string - * @param string $msg The log message + * @param string $message 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"; } + + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_overload) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/src/system/core/Model.php b/src/system/core/Model.php index 941881a9..c809e7b8 100644 --- a/src/system/core/Model.php +++ b/src/system/core/Model.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 diff --git a/src/system/core/Output.php b/src/system/core/Output.php index ec9c21b9..6ddded22 100644 --- a/src/system/core/Output.php +++ b/src/system/core/Output.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -122,6 +122,13 @@ class CI_Output { */ public $parse_exec_vars = TRUE; + /** + * mbstring.func_overload flag + * + * @var bool + */ + protected static $func_overload; + /** * Class constructor * @@ -138,6 +145,8 @@ class CI_Output { && extension_loaded('zlib') ); + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + // Get mime types for later $this->mimes =& get_mimes(); @@ -285,7 +294,7 @@ class CI_Output { /** * Get Header * - * @param string $header_name + * @param string $header * @return string */ public function get_header($header) @@ -302,11 +311,12 @@ class CI_Output { return NULL; } - for ($i = 0, $c = count($headers); $i < $c; $i++) + // Count backwards, in order to get the last matching header + for ($c = count($headers) - 1; $c > -1; $c--) { - if (strncasecmp($header, $headers[$i], $l = strlen($header)) === 0) + if (strncasecmp($header, $headers[$c], $l = self::strlen($header)) === 0) { - return trim(substr($headers[$i], $l+1)); + return trim(self::substr($headers[$c], $l+1)); } } @@ -480,13 +490,13 @@ class CI_Output { if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { header('Content-Encoding: gzip'); - header('Content-Length: '.strlen($output)); + header('Content-Length: '.self::strlen($output)); } else { // User agent doesn't support gzip compression, // so we'll have to decompress our cache - $output = gzinflate(substr($output, 10, -8)); + $output = gzinflate(self::substr($output, 10, -8)); } } @@ -601,9 +611,9 @@ class CI_Output { $output = $cache_info.'ENDCI--->'.$output; - for ($written = 0, $length = strlen($output); $written < $length; $written += $result) + for ($written = 0, $length = self::strlen($output); $written < $length; $written += $result) { - if (($result = fwrite($fp, substr($output, $written))) === FALSE) + if (($result = fwrite($fp, self::substr($output, $written))) === FALSE) { break; } @@ -711,7 +721,7 @@ class CI_Output { } // Display the cache - $this->_display(substr($cache, strlen($match[0]))); + $this->_display(self::substr($cache, self::strlen($match[0]))); log_message('debug', 'Cache file is current. Sending it to browser.'); return TRUE; } @@ -797,4 +807,43 @@ class CI_Output { } } + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_overload) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/src/system/core/Router.php b/src/system/core/Router.php index 045d3668..1abe4c4e 100644 --- a/src/system/core/Router.php +++ b/src/system/core/Router.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 diff --git a/src/system/core/Security.php b/src/system/core/Security.php index d5305d1c..082ffa96 100644 --- a/src/system/core/Security.php +++ b/src/system/core/Security.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, 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 @@ -29,7 +29,7 @@ * @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/) + * @copyright Copyright (c) 2014 - 2017, 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 @@ -133,15 +133,16 @@ class CI_Security { * @var array */ protected $_never_allowed_str = array( - 'document.cookie' => '[removed]', - 'document.write' => '[removed]', - '.parentNode' => '[removed]', - '.innerHTML' => '[removed]', - '-moz-binding' => '[removed]', - '' => '-->', - ' '<![CDATA[', - '