From 7d2f024e755b61cf5a6689477046af9332d4f1fa Mon Sep 17 00:00:00 2001 From: hide_d Date: Sun, 14 Jan 2018 19:11:14 +0900 Subject: [PATCH] =?UTF-8?q?...=20require=5Fonce=EB=A1=9C=20=EB=90=98?= =?UTF-8?q?=EB=8F=8C=EB=A6=BC=20=E3=85=9C=E3=85=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _common.php | 6 +- che_close/d_setting/_common.php | 6 +- d_setting/_common.php | 6 +- e_lib/plates.php | 2 + e_lib/utilphp-1.1.0/.coveralls.yml | 1 - e_lib/utilphp-1.1.0/.gitignore | 4 - e_lib/utilphp-1.1.0/.travis.yml | 22 - e_lib/utilphp-1.1.0/CHANGELOG.md | 86 -- e_lib/utilphp-1.1.0/CONTRIBUTORS.md | 48 - e_lib/utilphp-1.1.0/LICENSE.md | 24 - e_lib/utilphp-1.1.0/README.md | 123 -- e_lib/utilphp-1.1.0/composer.json | 24 - e_lib/utilphp-1.1.0/docs/css/docs.css | 168 --- e_lib/utilphp-1.1.0/docs/favicon.png | Bin 803 -> 0 bytes .../docs/images/awesome_var_dump.jpg | Bin 41429 -> 0 bytes .../utilphp-1.1.0/docs/images/background.png | Bin 1028 -> 0 bytes .../docs/images/utility_logo.png | Bin 84870 -> 0 bytes e_lib/utilphp-1.1.0/docs/index.html | 1234 ----------------- e_lib/utilphp-1.1.0/phpunit.xml.dist | 25 - e_lib/utilphp-1.1.0/tests/README.md | 39 - e_lib/utilphp-1.1.0/tests/UtilTest.php | 1183 ---------------- f_config/DB.php | 4 +- f_config/DBS.php | 4 +- f_config/MAIL.php | 2 +- f_config/SESSION.php | 4 +- f_config/SETTING.php | 4 +- f_config/SETTINGS.php | 4 +- f_config/_common.php | 6 +- f_config/config.php | 2 +- f_func/_common.php | 6 +- f_func/class._Chat.php | 8 +- f_func/class._DB.php | 2 +- f_func/class._Lock.php | 4 +- f_func/class._Log.php | 8 +- f_func/class._Mail.php | 2 +- f_func/class._Process.php | 4 +- f_func/class._Setting.php | 4 +- f_install/_common.php | 6 +- f_install/install.php | 2 +- f_install/install1.php | 2 +- f_install/install1Post.php | 4 +- f_install/install2.php | 2 +- f_install/install2Post.php | 4 +- f_retrival/_common.php | 6 +- i_entrance/Frame.php | 6 +- i_entrance/_common.php | 6 +- i_entrance/adminInc.php | 2 +- i_entrance/adminPost.php | 89 +- i_entrance/donation/Frame.php | 2 +- i_entrance/donation/Get.php | 8 +- i_entrance/donation/Post.php | 8 +- i_entrance/donation/_common.php | 6 +- i_entrance/donation/calculatePost.php | 8 +- i_entrance/enterPost.php | 8 +- i_entrance/entrance.php | 4 +- i_entrance/logoutPost.php | 8 +- i_entrance/manage/Frame.php | 2 +- i_entrance/manage/Get.php | 8 +- i_entrance/manage/_common.php | 6 +- i_entrance/manage/deletePost.php | 8 +- i_entrance/manage/iconPost.php | 6 +- i_entrance/manage/passwordPost.php | 8 +- i_entrance/manage/quitPost.php | 8 +- i_entrance/member/Frame.php | 2 +- i_entrance/member/Get.php | 8 +- i_entrance/member/Post.php | 8 +- i_entrance/member/_common.php | 6 +- i_entrance/serverListPost.php | 8 +- i_entrance/template/block_htaccess.php | 4 +- i_login/Frame.php | 4 +- i_login/Post.php | 8 +- i_login/_common.php | 6 +- i_login/findpw/Frame.php | 2 +- i_login/findpw/Get.php | 6 +- i_login/findpw/Post.php | 6 +- i_login/findpw/_common.php | 6 +- i_login/findpw/checkPost.php | 6 +- i_login/findpw/sendCodePost.php | 6 +- i_login/findpw/verifyCodePost.php | 6 +- i_login/join/Frame.php | 2 +- i_login/join/Get.php | 6 +- i_login/join/Post.php | 6 +- i_login/join/_common.php | 6 +- i_login/join/checkPost.php | 6 +- i_login/join/sendCodePost.php | 6 +- i_login/join/verifyCodePost.php | 6 +- i_login/login.php | 2 +- i_other/_common.php | 6 +- i_other/help.php | 2 +- i_other/screenshot.php | 2 +- i_popup/Frame.php | 2 +- i_popup/_common.php | 6 +- install.php | 2 +- twe/d_setting/_common.php | 6 +- twe/lib.php | 19 +- 95 files changed, 265 insertions(+), 3208 deletions(-) delete mode 100644 e_lib/utilphp-1.1.0/.coveralls.yml delete mode 100644 e_lib/utilphp-1.1.0/.gitignore delete mode 100644 e_lib/utilphp-1.1.0/.travis.yml delete mode 100644 e_lib/utilphp-1.1.0/CHANGELOG.md delete mode 100644 e_lib/utilphp-1.1.0/CONTRIBUTORS.md delete mode 100644 e_lib/utilphp-1.1.0/LICENSE.md delete mode 100644 e_lib/utilphp-1.1.0/README.md delete mode 100644 e_lib/utilphp-1.1.0/composer.json delete mode 100644 e_lib/utilphp-1.1.0/docs/css/docs.css delete mode 100644 e_lib/utilphp-1.1.0/docs/favicon.png delete mode 100644 e_lib/utilphp-1.1.0/docs/images/awesome_var_dump.jpg delete mode 100644 e_lib/utilphp-1.1.0/docs/images/background.png delete mode 100644 e_lib/utilphp-1.1.0/docs/images/utility_logo.png delete mode 100644 e_lib/utilphp-1.1.0/docs/index.html delete mode 100644 e_lib/utilphp-1.1.0/phpunit.xml.dist delete mode 100644 e_lib/utilphp-1.1.0/tests/README.md delete mode 100644 e_lib/utilphp-1.1.0/tests/UtilTest.php diff --git a/_common.php b/_common.php index da8c3bcb..fecd45f7 100644 --- a/_common.php +++ b/_common.php @@ -2,8 +2,8 @@ if(!defined('ROOT')){ define('ROOT', '.'); } -require(ROOT.'/f_config/config.php'); -require(ROOT.W.F_CONFIG.W.APP.PHP); -require(ROOT.W.F_FUNC.W.FUNC.PHP); +require_once(ROOT.'/f_config/config.php'); +require_once(ROOT.W.F_CONFIG.W.APP.PHP); +require_once(ROOT.W.F_FUNC.W.FUNC.PHP); CustomHeader(); diff --git a/che_close/d_setting/_common.php b/che_close/d_setting/_common.php index 2b789212..57949e8d 100644 --- a/che_close/d_setting/_common.php +++ b/che_close/d_setting/_common.php @@ -2,8 +2,8 @@ if(!defined('ROOT')){ define('ROOT', '../..'); } -require(ROOT.'/f_config/config.php'); -require(ROOT.W.F_CONFIG.W.APP.PHP); -require(ROOT.W.F_FUNC.W.FUNC.PHP); +require_once(ROOT.'/f_config/config.php'); +require_once(ROOT.W.F_CONFIG.W.APP.PHP); +require_once(ROOT.W.F_FUNC.W.FUNC.PHP); CustomHeader(); diff --git a/d_setting/_common.php b/d_setting/_common.php index d9e9ed06..25378505 100644 --- a/d_setting/_common.php +++ b/d_setting/_common.php @@ -2,8 +2,8 @@ if(!defined('ROOT')){ define('ROOT', '..'); } -require(ROOT.'/f_config/config.php'); -require(ROOT.W.F_CONFIG.W.APP.PHP); -require(ROOT.W.F_FUNC.W.FUNC.PHP); +require_once(ROOT.'/f_config/config.php'); +require_once(ROOT.W.F_CONFIG.W.APP.PHP); +require_once(ROOT.W.F_FUNC.W.FUNC.PHP); CustomHeader(); diff --git a/e_lib/plates.php b/e_lib/plates.php index bd1f1534..88f1d1c8 100644 --- a/e_lib/plates.php +++ b/e_lib/plates.php @@ -11,4 +11,6 @@ include(__DIR__.'/plates/Template/Functions.php'); include(__DIR__.'/plates/Template/Name.php'); include(__DIR__.'/plates/Template/Template.php'); +class Plates extends League\Plates\Engine { } + ?> \ No newline at end of file diff --git a/e_lib/utilphp-1.1.0/.coveralls.yml b/e_lib/utilphp-1.1.0/.coveralls.yml deleted file mode 100644 index 6e649991..00000000 --- a/e_lib/utilphp-1.1.0/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -service_name: travis-ci \ No newline at end of file diff --git a/e_lib/utilphp-1.1.0/.gitignore b/e_lib/utilphp-1.1.0/.gitignore deleted file mode 100644 index a28cc36f..00000000 --- a/e_lib/utilphp-1.1.0/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -test.php -build/* -report/* -tests/test* diff --git a/e_lib/utilphp-1.1.0/.travis.yml b/e_lib/utilphp-1.1.0/.travis.yml deleted file mode 100644 index bfce66e7..00000000 --- a/e_lib/utilphp-1.1.0/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: php - -php: - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - hhvm - -matrix: - allow_failures: - - php: hhvm - -before_script: - - pyrus install pear/PHP_CodeSniffer - - wget -nc http://getcomposer.org/composer.phar - - php composer.phar install --dev --no-interaction - - mkdir -p build/logs - - phpenv rehash - -after_script: - - php vendor/bin/coveralls diff --git a/e_lib/utilphp-1.1.0/CHANGELOG.md b/e_lib/utilphp-1.1.0/CHANGELOG.md deleted file mode 100644 index 8cbd899f..00000000 --- a/e_lib/utilphp-1.1.0/CHANGELOG.md +++ /dev/null @@ -1,86 +0,0 @@ -Change Log -========== - -1.1.0 ------ - -This release introduces a deprecation notice for `slugify()`, please update your code. - -* Added a cryptographically secure random string function `secure_random_string`. Thanks to @abhimanyusharma003 via [Pull Request #53](https://github.com/brandonwamboldt/utilphp/pull/53) -* Added `limit_characters` and `limit_words` functions. Thanks to @abhimanyusharma003 via [Pull Request #55](https://github.com/brandonwamboldt/utilphp/pull/55) -* Added `rmdir` method to recursively delete a directory. Thanks to @ARACOOOL via [Pull Request #56](https://github.com/brandonwamboldt/utilphp/pull/56) -* Added `set_executable`, `set_readable`, `set_writable`, `directory_size`, `directory_contents` and `get_user_dir` functions. Thanks to @sergserg via [Pull Request #70](https://github.com/brandonwamboldt/utilphp/pull/70) -* Changed parameter ordering for `slugify`, `$css_mode` is now the third argument. For backwards compatibility, the old order will still work but it will generate an `E_USER_DEPRECATED` warning. Thanks to @abhimanyusharma003 via [Pull Request #71](https://github.com/brandonwamboldt/utilphp/pull/71) -* Added `match_string` method. Thanks to @abhimanyusharma003 via [Pull Request #72](https://github.com/brandonwamboldt/utilphp/pull/72) -* Renamed internal methods (protected ones) for PSR-2 compliance -* General performance improvements, code quality improvements, and increased unit test coverage (special thanks to @hopeseekr for getting us near 100% coverage) - -1.0.7 ------ - -* Added `fix_broken_serialization` to fix broken serialized strings (Thanks to @hopeseekr via [Pull Request #48](https://github.com/brandonwamboldt/utilphp/pull/48)) -* Fixed `get_current_url` appending port 80 or 443 when not needed (Thanks to @scottchiefbaker via [Pull Request #49](https://github.com/brandonwamboldt/utilphp/pull/49)) -* `var_dump` can now handle recursive data structures without crashing -* `var_dump` code was minified and cleaned up -* `array_flatten` was optimized (thanks to @hopeseekr via [Pull Request #47](https://github.com/brandonwamboldt/utilphp/pull/47)) -* `remove_accents` was completely rewritten and is now ~4x faster - -1.0.6 ------ - -* Added `start_with` function -* Added `ends_with` function -* Added `str_contains` function -* Added `str_icontains` function -* Added `get_file_ext` function -* Fixing permissions on the files & directories -* Fixing a bug with the include path of util.php - -1.0.5 ------ - -* [Issue #29](https://github.com/brandonwamboldt/utilphp/issues/29) Fixed error in `var_dump` if mbstring extension wasn't present -* Adding Composer support -* Updating license from GPL to MIT -* Adding Changelog to project -* Bumping minimum version to PHP 5.3.3 - -1.0.4 ------ - -* [Issue #22](https://github.com/brandonwamboldt/utilphp/issues/22) Removed all superglobal *_get functions, you can use the modified array_get now -* [Issue #22](https://github.com/brandonwamboldt/utilphp/issues/22) Modifed the behaviour of `array_get`, see documentation -* [Pull Request #21](https://github.com/brandonwamboldt/utilphp/pull/21) Added multibyte support to html* functions -* [Issue #9](https://github.com/brandonwamboldt/utilphp/issues/9) Removed the `str_to_utf8` function -* [Issue #3](https://github.com/brandonwamboldt/utilphp/issues/3) Removed the `absint` function -* Removed declare() from util.php to avoid errors -* Updated PHPUnit tests to use PHPUnit 3.6 - -1.0.3 ------ - -* [Issue #16](https://github.com/brandonwamboldt/utilphp/issues/16) Improved performance of `slugify` -* [Issue #14](https://github.com/brandonwamboldt/utilphp/issues/14) Modified the regex for `seems_utf8` to be more accurate -* [Issue #13](https://github.com/brandonwamboldt/utilphp/issues/13) Changed `validate_email` to be wrapper for `filter_var` -* Added 'ok' to the list of yes words for `str_to_bool` -* `str_to_bool` matches no followed by any number of 'o's - -1.0.2 ------ - -* [Issue #12](https://github.com/brandonwamboldt/utilphp/issues/12) `get_current_url` now includes the port and user/password if required -* [Issue #11](https://github.com/brandonwamboldt/utilphp/issues/11) `human_time_diff` now uses the DateTime functions -* [Issue #10](https://github.com/brandonwamboldt/utilphp/issues/10) `is_https` no longer checks the port as well - -1.0.1 ------ - -* [Issue #7](https://github.com/brandonwamboldt/utilphp/issues/7) Added the `$trust_proxy_headers` parameter to `get_client_ip` -* [Issue #6](https://github.com/brandonwamboldt/utilphp/issues/6) Removed `is_isset` as the function did not work as intended -* [Issue #6](https://github.com/brandonwamboldt/utilphp/issues/6) Removed `is_empty` as it is redundant, use ! with function calls instead -* Fixed a bug with `get_gravatar` - -1.0.0 ------ - -* Initial release of util.php. diff --git a/e_lib/utilphp-1.1.0/CONTRIBUTORS.md b/e_lib/utilphp-1.1.0/CONTRIBUTORS.md deleted file mode 100644 index 7fadf04f..00000000 --- a/e_lib/utilphp-1.1.0/CONTRIBUTORS.md +++ /dev/null @@ -1,48 +0,0 @@ -# CONTRIBUTORS - -Util.php is the combined effort of many people who contributed new functions and features, bug fixes, tests, and documentation. - -# Maintainer / Lead - -* Brandon Wamboldt (http://brandonwamboldt.ca) - -## Third-Party Projects - -The following projects were fully or partially incorporated into util.php (and properly attributed). - -* IntToWords (https://github.com/hemant347/IntToWords) -* LinkifyURL (https://github.com/jmrware/LinkifyURL) -* URLify.php (https://github.com/jbroadway/urlify/) -* Pure PHP http_build_url (https://github.com/jakeasmith/http_build_url) - -## Methods - -The following developers and/or companies helped contribute to building util.php. - -* PHP Experts, Inc. (http://www.phpexperts.pro/) - - `array_flatten()` - - `fix_broken_serialization()` - - Lots of unit tests. -* Tony Ferrara (ircmaxwell, http://blog.ircmaxell.com/) - - `seemsUtf8Regex()`: http://stackoverflow.com/a/11709412/430062 -* Askar ([@ARACOOOL](https://github.com/ARACOOOL)) - - `rmdir()` - - `limit_characters()` - - `limit_words()` -* Anonymous (tmp1000@fastmail.fm) - - `htmlspecialentities()`: http://php.timesoft.cc/manual/en/function.htmlentities.php - - `htmlspecialchars()` -* Laravel Project (https://github.com/laravel/laravel) - - `secure_random_string()`: http://trac.allenjb.me.uk/php/browser/tagi/vendor/laravel/framework/src/Illuminate/Support/Str.php?rev=87#L127 -* Abhimanyu Sharma ([@abhimanyusharma003](https://github.com/abhimanyusharma003)) - - `limit_characters()` - - `limit_words()` - - `match_string()` -* Scott Baker ([@scottchiefbaker](https://github.com/scottchiefbaker)) -* [@sergserg](https://github.com/sergserg) - - `set_writable()` - - `set_executable()` - - `set_readable()` - - `directory_size()` - - `directory_contents()` - - `get_user_dir()` diff --git a/e_lib/utilphp-1.1.0/LICENSE.md b/e_lib/utilphp-1.1.0/LICENSE.md deleted file mode 100644 index 7c3f2915..00000000 --- a/e_lib/utilphp-1.1.0/LICENSE.md +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License (MIT) -===================== - -The MIT License (MIT) - -Copyright (c) 2013 Brandon Wamboldt - -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. \ No newline at end of file diff --git a/e_lib/utilphp-1.1.0/README.md b/e_lib/utilphp-1.1.0/README.md deleted file mode 100644 index 3b271796..00000000 --- a/e_lib/utilphp-1.1.0/README.md +++ /dev/null @@ -1,123 +0,0 @@ -# Util.php [![Build Status](https://img.shields.io/travis/brandonwamboldt/utilphp.svg)](https://travis-ci.org/brandonwamboldt/utilphp) [![Coverage Status](https://img.shields.io/coveralls/brandonwamboldt/utilphp/master.svg)](https://coveralls.io/r/brandonwamboldt/utilphp) - -[UtilPHP](http://brandonwamboldt.github.com/utilphp/) (Aka util.php) is a -collection of useful functions and snippets that you need or could use every -day. It's implemented as a class with static methods, to avoid conflicts with -your existing code-base. Just drop it in and start using it immediately. - -Included are 55+ functions that provide you with the ability to do common -tasks much easier and more efficiently, without having to find that one comment -on php.net where you know it's been done already. Access superglobals without -checking to see if certain indexes are set first and pass default values, use a -nicely formatted var dump, validate emails, generate random strings, flatten an -array, pull a single column out of a multidimensional array and much more. - -Although it's implemented as one giant class, util.php has extensive -documentation and a full suite of unit tests to avoid breaking -backwards-compatibility unintentionally. - -## Release Information - -This repo contains in development code for future releases as well as the -current stable branch. Development code is contained in the develop branch. - -## Changelog and New Features - -You can find a list of all changes for each release in the -[official documentation](http://brandonwamboldt.github.com/utilphp/#changelog) - -## Installation - -### Server Requirements - -* PHP version 5.3.3 or higher. - -### Standalone File - -Simply drop `util.php` in any project and call `include 'util.php';` in your -project. You can then access the `Util` class. - -### Composer - -Add the following dependency to your composer.json: - -``` -"brandonwamboldt/utilphp": "1.0.*" -``` - -When used with composer, the class is namespaced (`\utilphp\util`) instead of -just `util`. - -## Contributing - -UtilPHP is a community driven project and accepts contributions of code and -documentation from the community. These contributions are made in the form of -Issues or [Pull Requests](http://help.github.com/send-pull-requests/) on the -[UtilityPHP repository](https://github.com/brandonwamboldt/utilphp) on GitHub. - -Issues are a quick way to point out a bug. If you find a bug or documentation -error in UtilityPHP then please check a few things first: - -* There is not already an open Issue -* The issue has already been fixed (check the develop branch, or look for closed Issues) -* Is it something really obvious that you fix it yourself? - -Reporting issues is helpful but an even better approach is to send a Pull -Request, which is done by "Forking" the main repository and committing to your -own copy. This will require you to use the version control system called Git. - -## Guidelines - -Before we look into how, here are the guidelines. If your Pull Requests fail to -pass these guidelines it will be declined and you will need to re-submit when -you’ve made the changes. This might sound a bit tough, but it is required for -me to maintain quality of the code-base. - -### PHP Style - -Please ensure all new contributions match the [PSR-2](http://www.php-fig.org/psr/psr-2/) -coding style guide. - -### Documentation - -If you change anything that requires a change to documentation then you will -need to add it. New methods, parameters, changing default values, adding -constants, etc are all things that will require a change to documentation. The -change-log must also be updated for every change. Also PHPDoc blocks must be -maintained. - -### PHP Version Compatibility - -UtilityPHP is compatible with PHP 5.3.3 so all code supplied must stick to this -requirement. - -Of particular note is avoiding short array notation like this: - -``` -$var = []; -``` - -Please use the old notation instead: - -``` -$var = array(); -``` - -I know it's uglier, but PHP 5.3 while EOL'd, still isn't that old. - -### Branching - -One thing at a time: A pull request should only contain one change. That does -not mean only one commit, but one change - however many commits it took. The -reason for this is that if you change X and Y but send a pull request for both -at the same time, we might really want X but disagree with Y, meaning we cannot -merge the request. Using the Git-Flow branching model you can create new -branches for both of these features and send two requests. - -## License - -UtilPHP is licensed under the MIT license. - -## Resources - -* [Documentation](http://brandonwamboldt.github.com/utilphp/) diff --git a/e_lib/utilphp-1.1.0/composer.json b/e_lib/utilphp-1.1.0/composer.json deleted file mode 100644 index 9bf3520e..00000000 --- a/e_lib/utilphp-1.1.0/composer.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "brandonwamboldt/utilphp", - "type": "library", - "version": "1.1.0", - "description": "util.php is a collection of useful functions and snippets that you need or could use every day, designed to avoid conflicts with existing projects", - "keywords": ["php", "utility", "collection", "helpers"], - "homepage": "https://github.com/brandonwamboldt/utilphp", - "license": "MIT", - "authors": [ - { - "name": "Brandon Wamboldt", - "email": "brandon.wamboldt@gmail.com" - } - ], - "autoload": { - "psr-0": { "utilphp\\": "src/" } - }, - "require-dev": { - "satooshi/php-coveralls": "dev-master" - }, - "require": { - "php": ">=5.3.3" - } -} diff --git a/e_lib/utilphp-1.1.0/docs/css/docs.css b/e_lib/utilphp-1.1.0/docs/css/docs.css deleted file mode 100644 index 77993435..00000000 --- a/e_lib/utilphp-1.1.0/docs/css/docs.css +++ /dev/null @@ -1,168 +0,0 @@ -body { - background: #f4f4f4 url('../images/background.png'); - color: #333; - font: 18px/30px "Droid Serif", "Helvetica Neue", Helvetica, Arial; -} - -a { - text-decoration: none; - color: #f00; - padding: 2px; -} - -a:hover { - background: #277585; - color: #fff; - border-radius: 3px; -} - -h1, h2, h3, h4, h5, h6 { - padding-top: 20px; -} - -h2 { - font-size: 40px; - font-weight: normal; - margin: 0 0 15px; -} - -p { - margin: 20px 0; - min-width: 550px; - max-width: 900px; -} - -table, tr, td { - margin: 0; padding: 0; -} - -td { - padding: 2px 12px 2px 0; -} - -ul { - list-style-type: circle; - padding: 0 0 0 20px; -} - -li { - width: 500px; - margin-bottom: 10px; -} - -code, pre, tt { - font-family: Monaco, Consolas, "Lucida Console", monospace; - font-size: 12px; - line-height: 18px; - font-style: normal; -} - -tt { - padding: 0px 3px; - background: #fff; - border: 1px solid #ddd; - zoom: 1; -} - -code { - margin-left: 20px; -} - -pre { - font-size: 12px; - padding: 12px; - background: #fff; - margin: 0px 0 30px; - border-radius: 0 0 2px 2px; - box-shadow: inset 0 0 0 1px rgba(0,0,0,.15); -} - -span.header { - font-size: 24px; - line-height: 30px; - border-left: 10px solid #ddd; - padding-left: 10px; -} - -.desc-text code { - margin-left: 0; - font-size: 18px; - color: #0E04C8; -} - -#sidebar { - background: #fff; - position: fixed; - top: 0; left: 0; bottom: 0; - width: 220px; - overflow-y: auto; - overflow-x: hidden; - padding: 5px 0 30px 10px; - border-right: 1px solid #bbb; - - box-shadow: 0 0 20px #ccc; - -webkit-box-shadow: 0 0 20px #ccc; - -moz-box-shadow: 0 0 20px #ccc; - -webkit-overflow-scrolling: touch; -} - -.toc_title, .toc_title:visited { - display: block; - color: #000; - margin-top: 15px; -} - -.toc_title:hover { - background: none; - color: #f00; -} - -.toc_title .version { - font-size: 12px; - font-weight: normal; -} - -.toc_section { - font-size: 14px; - line-height: 24px; - margin: 5px 0 0 0; - padding-left: 10px; - list-style-type: none; -} - -.toc_section li { - cursor: pointer; - margin: 0 0 3px 0; -} - -.toc_section li a { - text-decoration: none; - color: black; -} - -.toc_section li a:hover { - background: none; - color: #f00; -} - -.container { - min-width: 550px; - max-width: 1000px; - margin: 40px 0 50px 260px; -} - -#documentation section > article > p > code { - color: #999; -} - -#documentation section > article > p > code > .util_class { - color: #bbb; -} - -#documentation section > article > p > code > .func_name { - color: #0E04C8; -} - -#documentation section > article > p > code > .param { - color: #DA72F3; -} diff --git a/e_lib/utilphp-1.1.0/docs/favicon.png b/e_lib/utilphp-1.1.0/docs/favicon.png deleted file mode 100644 index 5f17cf1dbd24f03f46089ef35b6078c8a09aeee8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 803 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 z�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 diff --git a/e_lib/utilphp-1.1.0/docs/images/background.png b/e_lib/utilphp-1.1.0/docs/images/background.png deleted file mode 100644 index 1e6fddd7dfd3e43f9a6ff7fa5c4aa3eb2ca6275d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1028 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 at&X`!7td+Kk+sfrr)3JUFsd_jPy81`G - - - - - - - - - - - - - - - util.php - The PHP programmers best friend - UtilityPHP - - - -

- -
-

- -

- -

- util.php is a collection of useful functions and snippets - that you need or could use every day. It's implemented as a class with static methods, to avoid conflicts with your - existing code-base. Just drop it in and start using it immediately. -

- -

- Included are 60+ functions that provide you with the ability to do common tasks much easier and more efficiently, - without having to find that one comment on php.net where you know its been done already. Access superglobals - without checking to see if certain indexes are set first and pass default values, use a nicely formatted var dump, - validate emails, generate random strings, flatten an array, pull a single column out of a multidimensional array - and much more. -

- -

- Although it's implemented as one giant class, util.php has extensive documentation and a full suite of unit tests - to avoid breaking backwards-compatibility unintentionally. -

- -

- The project is hosted on GitHub. - You can report bugs and discuss features on the - issues page, - or send tweets to @brandonwamboldt. -

- -

Downloads (Right-click, and use "Save As")

- -

- Stable Version (1.1.0)
- Unstable Version (master) -

- -

Installation

- - Server Requirements
- -
    -
  • PHP 5.3.3+
  • -
- - Standalone File
- -

- Simply drop util.php in any project and call include 'util.php'; in your project. - You can then access the Util class. -

- - Composer
- -

- Add the following dependency to your composer.json: - -

"brandonwamboldt/utilphp": "1.1.*"
- - When used with composer, the class is namespaced (\utilphp\util) instead of - just util. -

- -
-

Debugging Functions

- -
-
-

- var_dump - - util::var_dump(mixed $var[, bool $return = FALSE]) - -

- -

- Nicely prints out the contents of a passed variable. Booleans are properly displayed as 'true' or 'false', - null values are shown as 'NULL', variable types are displayed, and arrays and objects are displayed as a - collapsible tree powered by JavaScript. -

- -

Usage:

- -
util::var_dump($var);
- - -
-
- -

Array/Object Functions

- -
-
-

- array_first - - util::array_first(array $array) - -

- -

- Retrieve the first value from an array. Can be run on function callbacks, and it will not modify the pointer - of the source array unlike most other methods of doing this. -

- -

Usage:

- -
util::array_first( ['a', 'b', 'c'] );
=> Returns 'a'
-
- -
-

- array_first_key - - util::array_first_key(array $array) - -

- -

- Retrieve the first key from an array. Can be run on function callbacks, and it will not modify the pointer of - the source array unlike most other methods of doing this. -

- -

Usage:

- -
util::array_first_key( $users );
=> Returns 'brandon'
-
- -
-

- array_flatten - - util::array_flatten(array $array[, bool $preserve_keys = TRUE]) - -

- -

Flattens a multi-dimensional array into a one dimensional array

- -

Usage:

- -
util::array_flatten( [ 'a', 'b', [ 'c', 'd', 'e', [ 'f', 'g', [ [ [ [ 'h', 'i', 'j' ] ] ] ] ] ] ] );
-=> Returns [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ]
-
- -
-

- array_get - - util::array_get($var[, mixed $default = NULL]) - -

- -

Retrieve a value from an array, or return a given default if the index isn't set

- -

Usage:

- -
util::array_get($_POST['action'], 'index');
-=> If $_POST['action'] is set, returns its value, otherwise returns 'index'
-util::array_get($_POST['action']['do'], 'index');
-=> Returns the value of $_POST['action']['do'] or 'index'
-
- -
-

- array_last - - util::array_last(array $array) - -

- -

- Retrieve the last value from an array. Can be run on function callbacks, and it will not modify the pointer - of the source array unlike most other methods of doing this. -

- -

Usage:

- -
util::array_last( [ 'a', 'b', 'c'] );
-=> Returns 'c'
-
- -
-

- array_last_key - - util::array_last_key(array $array) - -

- -

- Retrieve the last key from an array. Can be run on function callbacks, and it will not modify the pointer of - the source array unlike most other methods of doing this. -

- -

Usage:

- -
util::array_last_key( $users );
-=> Returns 'zane'
-
- -
-

- array_map_deep - - util::array_map_deep(array $array, callable $callback[, bool $on_nonscalar = FALSE]) - -

- -

- Returns an array containing all the elements of $array after applying the callback function to each one recursively. - Particularly useful for avoiding errors when calling functions that only accept scalar values on an array that could - contain nested arrays, such as $_GET or $_POST. -

- -

Usage:

- -
util::array_map_deep($_POST, 'htmlentities');
-=> Recursively escapes each scalar value in $_POST
-util::array_map_deep($_POST, 'htmlentities', TRUE);
-=> Recursively escapes each value in $_POST regardless of its type
-
- -
-

- array_pluck - - util::array_pluck(array $array, string $field[, bool $preserve_keys, bool $remove_nomatches]) - -

- -

- Replaces each value in an array with the specified field of the array or object that used to be the value. Very - useful when you have an array of objects or arrays from a database, and you only want one specific field. For - example, you want an array of emails from an array of users. -

- -

Usage:

- -
util::array_pluck([['val' => 1], ['val' => 2], ['val' => 3]], 'val');
-=> Returns [1, 2, 3]
-util::array_pluck($users, 'email');
-=> Returns an array of email addresses for each user
-
- -
-

- array_search_deep - - util::array_search_deep(array $array, mixed $search[, string $field = FALSE]) - -

- -

- Allows you to search for a value in an array of arrays or an array of objects, and return the key of the value - that matches the search criteria. If $field is unspecified, the entire array/object is searched. -

- -

Usage:

- -
util::array_search_deep($_POST, 'delete_post');
-=> Might return 'do' if $_POST['do']['action'] = 'delete_post'
-util::array_search_deep($users, 'rogue_coder', 'username');
-=> Might return 5 if $users[5]->username = 'rogue_coder'
-
- -
-

- array_clean - - util::array_clean(array $array) - -

- -

- Remove all null/empty/false values from the given array. -

- -

Usage:

- -
util::array_clean( array( 'a', 'b', '', null, false, 0) );
=> Returns array('a', 'b');
-
- -
- -

URL Functions

- -
-
-

- add_query_arg - - util::add_query_arg() - -

- -

Adds one ore more query args to the query string of the current URL or a given URL

- -

Usage:

- -
util::add_query_arg( 'user', '5', '/admin/users?action=edit' );
-=> Returns '/admin/users?action=edit&user=5'
-util::add_query_arg( [ 'user' => 5, 'action' => 'edit' ], '/admin/users' );
-=> Returns '/admin/users?user=5&action=edit'
-
- -
-

- get_current_url - - util::get_current_url() - -

- -

Returns the current URL with hostname

- -

Usage:

- -
util::get_current_url();
-=> Returns 'http://brandonwamboldt.ca/utilphp/'
-
- -
-

- is_https - - util::is_https() - -

- -

Returns true if the current page is being loaded over https, false if it isn't

- -

Usage:

- -
util::is_https();
-=> Returns false
-
- -
-

- http_build_url - - util::http_build_url([mixed $url[, mixed $parts[, int $flags = HTTP_URL_REPLACE[, array &amo;$new_url]]]]) - -

- -

- Pure PHP implementation/polyfill for http_build_url - which requires pecl_http to be installed. -

- -

Usage:

- -
echo util::http_build_url("http://user@www.example.com/pub/index.php?a=b#files",
-    array(
-        "scheme" => "ftp",
-        "host" => "ftp.example.com",
-        "path" => "files/current/",
-        "query" => "a=c"
-    ),
-    HTTP_URL_STRIP_AUTH | HTTP_URL_JOIN_PATH | HTTP_URL_JOIN_QUERY | HTTP_URL_STRIP_FRAGMENT
-);
- -

The above example will output:

- -
ftp://ftp.example.com/pub/files/current/?a=c
-
- -
-

- is_https - - util::is_https() - -

- -

Returns true if the current page is being loaded over https, false if it isn't

- -

Usage:

- -
util::is_https();
-=> Returns false
-
- -
-

- remove_query_arg - - util::remove_query_arg( array|string $query_args[, string $url]) - -

- -

Removes one ore more query args from the query string of the current URL or a given URL

- -

Usage:

- -
util::remove_query_arg( 'action', '/admin/users?action=edit&user=5' );
-=> Returns '/admin/users?user=5'
-util::remove_query_arg( [ 'user', 'action'], '/admin/users?action=edit&user=5' );
-=> Returns '/admin/users'
-
- -
-

- slugify - - util::slugify(string $string[, string $separator = "-", bool $css_mode = FALSE]) - -

- -

- Generate a string safe for use in URLs from any given string. Converts any accent characters - to their equivalent normal characters and converts any other non-alphanumeric characters to - dashes, then converts any sequence of two or more dashes to a single dash. This function - generates slugs safe for use as URLs, and if you pass TRUE as the second parameter, it will - create strings safe for use as CSS classes or IDs. -

- -

Usage:

- -
util::slugify('This is a random --string with an Ãccent');
-=> Returns 'this-is-a-random-string-with-an-accent'
-util::slugify('Another String', '.');
-=> Returns 'another.string'
-
-
- -

String Functions

- -
-
-

- htmlentities - - util::htmlentities(string $string[, bool $preserve_encoded_entities = FALSE]) - -

- -

- Executes htmlentities with ENT_QUOTES set by default. However, if you pass TRUE as - the second parameter, it will not re-encode entities that are already encoded. -

- -

Usage:

- -
util::htmlentities('this string < this string', TRUE);
-=> Returns 'this string < this string'
-
- -
-

- htmlspecialchars - - util::htmlspecialchars(string $string[, bool $preserve_encoded_entities = FALSE]) - -

- -

- Executes htmlspecialchars with ENT_QUOTES set by default. However, if you pass TRUE as - the second parameter, it will not re-encode entities that are already encoded. -

- -

Usage:

- -
util::htmlspecialchars('this string < this string', TRUE);
-=> Returns 'this string < this string'
-
- -
-

- linkify - - util::linkify(string $text) - -

- -

Find's any URLs in the specified text and wraps them with HTML anchor tags

- -

Usage:

- -
util::linkify('this string has a link to www.google.com');
-=> Returns 'this string has a link to <a href="http://wwww.google.com/">www.google.com</a>'
-
- -
-

- match_string - - util::match_string(string $pattern, string $string[, bool $caseSensitive = true]) - -

- -

- Check if a string matches a given pattern. You can use '*' as a wildcard character. -

- -

Usage:

- -
util::match_string("test/*", "test/my/test");
-=> Returns true
-util::match_string("test/", "test/my/test");
-=> Returns false
-
- -
-

- random_string - - util::random_string(int $length[, bool $human_friendly = TRUE, bool $include_symbols = FALSE, bool $no_duplicate_chars = FALSE]) - -

- -

- Generates a random string of the specified length. Human friendly mode - will exclude characters that can be confused with other characters, such - as 0 (zero) and O (capital o), 1 (one) and l (lowercase L). -

- -

Usage:

- -
util::random_string(8);
-=> Returns 'a6BiF4UW'
-
- -
-

- number_to_word - - util::number_to_word(int|float $number) - -

- -

Converts a number into its text equivalent. For example, 56 becomes fifty-six.

- -
util::number_to_word(512.5);
-=> Returns 'five hundred and twelve point five'
-
- -
-

- ordinal - - util::ordinal(int $number) - -

- -

Returns the ordinal version of a number (appends th, st, nd, rd)

- -

Usage:

- -
util::ordinal(22);
-=> Returns '22nd'
-
- -
-

- remove_accents - - util::remove_accents(string $string) - -

- -

Converts all accent characters to their ASCII equivalents

- -

Usage:

- -
util::remove_accents('Àccent');
-=> Returns 'Accent'
-
- -
-

- secure_random_string - - util::secure_random_string(int $length) - -

- -

Generate a random string of characters. Will attempt to use a secure source (openssl).

- -

Usage:

- -
util::secure_random_string(16);
-=> Returns '5bB1RJH0cQhNjviT'
-
- -
-

- seems_utf8 - - util::seems_utf8(string $string) - -

- -

Checks to see if a given string is UTF-8 encoded/safe

- -

Usage:

- -
util::seems_utf8('This is some random string user input');
-=> Returns true
-
- -
-

- safe_truncate - - util::safe_truncate(string $string, int $length[, string $append = '...']) - -

- -

Truncate a string to a specified length without cutting a word off

- -

Usage:

- -
util::safe_truncate('The quick brown fox jumps over the lazy dog', 24);
-=> Returns 'The quick brown fox...'
-
- -
-

- size_format - - util::size_format(int $bytes[, int $decimals = 0]) - -

- -

Formats an integer as a human friendly size string, such as 4 KiB.

- -

Usage:

- -
util::size_format( 25151251, 2 );
-=> Returns '23.99 MiB'
-
- -
-

- str_to_bool - - util::str_to_bool(string $string) - -

- -

Converts a string to boolean, looking for yes/no words like 'yes', 'no', 'true', 'false', 'y', 'n', etc

- -

Usage:

- -
util::str_to_bool('yes');
-=> Returns true
-
- -
-

- zero_pad - - util::zero_pad(int $number, int $length) - -

- -

Pads a given number with zeroes on the left

- -

Usage:

- -
util::zero_pad(341, 8);
-=> Returns '00000341'
-
- -
-

- strip_space - - util::strip_space(string $string) - -

- -

Strip all withspace from the given string

- -

Usage:

- -
util::strip_space(' The quick brown fox jumps over the lazy dog ');
-=> Returns 'Thequickbrownfoxjumpsoverthelazydog'
-
- -
-

- sanitize_string - - util::sanitize_string(string $string) - -

- -

- Sanitize a string by performing the following operation : -

    -
  • Remove accents
  • -
  • Lower the string
  • -
  • Remove punctuation characters
  • -
  • Strip whitespaces
  • -
- -

-

Usage:

- -
util::sanitize_string(' Benoit! à New-York? j’ai perçu 1 % : Qu’as-tu "gagné" chez M. V. Noël? Dix francs.');
-=> Returns 'benoitanewyorkjaipercu1quastugagnechezmvnoeldixfrancs'
-
-
- -

Files

- -
-
-

- full_permissions - - util::full_permissions(string $file) - -

- -

Returns the file permissions as a nice string, like -rw-r--r--

- -

Usage:

- -
util::full_permissions('/etc/passwd');
-=> Returns '-rw-r--r--'
-
- -
-

- rmdir - - util::rmdir(string $dir[, bool $traverseSymlinks = false]) - -

- -

Recursively deletes a directories (including all contents).

- -

Usage:

- -
util::rmdir('/tmp/working/dir');
-=> Returns true
-
-
- -

Serialization

- -
-
-

- is_serialized - - util::is_serialized(mixed $data) - -

- -

Checks to see if a given variable is a seralized data structure

- -

Usage:

- -
util::is_serialized( 'a:0:{}' );
-=> Returns true
-
- -
-

- maybe_serialize - - util::maybe_serialize(mixed $data) - -

- -

Serialize data, if needed to store in plaintext (Arrays or objects)

- -

Usage:

- -
util::maybe_serialize( 5 );
-=> Returns 5
-util::maybe_serialize( array() );
-=> Returns 'a:0:{}'
-
- -
-

- maybe_unserialize - - util::maybe_unserialize(mixed $data) - -

- -

Unserialize data, if it's a serialized string

- -

Usage:

- -
util::maybe_unserialize(5);
-=> Returns 5
-util::maybe_unserialize("a:0:{}");
-=> Returns array()
-
- -
-

- fix_broken_serialization - - util::fix_broken_serialization(mixed $data) - -

- -

- Attempt to fix a broken serialization string (e.g. where string offsets are incorrect). Can fix - errors that frequently occur with mismatched character sets or higher-than-ASCII characters. -

- -

Usage:

- -
util::fix_broken_serialization('a:1:{s:4:"test";s:4:"abc";}');
-=> Returns 'a:1:{s:4:"test";s:3:"abc";}'
-
-
- -

Other

- -
-
-

- force_download - - util::force_download(string $filename, string $content = FALSE) - -

- -

- Transmit headers that force a browser to display the download file dialog. Cross - browser compatible. Only fires if headers have not already been sent. -

- -

Usage:

- -
util::force_download( 'export.csv', file_get_contents( 'securefile.csv' ) );
-=> The user will be prompted to download the file
-
- -
-

- get_client_ip - - util::get_client_ip(bool $trust_proxy_headers = FALSE) - -

- -

- Returns the IP address of the client. Only enable $trust_proxy_headers if your server is behind a proxy - that sets the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR headers. -

- -

Usage:

- -
util::get_client_ip();
-=> Returns '12.123.12.100'
-
- -
-

- get_gravatar - - util::get_gravatar(string $email, int $size = 32) - -

- -

Return the URL to a user's gravatar

- -

Usage:

- -
util::get_gravatar('brandon.wamboldt@gmail.com');
-=> Returns 'http://www.gravatar.com/avatar/46679faeb6780ecb1ea57527fdc66eb3?s=32'
-
- -
-

- human_time_diff - - util::human_time_diff(int $from, int $to = '', int $as_text = FALSE, string $suffix = ' ago') - -

- -

Converts a unix timestamp to a relative time string, such as "3 days ago" or "2 weeks ago"

- -

Usage:

- -
util::human_time_diff(time() - 7400);
-=> Returns '2 hours ago'
-util::human_time_diff(time() - 7400, '', TRUE);
-=> Returns 'two hours ago'
-
- -
-

- nocache_headers - - util::nocache_headers(mixed $data) - -

- -

Sets the headers to prevent caching for the different browsers

- -

- Different browsers support different nocache headers, so several headers must be sent - so that all of them get the point that no caching should occur -

- -

Usage:

- -
util::nocache_headers();
-
- -
-

- utf8_headers - - util::utf8_headers(mixed $content_type = 'text/html') - -

- -

Transmit UTF-8 content headers if the headers haven't already been sent

- -

Usage:

- -
util::utf8_headers();
-
- -
-

- validate_email - - util::validate_email(string $possible_email) - -

- -

Validate an email address

- -

Usage:

- -
util::validate_email( 'brandon.wamboldt@gmail.com' );
-=> Returns true
-util::validate_email( 'not an email' );
-=> Returns false
-
-
- -

Constants

- -
-
-

- SECONDS_IN_A_MINUTE - - util::SECONDS_IN_A_MINUTE - -

- -

The number of seconds in a minute, useful for making code more verbose

-
- -
-

- SECONDS_IN_AN_HOUR - - util::SECONDS_IN_AN_HOUR - -

- -

The number of seconds in an hour, useful for making code more verbose

-
- -
-

- SECONDS_IN_A_DAY - - util::SECONDS_IN_A_DAY - -

- -

The number of seconds in a day, useful for making code more verbose

-
- -
-

- SECONDS_IN_A_WEEK - - util::SECONDS_IN_A_WEEK - -

- -

The number of seconds in a week (7 days), useful for making code more verbose

-
- -
-

- SECONDS_IN_A_MONTH - - util::SECONDS_IN_A_MONTH - -

- -

The number of seconds in a month (30 days), useful for making code more verbose

-
- -
-

- SECONDS_IN_A_YEAR - - util::SECONDS_IN_A_YEAR - -

- -

The number of seconds in a year (365 days), useful for making code more verbose

-
-
- -

Change Log

- - - -

- 1.1.0
- - This release introduces a deprecation notice for slugify(), please update your code.

- - - Added a cryptographically secure random string function secure_random_string. Thanks to @abhimanyusharma003 via Pull Request #53
- - Added limit_characters and limit_words functions. Thanks to @abhimanyusharma003 via Pull Request #55
- - Added rmdir method to recursively delete a directory. Thanks to @ARACOOOL via Pull Request #56
- - Added set_executable, set_readable, set_writable, directory_size, directory_contents and get_user_dir functions. Thanks to @sergserg via Pull Request #70
- - Changed parameter ordering for slugify, $css_mode is now the third argument. For backwards compatibility, the old order will still work but it will generate an E_USER_DEPRECATED warning. Thanks to @abhimanyusharma003 via Pull Request #71
- - Added match_string method. Thanks to @abhimanyusharma003 via Pull Request #72
- - Renamed internal methods (protected ones) for PSR-2 compliance
- - General performance improvements, code quality improvements, and increased unit test coverage (special thanks to @hopeseekr for getting us near 100% coverage)
-

- -

- 1.0.7
- - Added fix_broken_serialization to fix broken serialized strings (Thanks to @hopeseekr via Pull Request #48)
- - Fixed get_current_url appending port 80 or 443 when not needed (Thanks to @scottchiefbaker via Pull Request #49)
- - var_dump can now handle recursive data structures without crashing
- - var_dump code was minified and cleaned up
- - array_flatten was optimized (thanks to @hopeseekr via Pull Request #47)
- - remove_accents was completely rewritten and is now ~4x faster
-

- -

- 1.0.6
- - Added start_with function
- - Added ends_with function
- - Added str_contains function
- - Added str_icontains function
- - Added get_file_ext function
- - Fixing permissions on the files & directories
- - Fixing a bug with the include path of util.php
-

- -

- 1.0.5
- - Issue #29 Fixed error in var_dump if mbstring extension wasn't present
- - Adding Composer support
- - Updating license from GPL to MIT
- - Adding Changelog to project
- - Bumping minimum version to PHP 5.3.3
-

- -

- 1.0.4
- - Issue #22 Removed all superglobal *_get functions, you can use the modified array_get now
- - Issue #22 Modifed the behaviour of array_get, see documentation
- - Pull Request #21 Added multibyte support to html* functions
- - Issue #9 Removed the str_to_utf8 function
- - Issue #3 Removed the absint function
- - Removed declare() from util.php to avoid errors
- - Updated PHPUnit tests to use PHPUnit 3.6 -

- -

- 1.0.3
- - Issue #16 Improved performance of slugify
- - Issue #14 Modified the regex for seems_utf8 to be more accurate
- - Issue #13 Changed validate_email to be wrapper for filter_var
- - Added 'ok' to the list of yes words for str_to_bool
- - str_to_bool matches no followed by any number of 'o's -

- -

- 1.0.2
- - Issue #12 get_current_url now includes the port and user/password if required
- - Issue #11 human_time_diff now uses the DateTime functions
- - Issue #10 is_https no longer checks the port as well -

- -

- 1.0.1
- - Issue #7 Added the $trust_proxy_headers parameter to get_client_ip
- - Issue #6 Removed is_isset as the function did not work as intended
- - Issue #6 Removed is_empty as it is redundant, use ! with function calls instead
- - Fixed a bug with get_gravatar -

- -

- 1.0.0
- Initial release of util.php. -

-
-
- - - diff --git a/e_lib/utilphp-1.1.0/phpunit.xml.dist b/e_lib/utilphp-1.1.0/phpunit.xml.dist deleted file mode 100644 index d4b9366c..00000000 --- a/e_lib/utilphp-1.1.0/phpunit.xml.dist +++ /dev/null @@ -1,25 +0,0 @@ - - - - - ./tests - - - - - ./src - - - - - - \ No newline at end of file diff --git a/e_lib/utilphp-1.1.0/tests/README.md b/e_lib/utilphp-1.1.0/tests/README.md deleted file mode 100644 index e81d26c3..00000000 --- a/e_lib/utilphp-1.1.0/tests/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# UtilityPHP Unit Tests # - -### Introduction - -This is the testing documentation for util.php. The unit tests require PHPUnit, -and can be run in your web browser. - -### Requirements - -PHP Unit >= 3.5.6 - -#### Installation of PHPUnit - - # Download the PHPUnit phar. - wget https://phar.phpunit.de/phpunit.phar - - # You can just run it locally. (Preferred for Windows) - php phpunit.phar --version - - # Or install it system-wide. - mv phpunit.phar phpunit - chmod +x phpunit - sudo mv phpunit /usr/local/bin - phpunit --version - -## Test Suites: - -util.php includes a phpunit config file, so just run `phpunit` from the working -directory to run the test suite. - -``` -phpunit -``` - -If you want code coverage reports, use the following: - -``` -phpunit --coverage-html ./report -``` diff --git a/e_lib/utilphp-1.1.0/tests/UtilTest.php b/e_lib/utilphp-1.1.0/tests/UtilTest.php deleted file mode 100644 index 404cf7bd..00000000 --- a/e_lib/utilphp-1.1.0/tests/UtilTest.php +++ /dev/null @@ -1,1183 +0,0 @@ -data = (object)array('a', 'b', 'c'); - } -} - -/** - * PHPUnit test case for the util.php library - * - * @author Brandon Wamboldt - * @since 1.0.000 - */ -class UtilityPHPTest extends PHPUnit_Framework_TestCase -{ - /** - * Allows for the testing of private and protected methods. - * - * @param $name - * @return \ReflectionMethod - */ - protected static function getMethod($name) - { - $class = new \ReflectionClass('util'); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method; - } - - public function test_array_get() - { - $_GET = array(); - $_GET['abc'] = 'def'; - $_GET['nested'] = array( 'key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3' ); - - // Looks for $array['abc'] - $this->assertEquals( 'def', util::array_get( $_GET['abc'] ) ); - - // Looks for $array['nested']['key2'] - $this->assertEquals( 'val2', util::array_get( $_GET['nested']['key2'] ) ); - - // Looks for $array['doesnotexist'] - $this->assertEquals( 'defaultval', util::array_get( $_GET['doesnotexist'], 'defaultval' ) ); - } - - public function test_slugify() - { - $this->assertEquals( 'a-simple-title', util::slugify( 'A simple title' ) ); - $this->assertEquals( 'this-post-it-has-a-dash', util::slugify( 'This post -- it has a dash' ) ); - $this->assertEquals( '123-1251251', util::slugify( '123----1251251' ) ); - $this->assertEquals( 'one23-1251251', util::slugify( '123----1251251', '-', true ) ); - - $this->assertEquals( 'a-simple-title', util::slugify( 'A simple title', '-' ) ); - $this->assertEquals( 'this-post-it-has-a-dash', util::slugify( 'This post -- it has a dash', '-' ) ); - $this->assertEquals( '123-1251251', util::slugify( '123----1251251', '-' ) ); - $this->assertEquals( 'one23-1251251', util::slugify( '123----1251251', '-', true ) ); - - $this->assertEquals( 'a_simple_title', util::slugify( 'A simple title', '_' ) ); - $this->assertEquals( 'this_post_it_has_a_dash', util::slugify( 'This post -- it has a dash', '_' ) ); - $this->assertEquals( '123_1251251', util::slugify( '123----1251251', '_' ) ); - $this->assertEquals( 'one23_1251251', util::slugify( '123----1251251', '_', true ) ); - - // Blank seperator test - $this->assertEquals( 'asimpletitle', util::slugify( 'A simple title', '' ) ); - $this->assertEquals( 'thispostithasadash', util::slugify( 'This post -- it has a dash', '' ) ); - $this->assertEquals( '1231251251', util::slugify( '123----1251251', '' ) ); - $this->assertEquals( 'one231251251', util::slugify( '123----1251251', '', true ) ); - - // Test old parameter ordering for backwards compatability - error_reporting(E_ALL ^ E_USER_DEPRECATED); - $this->assertEquals( 'one23-1251251', util::slugify( '123----1251251', true ) ); - $this->assertEquals( '123-1251251', util::slugify( '123----1251251', false ) ); - } - - public function test_seems_utf8() - { - // Test a valid UTF-8 sequence: "ÜTF-8 Fµñ". - $validUTF8 = "\xC3\x9CTF-8 F\xC2\xB5\xC3\xB1"; - $this->assertTrue( util::seems_utf8( $validUTF8 ) ); - - $this->assertTrue( util::seems_utf8( "\xEF\xBF\xBD this has \xEF\xBF\xBD\xEF\xBF\xBD some invalid utf8 \xEF\xBF\xBD" ) ); - - // Test invalid UTF-8 sequences - $invalidUTF8 = "\xc3 this has \xe6\x9d some invalid utf8 \xe6"; - $this->assertFalse( util::seems_utf8( $invalidUTF8 ) ); - - // And test some plain ASCII - $this->assertTrue( util::seems_utf8( 'The quick brown fox jumps over the lazy dog' ) ); - - // Test an invalid non-UTF-8 string. - if (function_exists('mb_convert_encoding')) { - mb_internal_encoding('UTF-8'); - // Converts the 'ç' UTF-8 character to UCS-2LE - $utf8Char = pack('n', 50087); - $ucsChar = mb_convert_encoding($utf8Char, 'UCS-2LE', 'UTF-8'); - - // Ensure that PHP's internal encoding system isn't malconfigured. - $this->assertEquals( $utf8Char, 'ç', 'This PHP system\'s internal character set is not properly set as UTF-8.' ); - $this->assertEquals( $utf8Char, pack('n', 50087), 'Something is wrong with your ICU unicode library.' ); - - // Test for not UTF-8. - $this->assertFalse( util::seems_utf8( $ucsChar) ); - - // Test the worker method. - $method = self::getMethod('seemsUtf8Regex'); - $this->assertFalse($method->invoke(null, $invalidUTF8), 'util::seemsUtf8Regex did not properly detect invalid UTF-8.'); - $this->assertTrue($method->invoke(null, $validUTF8), 'util::seemsUtf8Regex did not properly detect valid UTF-8.'); - } - } - - public function test_size_format() - { - $size = util::size_format( 512, 0 ); - $this->assertEquals( '512 B', $size ); - - $size = util::size_format( 2048, 1 ); - $this->assertEquals( '2.0 KiB', $size ); - - $size = util::size_format( 25151251, 2 ); - $this->assertEquals( '23.99 MiB', $size ); - - $size = util::size_format( 19971597926, 2 ); - $this->assertEquals( '18.60 GiB', $size ); - - $size = util::size_format( 2748779069440, 1 ); - $this->assertEquals( '2.5 TiB', $size ); - - $size = util::size_format( 2.81475e15, 1 ); - $this->assertEquals( '2.5 PiB', $size ); - - $size = util::size_format( 2.81475e19, 1 ); - $this->assertEquals( '25000.0 PiB', $size ); - } - - public function test_maybe_serialize() - { - $obj = new stdClass(); - $obj->prop1 = 'Hello'; - $obj->prop2 = 'World'; - - $this->assertEquals( 'This is a string', util::maybe_serialize( 'This is a string' ) ); - $this->assertEquals( 5.81, util::maybe_serialize( 5.81 ) ); - $this->assertEquals( 'a:0:{}', util::maybe_serialize( array() ) ); - $this->assertEquals( 'O:8:"stdClass":2:{s:5:"prop1";s:5:"Hello";s:5:"prop2";s:5:"World";}', util::maybe_serialize( $obj ) ); - $this->assertEquals( 'a:4:{i:0;s:4:"test";i:1;s:4:"blah";s:5:"hello";s:5:"world";s:5:"array";O:8:"stdClass":2:{s:5:"prop1";s:5:"Hello";s:5:"prop2";s:5:"World";}}', util::maybe_serialize( array( 'test', 'blah', 'hello' => 'world', 'array' => $obj ) ) ); - } - - public function test_maybe_unserialize() - { - $obj = new stdClass(); - $obj->prop1 = 'Hello'; - $obj->prop2 = 'World'; - - $this->assertNull(util::maybe_unserialize(serialize(null))); - $this->assertFalse(util::maybe_unserialize(serialize(false))); - - $this->assertEquals( 'This is a string', util::maybe_unserialize( 'This is a string' ) ); - $this->assertEquals( 5.81, util::maybe_unserialize( 5.81 ) ); - $this->assertEquals( array(), util::maybe_unserialize( 'a:0:{}' ) ); - $this->assertEquals( $obj, util::maybe_unserialize( 'O:8:"stdClass":2:{s:5:"prop1";s:5:"Hello";s:5:"prop2";s:5:"World";}' ) ); - $this->assertEquals( array( 'test', 'blah', 'hello' => 'world', 'array' => $obj ), util::maybe_unserialize( 'a:4:{i:0;s:4:"test";i:1;s:4:"blah";s:5:"hello";s:5:"world";s:5:"array";O:8:"stdClass":2:{s:5:"prop1";s:5:"Hello";s:5:"prop2";s:5:"World";}}' ) ); - - // Test a broken serialization. - $expectedData = array( - 'Normal', - 'High-value Char: '.chr(231).'a-va?', // High-value Char: ça-va? [in ISO-8859-1] - ); - - $brokenSerialization = 'a:2:{i:0;s:6:"Normal";i:1;s:23:"High-value Char: ▒a-va?";}'; - - $unserializedData = util::maybe_unserialize($brokenSerialization); - $this->assertEquals($expectedData[0], $unserializedData[0], 'Did not properly fix the broken serialized data.'); - $this->assertEquals(substr($expectedData[1], 0, 10), substr($unserializedData[1], 0, 10), 'Did not properly fix the broken serialized data.'); - - // Test unfixable serialization. - $unfixableSerialization = 'a:2:{i:0;s:6:"Normal";}'; - $this->assertEquals($unfixableSerialization, util::maybe_unserialize($unfixableSerialization), 'Somehow the [previously?] impossible happened and utilphp thinks it has unserialized an unfixable serialization.'); - } - - public function test_is_serialized() - { - $this->assertFalse( util::is_serialized(1) ); - $this->assertFalse( util::is_serialized(null) ); - $this->assertFalse( util::is_serialized( 's:4:"test;' ) ); - $this->assertFalse( util::is_serialized( 'a:0:{}!' ) ); - $this->assertFalse( util::is_serialized( 'a:0' ) ); - $this->assertFalse( util::is_serialized( 'This is a string' ) ); - $this->assertFalse( util::is_serialized( 'a string' ) ); - $this->assertFalse( util::is_serialized( 'z:0;' ) ); - $this->assertTrue( util::is_serialized( 'N;' ) ); - $this->assertTrue( util::is_serialized( 'b:1;' ) ); - $this->assertTrue( util::is_serialized( 'a:0:{}' ) ); - $this->assertTrue( util::is_serialized( 'O:8:"stdClass":2:{s:5:"prop1";s:5:"Hello";s:5:"prop2";s:5:"World";}' ) ); - } - - public function test_fix_broken_serialization() - { - $expectedData = array( - 'Normal', - 'High-value Char: '.chr(231).'a-va?', // High-value Char: ça-va? [in ISO-8859-1] - ); - - $brokenSerialization = 'a:2:{i:0;s:6:"Normal";i:1;s:23:"High-value Char: ▒a-va?";}'; - - // Temporarily override error handling to ensure that this is, in fact, [still] a broken serialization. - { - $expectedError = array( - 'errno' => 8, - 'errstr' => 'unserialize(): Error at offset 55 of 60 bytes' - ); - - $reportedError = array(); - set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) use (&$reportedError) { - $reportedError = compact('errno', 'errstr'); - }); - - unserialize($brokenSerialization); - - $this->assertEquals($expectedError['errno'], $reportedError['errno']); - // Because HHVM's unserialize() error message does not contain enough info to properly test. - if (!defined('HHVM_VERSION')) { - $this->assertEquals($expectedError['errstr'], $reportedError['errstr']); - } - restore_error_handler(); - } - - $fixedSerialization = util::fix_broken_serialization($brokenSerialization); - $unserializedData = unserialize($fixedSerialization); - $this->assertEquals($expectedData[0], $unserializedData[0], 'Did not properly fix the broken serialized data.'); - - $this->assertEquals(substr($expectedData[1], 0, 10), substr($unserializedData[1], 0, 10), 'Did not properly fix the broken serialized data.'); - } - - public function test_is_https() - { - $_SERVER['HTTPS'] = null; - - $this->assertFalse( util::is_https() ); - - $_SERVER['HTTPS'] = 'on'; - - $this->assertTrue( util::is_https() ); - } - - public function test_add_query_arg() - { - // Regular tests - $this->assertEquals( '/app/admin/users?user=5', util::add_query_arg( 'user', 5, '/app/admin/users' ) ); - $this->assertEquals( '/app/admin/users?user=5', util::add_query_arg( array( 'user' => 5 ), '/app/admin/users' ) ); - $this->assertEquals( '/app/admin/users?user=5', util::add_query_arg( array( 'user' => 5 ), null, '/app/admin/users' ) ); - $this->assertEquals( '/app/admin/users?action=edit&user=5', util::add_query_arg( 'user', 5, '/app/admin/users?action=edit' ) ); - $this->assertEquals( '/app/admin/users?action=edit&user=5', util::add_query_arg( array( 'user' => 5 ), '/app/admin/users?action=edit' ) ); - $this->assertEquals( '/app/admin/users?action=edit&tab=personal&user=5', util::add_query_arg( 'user', 5, '/app/admin/users?action=edit&tab=personal' ) ); - $this->assertEquals( '/app/admin/users?action=edit&tab=personal&user=5', util::add_query_arg( array( 'user' => 5 ), '/app/admin/users?action=edit&tab=personal' ) ); - - // Ensure strips false. - $this->assertEquals('/index.php', util::add_query_arg('debug', false, '/index.php')); - - // With a URL fragment - $this->assertEquals( '/app/admin/users?user=5#test', util::add_query_arg( 'user', 5, '/app/admin/users#test' ) ); - - // Full URL - $this->assertEquals( 'http://example.com/?a=b', util::add_query_arg( 'a', 'b', 'http://example.com' ) ); - - // Only the query string - $this->assertEquals( '?a=b&c=d', util::add_query_arg( 'c', 'd', '?a=b' ) ); - $this->assertEquals( 'a=b&c=d', util::add_query_arg( 'c', 'd', 'a=b' ) ); - - // Url encoding test - $this->assertEquals( '/app/admin/users?param=containsa%26sym', util::add_query_arg( 'param', 'containsa&sym', '/app/admin/users' ) ); - - // If not provided, grab the URI from the server. - $_SERVER['REQUEST_URI'] = '/app/admin/users'; - $this->assertEquals( '/app/admin/users?user=6', util::add_query_arg( array( 'user' => 6 ) ) ); - $this->assertEquals( '/app/admin/users?user=7', util::add_query_arg( 'user', 7 ) ); - } - - public function test_remove_query_arg() - { - $this->assertEquals( '/app/admin/users', util::remove_query_arg( 'user', '/app/admin/users?user=5' ) ); - $this->assertEquals( '/app/admin/users?action=edit', util::remove_query_arg( 'user', '/app/admin/users?action=edit&user=5' ) ); - $this->assertEquals( '/app/admin/users?user=5', util::remove_query_arg( array( 'tab', 'action' ), '/app/admin/users?action=edit&tab=personal&user=5' ) ); - } - - public function test_http_build_url() - { - $url = 'http://user:pass@example.com:8080/path/?query#fragment'; - - $expected = 'http://example.com/'; - $actual = util::http_build_url($url, array(), util::HTTP_URL_STRIP_ALL); - $this->assertEquals($expected, $actual); - - $expected = 'http://example.com:8080/path/?query#fragment'; - $actual = util::http_build_url($url, array(), util::HTTP_URL_STRIP_AUTH); - $this->assertEquals($expected, $actual); - - $this->assertEquals('https://dev.example.com/', util::http_build_url('http://example.com/', array('scheme' => 'https', 'host' => 'dev.example.com'))); - $this->assertEquals('http://example.com/#hi', util::http_build_url('http://example.com/', array('fragment' => 'hi'), util::HTTP_URL_REPLACE)); - $this->assertEquals('http://example.com/page', util::http_build_url('http://example.com/', array('path' => 'page'), util::HTTP_URL_JOIN_PATH)); - $this->assertEquals('http://example.com/page', util::http_build_url('http://example.com', array('path' => 'page'), util::HTTP_URL_JOIN_PATH)); - $this->assertEquals('http://example.com/?hi=Bro', util::http_build_url('http://example.com/', array('query' => 'hi=Bro'), util::HTTP_URL_JOIN_QUERY)); - $this->assertEquals('http://example.com/?show=1&hi=Bro', util::http_build_url('http://example.com/?show=1', array('query' => 'hi=Bro'), util::HTTP_URL_JOIN_QUERY)); - - $this->assertEquals('http://admin@example.com/', util::http_build_url('http://example.com/', array('user' => 'admin'))); - $this->assertEquals('http://admin:1@example.com/', util::http_build_url('http://example.com/', array('user' => 'admin', 'pass' => '1'))); - } - - public function test_str_to_bool() - { - $this->assertTrue( util::str_to_bool( 'true' ) ); - $this->assertTrue( util::str_to_bool( 'yes' ) ); - $this->assertTrue( util::str_to_bool( 'y' ) ); - $this->assertTrue( util::str_to_bool( 'oui' ) ); - $this->assertTrue( util::str_to_bool( 'vrai' ) ); - - $this->assertFalse( util::str_to_bool( 'false' ) ); - $this->assertFalse( util::str_to_bool( 'no' ) ); - $this->assertFalse( util::str_to_bool( 'n' ) ); - $this->assertFalse( util::str_to_bool( 'non' ) ); - $this->assertFalse( util::str_to_bool( 'faux' ) ); - - $this->assertFalse( util::str_to_bool( 'test' , false) ); - - } - - public function test_array_pluck() - { - $array = array( - array( - 'name' => 'Bob', - 'age' => 37 - ), - array( - 'name' => 'Fred', - 'age' => 37 - ), - array( - 'name' => 'Jane', - 'age' => 29 - ), - array( - 'name' => 'Brandon', - 'age' => 20 - ), - array( - 'age' => 41 - ) - ); - - $obj_array = array( - 'bob' => (object) array( - 'name' => 'Bob', - 'age' => 37 - ), - 'fred' => (object) array( - 'name' => 'Fred', - 'age' => 37 - ), - 'jane' => (object) array( - 'name' => 'Jane', - 'age' => 29 - ), - 'brandon' => (object) array( - 'name' => 'Brandon', - 'age' => 20 - ), - 'invalid' => (object) array( - 'age' => 41 - ) - ); - - $obj_array_expect = array( - 'bob' => 'Bob', - 'fred' => 'Fred', - 'jane' => 'Jane', - 'brandon' => 'Brandon' - ); - - $this->assertEquals( array( 'Bob', 'Fred', 'Jane', 'Brandon' ), util::array_pluck( $array, 'name' ) ); - $this->assertEquals( array( 'Bob', 'Fred', 'Jane', 'Brandon', array( 'age' => 41 ) ), util::array_pluck( $array, 'name', TRUE, FALSE ) ); - $this->assertEquals( $obj_array_expect, util::array_pluck( $obj_array, 'name' ) ); - $this->assertEquals( array( 'Bob', 'Fred', 'Jane', 'Brandon' ), util::array_pluck( $obj_array, 'name', FALSE ) ); - - $expected = array('Bob', 'Fred', 'Jane', 'Brandon', 'invalid' => (object)array('age' => 41)); - $this->assertEquals($expected, util::array_pluck($obj_array, 'name', FALSE, FALSE)); - $expected = array('Bob', 'Fred', 'Jane', 'Brandon', array('age' => 41)); - $this->assertEquals($expected, util::array_pluck($array, 'name', false, false)); - } - - public function test_htmlentities() - { - $this->assertEquals( 'One & Two', util::htmlentities( 'One & Two' ) ); - $this->assertEquals( 'One & Two', util::htmlentities( 'One & Two', TRUE ) ); - } - - public function test_htmlspecialchars() - { - $this->assertEquals( 'One & Two', util::htmlspecialchars( 'One & Two' ) ); - $this->assertEquals( 'One & Two', util::htmlspecialchars( 'One & Two', TRUE ) ); - } - - public function test_remove_accents() - { - $this->assertEquals( 'A', util::remove_accents( "\xC3\x81" ) ); - $this->assertEquals( 'e', util::remove_accents( "\xC4\x97" ) ); - $this->assertEquals( 'U', util::remove_accents( "\xC3\x9C" ) ); - $this->assertEquals( 'Ae', util::remove_accents( "Ä", 'de' ) ); - $this->assertEquals( 'OEoeAEDHTHssaedhth', util::remove_accents(chr(140) . chr(156) . chr(198) . chr(208) . chr(222) . chr(223) . chr(230) . chr(240) . chr(254))); - } - - public function test_zero_pad() - { - $this->assertEquals( '00000341', util::zero_pad( 341, 8 ) ); - $this->assertEquals( '341', util::zero_pad( 341, 1 ) ); - } - - public function test_human_time_diff() - { - $this->assertEquals( '1 second ago', util::human_time_diff( time() - 1 ) ); - $this->assertEquals( '30 seconds ago', util::human_time_diff( time() - 30 ) ); - $this->assertEquals( '1 minute ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_MINUTE * 1.4 ) ) ); - $this->assertEquals( '5 minutes ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_MINUTE * 5 ) ) ); - $this->assertEquals( '1 hour ago', util::human_time_diff( time() - ( util::SECONDS_IN_AN_HOUR ) ) ); - $this->assertEquals( '2 hours ago', util::human_time_diff( time() - ( util::SECONDS_IN_AN_HOUR * 2 ) ) ); - $this->assertEquals( '1 day ago', util::human_time_diff( time() - ( util::SECONDS_IN_AN_HOUR * 24 ) ) ); - $this->assertEquals( '5 days ago', util::human_time_diff( time() - ( util::SECONDS_IN_AN_HOUR * 24 * 5 ) ) ); - $this->assertEquals( '1 week ago', util::human_time_diff( time() - ( util::SECONDS_IN_AN_HOUR * 24 * 7 ) ) ); - $this->assertEquals( '2 weeks ago', util::human_time_diff( time() - ( util::SECONDS_IN_AN_HOUR * 24 * 14 ) ) ); - $this->assertEquals( '1 month ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_WEEK * 5 ) ) ); - $this->assertEquals( '2 months ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_WEEK * 10 ) ) ); - $this->assertEquals( '1 year ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_MONTH * 15 ) ) ); - $this->assertEquals( '2 years ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_MONTH * 36 ) ) ); - $this->assertEquals( '11 years ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_MONTH * 140 ) ) ); - - $this->assertEquals( 'fifteen minutes ago', util::human_time_diff( time() - ( util::SECONDS_IN_A_MINUTE * 15 ), '', TRUE ) ); - } - - public function test_number_to_word() - { - try { - util::number_to_word('junk data'); - $this->fail('Accepted junk data'); - } catch(\LogicException $e) { - $this->assertEquals('Not a number', $e->getMessage()); - } - - // Partially numeric. - $this->assertEquals('', util::number_to_word('1a')); - - // Decimals - $this->assertEquals( 'five point zero five', util::number_to_word('5.05') ); - $this->assertEquals( 'zero point eight', util::number_to_word( 0.8 ) ); - - // Integers - $this->assertEquals( 'positive one', util::number_to_word( '+1' ) ); - $this->assertEquals( 'negative twelve', util::number_to_word( -12 ) ); - $this->assertEquals( 'one', util::number_to_word( 1 ) ); - $this->assertEquals( 'five', util::number_to_word( 5 ) ); - $this->assertEquals( 'fifteen', util::number_to_word( 15 ) ); - $this->assertEquals( 'twenty-one', util::number_to_word( 21 ) ); - $this->assertEquals( 'thirty-two', util::number_to_word( 32 ) ); - $this->assertEquals( 'forty-three', util::number_to_word( 43 ) ); - $this->assertEquals( 'fifty-four', util::number_to_word( 54 ) ); - $this->assertEquals( 'sixty-six', util::number_to_word( 66 ) ); - $this->assertEquals( 'seventy-seven', util::number_to_word( 77 ) ); - $this->assertEquals( 'eighty-eight', util::number_to_word( 88 ) ); - $this->assertEquals( 'ninety-nine', util::number_to_word( 99 ) ); - $this->assertEquals( 'one hundred and thirty-six', util::number_to_word( 136 ) ); - $this->assertEquals( 'ten', util::number_to_word( 10 ) ); - $this->assertEquals( 'twenty', util::number_to_word( 20 ) ); - $this->assertEquals( 'thirty', util::number_to_word( 30 ) ); - $this->assertEquals( 'forty', util::number_to_word( 40 ) ); - $this->assertEquals( 'fifty', util::number_to_word( 50 ) ); - $this->assertEquals( 'sixty', util::number_to_word( 60 ) ); - $this->assertEquals( 'seventy', util::number_to_word( 70 ) ); - $this->assertEquals( 'eighty', util::number_to_word( 80 ) ); - $this->assertEquals( 'ninety', util::number_to_word( 90 ) ); - $this->assertEquals( 'eleven', util::number_to_word( 11 ) ); - $this->assertEquals( 'thirteen', util::number_to_word( 13 ) ); - $this->assertEquals( 'fourteen', util::number_to_word( 14 ) ); - $this->assertEquals( 'fifteen', util::number_to_word( 15 ) ); - $this->assertEquals( 'sixteen', util::number_to_word( 16 ) ); - $this->assertEquals( 'seventeen', util::number_to_word( 17 ) ); - $this->assertEquals( 'eighteen', util::number_to_word( 18 ) ); - $this->assertEquals( 'nineteen', util::number_to_word( 19 ) ); - $this->assertEquals( 'one thousand', util::number_to_word( 1000 ) ); - $this->assertEquals( 'one million', util::number_to_word( 1000000 ) ); - $this->assertEquals( 'one billion', util::number_to_word( 1000000000 ) ); - $this->assertEquals( 'one trillion', util::number_to_word( 1000000000000 ) ); - $this->assertEquals( 'one quadrillion', util::number_to_word( '1000000000000000' ) ); - $this->assertEquals( 'one quintrillion', util::number_to_word( '1000000000000000000' ) ); - $this->assertEquals( 'one sextillion', util::number_to_word( '1000000000000000000000' ) ); - $this->assertEquals( 'one septillion', util::number_to_word( '1000000000000000000000000' ) ); - $this->assertEquals( 'one octillion', util::number_to_word( '1000000000000000000000000000' ) ); - $this->assertEquals( 'one nonillion', util::number_to_word( '1000000000000000000000000000000' ) ); - $this->assertEquals( 'one decillion', util::number_to_word( '1000000000000000000000000000000000' ) ); - $this->assertEquals( 'one', util::number_to_word( '1000000000000000000000000000000000000000000' ) ); - - } - - public function test_array_search_deep() - { - $users = array( - 1 => (object) array( 'username' => 'brandon', 'age' => 20 ), - 2 => (object) array( 'username' => 'matt', 'age' => 27 ), - 3 => (object) array( 'username' => 'jane', 'age' => 53 ), - 4 => (object) array( 'username' => 'john', 'age' => 41 ), - 5 => (object) array( 'username' => 'steve', 'age' => 11 ), - 6 => (object) array( 'username' => 'fred', 'age' => 42 ), - 7 => (object) array( 'username' => 'rasmus', 'age' => 21 ), - 8 => (object) array( 'username' => 'don', 'age' => 15 ), - 9 => array( 'username' => 'darcy', 'age' => 33 ), - ); - - $test = array( - 1 => 'brandon', - 2 => 'devon', - 3 => array( 'troy' ), - 4 => 'annie' - ); - - $this->assertFalse( util::array_search_deep( $test, 'bob' ) ); - $this->assertEquals( 3, util::array_search_deep( $test, 'troy' ) ); - $this->assertEquals( 4, util::array_search_deep( $test, 'annie' ) ); - $this->assertEquals( 2, util::array_search_deep( $test, 'devon', 'devon' ) ); - $this->assertEquals( 7, util::array_search_deep( $users, 'rasmus', 'username' ) ); - $this->assertEquals( 9, util::array_search_deep( $users, 'darcy', 'username' ) ); - $this->assertEquals( 1, util::array_search_deep( $users, 'brandon' ) ); - } - - public function test_array_map_deep() - { - $input = array( - '<', - 'abc', - '>', - 'def', - array( '&', 'test', '123' ), - (object) array( 'hey', '<>' ) - ); - - $expect = array( - '<', - 'abc', - '>', - 'def', - array( '&', 'test', '123' ), - (object) array( 'hey', '<>' ) - ); - - $this->assertEquals( $expect, util::array_map_deep( $input, 'htmlentities' ) ); - } - - public function test_random_string() - { - // Make sure the generated string contains only human friendly characters and is 30 characters long - $str = util::random_string( 30 ); - $this->assertTrue( (bool) preg_match( '/^([ABCDEFGHJKLMNPQRSTUVWXYZabcdefhjkmnprstuvwxyz23456789]{30})$/', $str ) ); - - // Make sure the generated string is 30 characters long - $str = util::random_string( 30, false, true ); - $this->assertTrue( strlen( $str ) === 30, 'random_string produced an invalid length string' ); - - // Make sure the generated string is 120 characters long - $str = util::random_string( 120 ); - $this->assertTrue(strlen( $str ) === 120, 'random_string produced an invalid length string'); - - // Make sure the string doesn't contain duplicate letters - $str = util::random_string( 53, true, false, true ); - $this->assertTrue(strlen($str) === 53, 'random_string produced an invalid length string'); - $this->assertTrue(count(array_unique(str_split($str))) === strlen($str), 'random_string produced a string with duplicate characters'); - - // Longer length than characters available - try { - $str = util::random_string( 55, true, false, true ); - $this->assertTrue( false ); - } catch (Exception $e) { - $this->assertTrue( true ); - } - - // Test secure variant - $str = util::secure_random_string(16); - $this->assertTrue(strlen($str) === 16); - - // Longer length than characters available - try { - $str = util::secure_random_string(0); - $this->assertTrue(false); - } catch (Exception $e) { - $this->assertTrue(true); - } - } - - public function test_match_string() - { - $this->assertTrue( util::match_string('a', 'a') ); - $this->assertFalse( util::match_string('a', ' a') ); - $this->assertFalse( util::match_string('/', '/something') ); - $this->assertTrue( util::match_string('test/*', 'test/first/second') ); - $this->assertTrue( util::match_string('*/test', 'first/second/test') ); - $this->assertFalse( util::match_string('first/', 'first/second/test') ); - $this->assertFalse( util::match_string('test', 'TEST') ); - $this->assertTrue( util::match_string('test', 'TEST', false) ); - } - - public function test_validate_email() - { - $this->assertTrue( util::validate_email( 'john.smith@gmail.com' ) ); - $this->assertTrue( util::validate_email( 'john.smith+label@gmail.com' ) ); - $this->assertTrue( util::validate_email( 'john.smith@gmail.co.uk' ) ); - } - - public function test_safe_truncate() - { - $this->assertEquals( 'The quick brown fox...', util::safe_truncate( 'The quick brown fox jumps over the lazy dog', 24 ) ); - $this->assertEquals( 'The quick brown fox jumps over the lazy dog', util::safe_truncate( 'The quick brown fox jumps over the lazy dog', 55 ) ); - $this->assertEquals( 'Th...', util::safe_truncate( 'The quick brown fox jumps over the lazy dog', 2 ) ); - $this->assertEquals( 'The...', util::safe_truncate( 'The quick brown fox jumps over the lazy dog', 3 ) ); - $this->assertEquals( 'The...', util::safe_truncate( 'The quick brown fox jumps over the lazy dog', 7 ) ); - } - - public function test_limit_characters() - { - $this->assertEquals( 'The quick brown fox jump...', util::limit_characters( 'The quick brown fox jumps over the lazy dog', 24 ) ); - $this->assertEquals( 'The quick brown fox jumps over the lazy dog', util::limit_characters( 'The quick brown fox jumps over the lazy dog', 55 ) ); - $this->assertEquals( 'Th...', util::limit_characters( 'The quick brown fox jumps over the lazy dog', 2 ) ); - $this->assertEquals( 'The...', util::limit_characters( 'The quick brown fox jumps over the lazy dog', 3 ) ); - $this->assertEquals( 'The qui...', util::limit_characters( 'The quick brown fox jumps over the lazy dog', 7 ) ); - $this->assertEquals( 'The quick brown fox jumps over the lazy dog', util::limit_characters( 'The quick brown fox jumps over the lazy dog', 150 ) ); - } - - public function test_limit_words() - { - $this->assertEquals( 'The quick brown...', util::limit_words( 'The quick brown fox jumps over the lazy dog', 3 ) ); - $this->assertEquals( 'The quick brown fox jumps...', util::limit_words( 'The quick brown fox jumps over the lazy dog', 5 ) ); - $this->assertEquals( 'The...', util::limit_words( 'The quick brown fox jumps over the lazy dog', 1 ) ); - $this->assertEquals( 'The quick brown fox jumps over the lazy dog', util::limit_words( 'The quick brown fox jumps over the lazy dog', 90 ) ); - $this->assertEquals( 'The quick brown fox jumps over the...', util::limit_words( 'The quick brown fox jumps over the lazy dog', 7 ) ); - } - - public function test_ordinal() - { - $this->assertEquals( '1st', util::ordinal( 1 ) ); - $this->assertEquals( '2nd', util::ordinal( 2 ) ); - $this->assertEquals( '3rd', util::ordinal( 3 ) ); - $this->assertEquals( '4th', util::ordinal( 4 ) ); - $this->assertEquals( '5th', util::ordinal( 5 ) ); - $this->assertEquals( '6th', util::ordinal( 6 ) ); - $this->assertEquals( '7th', util::ordinal( 7 ) ); - $this->assertEquals( '8th', util::ordinal( 8 ) ); - $this->assertEquals( '9th', util::ordinal( 9 ) ); - $this->assertEquals( '22nd', util::ordinal( 22 ) ); - $this->assertEquals( '23rd', util::ordinal( 23 ) ); - $this->assertEquals( '143rd', util::ordinal( 143 ) ); - } - - public function test_array_first() - { - $test = array( 'a' => array( 'a', 'b', 'c' ) ); - - $this->assertEquals( 'a', util::array_first( util::array_get( $test['a'] ) ) ); - } - - public function test_array_first_key() - { - $test = array( 'a' => array( 'a' => 'b', 'c' => 'd' ) ); - - $this->assertEquals( 'a', util::array_first_key( util::array_get( $test['a'] ) ) ); - } - - public function test_array_last() - { - $test = array( 'a' => array( 'a', 'b', 'c' ) ); - - $this->assertEquals( 'c', util::array_last( util::array_get( $test['a'] ) ) ); - } - - public function test_array_last_key() - { - $test = array( 'a' => array( 'a' => 'b', 'c' => 'd' ) ); - - $this->assertEquals( 'c', util::array_last_key( util::array_get( $test['a'] ) ) ); - } - - public function test_array_flatten() - { - $input = array( 'a', 'b', 'c', 'd', array( 'first' => 'e', 'f', 'second' => 'g', array( 'h', 'third' => 'i', array( array( array( array( 'j', 'k', 'l' ) ) ) ) ) ) ); - $expectNoKeys = range( 'a', 'l' ); - $expectWithKeys = array( - 'a', 'b', 'c', 'd', - 'first' => 'e', - 'f', - 'second' => 'g', - 'h', - 'third' => 'i', - 'j', 'k', 'l' - ); - - $this->assertEquals( $expectWithKeys, util::array_flatten( $input ) ); - $this->assertEquals( $expectNoKeys, util::array_flatten( $input, false ) ); - $this->assertEquals( $expectWithKeys, util::array_flatten( $input, true ) ); - } - - public function test_strip_space() - { - $input = ' The quick brown fox jumps over the lazy dog '; - $expect = 'Thequickbrownfoxjumpsoverthelazydog'; - - $this->assertEquals($expect, Util::strip_space($input)); - } - - public function test_sanitize_string() - { - $input = ' Benoit! à New-York? j’ai perçu 1 % : Qu’as-tu "gagné" chez M. V. Noël? Dix francs.'; - $expect = 'benoitanewyorkjaipercu1quastugagnechezmvnoeldixfrancs'; - - $this->assertEquals($expect, Util::sanitize_string($input)); - } - - public function test_get_gravatar() - { - $_SERVER['HTTPS'] = 'on'; - $this->assertEquals('https://secure.gravatar.com/avatar/a4bf5bbb9feaa2713d99a3b52ab80024?s=32', util::get_gravatar('john.doe@example.org')); - $this->assertEquals('https://secure.gravatar.com/avatar/a4bf5bbb9feaa2713d99a3b52ab80024?s=128', util::get_gravatar('john.doe@example.org', 128)); - - $_SERVER['HTTPS'] = 'off'; - $this->assertEquals('http://www.gravatar.com/avatar/a4bf5bbb9feaa2713d99a3b52ab80024?s=32', util::get_gravatar('john.doe@example.org')); - $this->assertEquals('http://www.gravatar.com/avatar/a4bf5bbb9feaa2713d99a3b52ab80024?s=128', util::get_gravatar('john.doe@example.org', 128)); - } - - public function test_get_client_ip() - { - $_SERVER['REMOTE_ADDR'] = '192.168.30.152'; - $_SERVER['HTTP_CLIENT_IP'] = '192.168.30.153'; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '192.168.30.154'; - $this->assertEquals('192.168.30.152', util::get_client_ip()); - $this->assertEquals('192.168.30.153', util::get_client_ip(true)); - - unset($_SERVER['HTTP_CLIENT_IP']); - $this->assertEquals('192.168.30.154', util::get_client_ip(true)); - unset($_SERVER['HTTP_X_FORWARDED_FOR']); - $this->assertEquals('192.168.30.152', util::get_client_ip(true)); - } - - public function test_full_permissions() - { - // Text a non-existant file. - $this->assertFalse(util::full_permissions('faker-123.blah'), 'Gave a permission value for a non-existant file.'); - - // Test an existing file. - $expected = '-rw-rw-rw-'; - $tempFile = tempnam(sys_get_temp_dir(), 'foo'); - $this->assertTrue(chmod($tempFile, 0666), 'Oops. Could not change temp file\'s permissions to 0666.'); - $this->assertEquals($expected, util::full_permissions($tempFile), 'Could not properly obtain permissions of an existing file.'); - unlink($tempFile); - - $this->assertEquals('lr--r--r--', util::full_permissions('fake-file-222', octdec('120444'))); - $this->assertEquals('ur--r--r--', util::full_permissions('fake-file-222', octdec('000444'))); - $this->assertEquals('srwxr-xr-x', util::full_permissions('fake-file-222', octdec('140755'))); - $this->assertEquals('drwxr-xr-x', util::full_permissions('fake-file-222', octdec('40755'))); - $this->assertEquals('brw-rw----', util::full_permissions('fake-file-222', octdec('60660'))); - $this->assertEquals('crw-rw----', util::full_permissions('fake-file-222', octdec('20660'))); - $this->assertEquals('prw-rw----', util::full_permissions('fake-file-222', octdec('10660'))); - $this->assertEquals('---x------', util::full_permissions('fake-file-222', octdec('100100'))); - $this->assertEquals('--w-------', util::full_permissions('fake-file-222', octdec('100200'))); - $this->assertEquals('--wx------', util::full_permissions('fake-file-222', octdec('100300'))); - $this->assertEquals('-r--------', util::full_permissions('fake-file-222', octdec('100400'))); - $this->assertEquals('-r-x------', util::full_permissions('fake-file-222', octdec('100500'))); - $this->assertEquals('-rw-------', util::full_permissions('fake-file-222', octdec('100600'))); - $this->assertEquals('-rwx------', util::full_permissions('fake-file-222', octdec('100700'))); - - // Windows does not have the concept of /. - if (!defined('PHP_WINDOWS_VERSION_MAJOR')) { - $this->assertEquals('drwxr-xr-x', util::full_permissions('/')); - } - } - - public function test_array_clean() - { - $input = array( 'a', 'b', '', null, false, 0); - $expect = array('a', 'b'); - $this->assertEquals($expect, Util::array_clean($input)); - } - - public function test_var_dump_plain() - { - $input = 'var'; - $expect = 'string(3) "var"'; - $this->assertEquals($expect, Util::var_dump_plain($input, true)); - - $input = true; - $expect = 'bool(true)'; - $this->assertEquals($expect, Util::var_dump_plain($input, true)); - - $input = 1; - $expect = 'int(1)'; - $this->assertEquals($expect, Util::var_dump_plain($input, true)); - - $input = 1.5; - $expect = 'float(1.5)'; - $this->assertEquals($expect, Util::var_dump_plain($input, true)); - - $input = null; - $expect = 'NULL'; - $this->assertEquals($expect, Util::var_dump_plain($input, true)); - - $input = fopen('php://memory', 'r'); - $expect = 'resource("stream") "' . $input . '"'; - $this->assertEquals($expect, Util::var_dump_plain($input, -1)); - fclose($input); - - // Test complex arrays. - $input = array(1, 2, 4, 6, 10 => 20, 100 => 200); - $actual = util::var_dump_plain($input, true); - $this->assertContains(')', $actual); - - // Test complex objects. - $experiment = new VarDumpExperiment(); - $actual = util::var_dump_plain($experiment, true); - $this->assertContains('1 => string(1', $actual); - } - - public function test_var_dump() - { - $input = 'var'; - $expect = '
string(3) "var"
'; - - // Ensure the proper output is returned - $this->assertEquals($expect, Util::var_dump($input, true)); - - // Ensure the proper output is actually outputted - $this->expectOutputString($expect); - util::var_dump($input); - - // Ensure we avoid infinite recursion on recursive arrays - $a = array('a' => 'value a', 'b' => 'value b'); - $b = array('test' => &$a); - $c = array('a' => &$a, 'b' => &$b); - $a['c'] = &$c; - $b['c'] = &$c; - $this->assertContains('*RECURSION DETECTED*', Util::var_dump($c, true)); - - // Ensure we avoid infinite recursion on recursive objects - $a = (object) array('a' => 'value a', 'b' => 'value b'); - $b = (object) array('test' => &$a); - $c = (object) array('a' => &$a, 'b' => &$b); - $a->c = &$c; - $b->c = &$c; - $this->assertContains('*RECURSION DETECTED*', Util::var_dump($c, true)); - - // Test class scoping. - $experiment = new VarDumpExperiment(); - $actual = util::var_dump($experiment, true); - - $snippet = substr($actual, strrpos($actual, 'display:inline')); - $this->assertContains('"public"', $snippet); - $this->assertContains('"protected:protected"', $snippet); - $this->assertContains('"private:VarDumpExperiment:private"', $actual); - } - - public function test_linkify() - { - $input = 'great websites: http://www.google.com?param=test and http://yahoo.com/a/nested/folder'; - $expect = 'great websites: http://www.google.com?param=test and http://yahoo.com/a/nested/folder'; - $this->assertEquals($expect, Util::linkify($input)); - - $this->assertEquals($expect, util::linkify($expect), 'linkify() tried to double linkify an href.'); - } - - public function test_start_with() - { - $this->assertTrue(Util::starts_with('start a string', 'start a')); - $this->assertFalse(Util::starts_with('start a string', 'string')); - } - - public function test_end_with() - { - $this->assertTrue(Util::ends_with('start a string', 'a string')); - $this->assertFalse(Util::ends_with('start a string', 'start')); - } - - public function test_contains() - { - $this->assertTrue(Util::str_contains('start a string', 'a string')); - $this->assertFalse(Util::str_contains('start a string', 'Start')); - } - - public function test_iContains() - { - $this->assertTrue(Util::str_icontains('start a string', 'a string')); - $this->assertTrue(Util::str_icontains('start a string', 'Start')); - } - - public function test_get_file_ext() - { - $input = 'a_pdf_fil.pdf'; - $expect = 'pdf'; - $this->assertEquals($expect, Util::get_file_ext($input)); - } - - public function test_rmdir() - { - $dirname = dirname(__FILE__); - - // Test deleting a non-existant directory - $this->assertFalse(file_exists($dirname . '/test1')); - $this->assertTrue(util::rmdir($dirname . '/test1')); - - // Test deleting an empty directory - $dir = $dirname . '/test2'; - mkdir($dir); - - $this->assertTrue(is_dir($dir)); - - if (is_dir($dir)) { - util::rmdir($dir); - $this->assertFalse(is_dir($dir)); - } - - // Test deleting a non-empty directory - $dir = $dirname . '/test3'; - $file = $dirname . '/test3/test.txt'; - mkdir($dir); - touch($file); - - $this->assertTrue(is_dir($dir)); - $this->assertTrue(is_file($file)); - - if (is_dir($dir)) { - util::rmdir($dir); - $this->assertFalse(is_dir($dir)); - $this->assertFalse(is_file($file)); - } - - // Test deleting a non-directory path - $file = $dirname . '/test4.txt'; - touch($file); - - try { - $str = util::rmdir($file); - $this->assertTrue(false); - } catch (\Exception $e) { - $this->assertTrue(true); - } - - unlink($file); - - // Test deleting a nested directory - $dir1 = $dirname . '/test5'; - $dir2 = $dirname . '/test5/nested_dir'; - $file1 = $dir1 . '/file1.txt'; - $file2 = $dir2 . '/file2.txt'; - mkdir($dir1); - mkdir($dir2); - touch($file1); - touch($file2); - - $this->assertTrue(is_dir($dir1)); - $this->assertTrue(is_dir($dir2)); - $this->assertTrue(is_file($file1)); - $this->assertTrue(is_file($file2)); - - if (is_dir($dir1)) { - util::rmdir($dir1); - $this->assertFalse(is_dir($dir1)); - $this->assertFalse(is_dir($dir2)); - $this->assertFalse(is_file($file1)); - $this->assertFalse(is_file($file2)); - } - - // Test symlink traversal. - $dir = $dirname . '/test6'; - $nestedDir = "$dir/nested"; - $symlink = "$dir/nested-symlink"; - - mkdir($dir); - mkdir($nestedDir); - - $symlinkStatus = symlink($nestedDir, $symlink); - $this->assertTrue($symlinkStatus, 'The test system does not support making symlinks.'); - - if (!$symlink) { - return; - } - - $this->assertTrue(util::rmdir($symlink, true), 'Could not delete a symlinked directory.'); - $this->assertFalse(file_exists($symlink), 'Could not delete a symlinked directory.'); - util::rmdir($dir, true); - $this->assertFalse(is_dir($dir), 'Could not delete a directory with a symlinked directory inside of it.'); - } - - public function test_get_current_url() - { - $expected = 'http://test.dev/test.php?foo=bar'; - $expectedAuth = 'http://admin:123@test.dev/test.php?foo=bar'; - $expectedPort = 'http://test.dev:443/test.php?foo=bar'; - $expectedPort2 = 'https://test.dev:80/test.php?foo=bar'; - $expectedSSL = 'https://test.dev/test.php?foo=bar'; - - $_SERVER['HTTP_HOST'] = 'test.dev'; - $_SERVER['SERVER_PORT'] = 80; - $_SERVER['REQUEST_URI'] = '/test.php?foo=bar'; - $_SERVER['QUERY_STRING'] = 'foo=bar'; - $_SERVER['PHP_SELF'] = '/test.php'; - - // Test regular. - $this->assertEquals($expected, util::get_current_url()); - - // Test server auth. - $_SERVER['PHP_AUTH_USER'] = 'admin'; - $_SERVER['PHP_AUTH_PW'] = '123'; - $this->assertEquals($expectedAuth, util::get_current_url()); - unset($_SERVER['PHP_AUTH_USER']); - unset($_SERVER['PHP_AUTH_PW']); - - // Test port. - $_SERVER['SERVER_PORT'] = 443; - $this->assertEquals($expectedPort, util::get_current_url()); - - // Test SSL. - $_SERVER['HTTPS'] = 'on'; - $this->assertEquals($expectedSSL, util::get_current_url()); - $_SERVER['SERVER_PORT'] = 80; - $this->assertEquals($expectedPort2, util::get_current_url()); - unset($_SERVER['HTTPS']); - - // Test no $_SERVER['REQUEST_URI'] (e.g., MS IIS). - unset($_SERVER['REQUEST_URI']); - $this->assertEquals($expected, util::get_current_url()); - } - - public function test_set_writable() - { - if (strncasecmp(PHP_OS, 'WIN', 3) === 0) { - $this->markTestSkipped('This functionality is not working on Windows.'); - } - - if (posix_geteuid() === 0) { - $this->markTestSkipped('These tests don\'t work when run as root'); - } - - $this->assertFalse(util::set_writable('/no/such/file')); - - // Create a file to test with - $dirname = dirname(__FILE__); - $file = $dirname . '/test7'; - touch($file); - chmod($file, 0644); - - // The file is owned by us so it should be writable - $this->assertTrue(is_writable($file)); - $this->assertEquals('-rw-r--r--', util::full_permissions($file)); - - // Toggle writable bit off for us - util::set_writable($file, false); - clearstatcache(); - $this->assertFalse(is_writable($file)); - $this->assertEquals('-r--r--r--', util::full_permissions($file)); - - // Toggle writable bit back on for us - util::set_writable($file, true); - clearstatcache(); - $this->assertTrue(is_writable($file)); - $this->assertEquals('-rw-r--r--', util::full_permissions($file)); - - unlink($file); - } - - public function test_set_readable() - { - if (strncasecmp(PHP_OS, 'WIN', 3) === 0) { - $this->markTestSkipped('This functionality is not working on Windows.'); - } - - if (posix_geteuid() === 0) { - $this->markTestSkipped('These tests don\'t work when run as root'); - } - - $this->assertFalse(util::set_readable('/no/such/file')); - - $dirname = dirname(__FILE__); - $file = $dirname . '/test8'; - touch($file); - - $this->assertTrue(is_readable($file)); - - util::set_readable($file, false); - clearstatcache(); - $this->assertFalse(is_readable($file)); - - util::set_readable($file, true); - clearstatcache(); - $this->assertTrue(is_readable($file)); - - unlink($file); - } - - public function test_set_executable() - { - if (strncasecmp(PHP_OS, 'WIN', 3) === 0) { - $this->markTestSkipped('This functionality is not working on Windows.'); - } - - if (posix_geteuid() === 0) { - $this->markTestSkipped('These tests don\'t work when run as root'); - } - - $this->assertFalse(util::set_executable('/no/such/file')); - - $dirname = dirname(__FILE__); - $file = $dirname . '/test9'; - touch($file); - - $this->assertFalse(is_executable($file)); - - util::set_executable($file, true); - clearstatcache(); - $this->assertTrue(is_executable($file)); - - util::set_executable($file, false); - clearstatcache(); - $this->assertFalse(is_executable($file)); - - unlink($file); - } - - public function test_directory_size() { - $dirname = dirname(__FILE__); - $dir = $dirname .'/dir1'; - mkdir($dir); - $file1 = $dir .'/file1'; - file_put_contents($file1, '1234567890'); - $file2 = $dir .'/file2'; - file_put_contents($file2, range('a', 'z')); - $this->assertEquals(10 + 26, util::directory_size($dir)); - util::rmdir($dir); - } - - public function test_get_user_directory() { - // Test for OS Default. - $this->assertTrue(is_writable(util::get_user_directory())); - - $oldServer = $_SERVER; - unset($_SERVER); - // Test for UNIX. - $_SERVER['HOME'] = '/home/unknown'; - $this->assertEquals($_SERVER['HOME'], util::get_user_directory(), 'Could not get the user\'s home directory in UNIX.'); - unset($_SERVER); - - // Test for Windows. - $expected = 'X:\Users\ThisUser'; - $_SERVER['HOMEDRIVE'] = 'X:'; - $_SERVER['HOMEPATH'] = '\Users\ThisUser'; - $this->assertEquals($expected, util::get_user_directory(), 'Could not get the user\'s home directory in Windows.'); - - // In case the tests are not being run in isolation. - $_SERVER = $oldServer; - } - - public function test_directory_contents() { - $dirname = dirname(__FILE__); - $dir = $dirname . DIRECTORY_SEPARATOR .'dir1'; - mkdir($dir); - $file1 = $dir . DIRECTORY_SEPARATOR .'file1'; - touch($file1); - $this->assertEquals(array($file1), util::directory_contents($dir)); - util::rmdir($dir); - } -} diff --git a/f_config/DB.php b/f_config/DB.php index 706dbe68..dc460849 100644 --- a/f_config/DB.php +++ b/f_config/DB.php @@ -1,6 +1,6 @@ IsExist()) { diff --git a/f_config/DBS.php b/f_config/DBS.php index 225af9d7..8221551d 100644 --- a/f_config/DBS.php +++ b/f_config/DBS.php @@ -1,6 +1,6 @@ diff --git a/f_install/install1.php b/f_install/install1.php index 20331bca..5eed4764 100644 --- a/f_install/install1.php +++ b/f_install/install1.php @@ -1,5 +1,5 @@ diff --git a/f_install/install2Post.php b/f_install/install2Post.php index 92a789d2..01311af9 100644 --- a/f_install/install2Post.php +++ b/f_install/install2Post.php @@ -4,9 +4,9 @@ $id = $_POST['id']; $pw = $_POST['pw']; $pw = md5($pw.$pw); -require('_common.php'); +require_once('_common.php'); require(ROOT.W.F_FUNC.W.'class._Time.php'); -require(ROOT.W.F_CONFIG.W.DB.PHP); +require_once(ROOT.W.F_CONFIG.W.DB.PHP); // 시스템정보 1개 등록 $DB->InsertArray('SYSTEM', array( diff --git a/f_retrival/_common.php b/f_retrival/_common.php index 96d7af6e..9ed1eefa 100644 --- a/f_retrival/_common.php +++ b/f_retrival/_common.php @@ -2,9 +2,9 @@ if(!defined('ROOT')){ define('ROOT', '.'); } -require(ROOT.'/f_config/config.php'); -require(ROOT.W.F_CONFIG.W.APP.PHP); -require(ROOT.W.F_FUNC.W.FUNC.PHP); +require_once(ROOT.'/f_config/config.php'); +require_once(ROOT.W.F_CONFIG.W.APP.PHP); +require_once(ROOT.W.F_FUNC.W.FUNC.PHP); CustomHeader(); diff --git a/i_entrance/Frame.php b/i_entrance/Frame.php index 4a80fa1e..106f7193 100644 --- a/i_entrance/Frame.php +++ b/i_entrance/Frame.php @@ -1,7 +1,7 @@ Select('NOTICE', 'SYSTEM', "NO='1'"); $system = $DB->Get($rs); diff --git a/i_entrance/_common.php b/i_entrance/_common.php index 9df83991..f57670c9 100644 --- a/i_entrance/_common.php +++ b/i_entrance/_common.php @@ -3,9 +3,9 @@ if(!defined('ROOT')){ define('ROOT', '..'); } -require(ROOT.'/f_config/config.php'); -require(ROOT.W.F_CONFIG.W.APP.PHP); -require(ROOT.W.F_FUNC.W.FUNC.PHP); +require_once(ROOT.'/f_config/config.php'); +require_once(ROOT.W.F_CONFIG.W.APP.PHP); +require_once(ROOT.W.F_FUNC.W.FUNC.PHP); CustomHeader(); diff --git a/i_entrance/adminInc.php b/i_entrance/adminInc.php index 6492a9c8..9fb243e1 100644 --- a/i_entrance/adminInc.php +++ b/i_entrance/adminInc.php @@ -1,7 +1,7 @@ diff --git a/i_entrance/adminPost.php b/i_entrance/adminPost.php index 584c1510..15e0875e 100644 --- a/i_entrance/adminPost.php +++ b/i_entrance/adminPost.php @@ -5,12 +5,12 @@ // $_POST['server'] : 서버 인덱스 // $_POST['select'] : 0: 폐쇄, 1: 리셋, 2: 오픈 -require('_common.php'); +require_once('_common.php'); require(ROOT.W.E_LIB.W.'util.php'); -require(ROOT.W.E_LIB.W.'util.php'); -require(ROOT.W.F_FUNC.W.'class._JSON.php'); -require(ROOT.W.F_CONFIG.W.DB.PHP); -require(ROOT.W.F_CONFIG.W.SESSION.PHP); +require(ROOT.W.E_LIB.W.'plates.php'); +require_once(ROOT.W.F_FUNC.W.'class._JSON.php'); +require_once(ROOT.W.F_CONFIG.W.DB.PHP); +require_once(ROOT.W.F_CONFIG.W.SESSION.PHP); function escapeIPv4($ip){ return str_replace('.', '\\.', $ip); @@ -25,38 +25,61 @@ $select = util::array_get($_POST['select'], ''); $rs = $DB->Select('GRADE', 'MEMBER', "NO='{$SESSION->NoMember()}'"); $member = $DB->Get($rs); -$response['result'] = 'FAIL'; -if($member['GRADE'] < 6) { - $response['result'] = 'FAIL'; - $response['msg'] = '운영자 권한이 없습니다.'; -} else { - if($action == 0) { - $DB->Update('SYSTEM', "NOTICE='{$notice}'", 'NO=1'); - $response['result'] = 'SUCCESS'; - } elseif($action == 1) { - $serverDir = $_serverDirs[$server]; +function doServerModeSet($server, $select, &$reason){ + global $_serverDirs; + $serverDir = $_serverDirs[$server]; - if($select == 0) { - rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir, realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_close'); - rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_rest', realpath(dirname(__FILE__)).W.ROOT.W.$serverDir); - $response['result'] = 'SUCCESS'; - } elseif($select == 1) { - if(file_exists(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_close'.W.D_SETTING.W.SET.PHP)){ - @unlink(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_close'.W.D_SETTING.W.SET.PHP); - } - - $response['installURL'] = ROOT.W."{$serverDir}_close/install.php"; - $response['result'] = 'SUCCESS'; - } elseif($select == 2) { - rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir, realpath(dirname(__FILE__)).W.ROOT.W.$serverDir."_rest"); - rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir."_close", realpath(dirname(__FILE__)).W.ROOT.W.$serverDir); - $response['result'] = 'SUCCESS'; + if($select == 0) { + rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir, realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_close'); + rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_rest', realpath(dirname(__FILE__)).W.ROOT.W.$serverDir); + $response['result'] = 'SUCCESS'; + } elseif($select == 1) { + if(file_exists(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_close'.W.D_SETTING.W.SET.PHP)){ + @unlink(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir.'_close'.W.D_SETTING.W.SET.PHP); } - } else { - $response['result'] = 'FAIL'; - $response['msg'] = '알 수 없는 명령입니다.'; + + $response['installURL'] = ROOT.W."{$serverDir}_close/install.php"; + $response['result'] = 'SUCCESS'; + } elseif($select == 2) { + rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir, realpath(dirname(__FILE__)).W.ROOT.W.$serverDir."_rest"); + rename(realpath(dirname(__FILE__)).W.ROOT.W.$serverDir."_close", realpath(dirname(__FILE__)).W.ROOT.W.$serverDir); + $response['result'] = 'SUCCESS'; } } +function doAdminPost($member, $action, $notice, $server, $select){ + $response['result'] = 'FAIL'; + if($member['GRADE'] < 6) { + $response['result'] = 'FAIL'; + $response['msg'] = '운영자 권한이 없습니다.'; + return $response; + } + + if($action == 0) { + $DB->Update('SYSTEM', "NOTICE='{$notice}'", 'NO=1'); + $response['result'] = 'SUCCESS'; + return $response; + } + + if($action == 1) { + $reason = ''; + if(doServerModeSet($server, $select)){ + $response['result'] = 'SUCCESS'; + } + else{ + $response['msg'] = $reason; + } + + return $response; + } + + $response['result'] = 'FAIL'; + $response['msg'] = '알 수 없는 명령입니다.'; + return $response; + +} + +$response = doAdminPost($member, $action, $notice, $server, $select); + sleep(1); echo json_encode($response); diff --git a/i_entrance/donation/Frame.php b/i_entrance/donation/Frame.php index c2bcae56..f7d5a032 100644 --- a/i_entrance/donation/Frame.php +++ b/i_entrance/donation/Frame.php @@ -1,5 +1,5 @@