From 9db7eddc68b3f5c993523a77308dccd9b1715014 Mon Sep 17 00:00:00 2001 From: Deep Shah Date: Thu, 17 Nov 2016 22:34:23 +0530 Subject: [PATCH] dotenv used for configurations --- .gitignore | 2 +- README.md | 6 +- UPGRADE.txt | 9 +- application/config/.env.example | 9 + application/config/config.php | 4 +- .../{database.php.tmpl => database.php} | 10 +- application/config/hooks.php | 8 +- composer.json | 3 +- composer.lock | 71 +++- vendor/autoload.php | 2 +- vendor/composer/autoload_psr4.php | 1 + vendor/composer/installed.json | 52 +++ vendor/vlucas/phpdotenv/LICENSE.txt | 32 ++ vendor/vlucas/phpdotenv/composer.json | 29 ++ vendor/vlucas/phpdotenv/src/Dotenv.php | 105 +++++ .../src/Exception/ExceptionInterface.php | 11 + .../Exception/InvalidCallbackException.php | 13 + .../src/Exception/InvalidFileException.php | 13 + .../src/Exception/InvalidPathException.php | 13 + .../src/Exception/ValidationException.php | 13 + vendor/vlucas/phpdotenv/src/Loader.php | 381 ++++++++++++++++++ vendor/vlucas/phpdotenv/src/Validator.php | 130 ++++++ 22 files changed, 887 insertions(+), 30 deletions(-) create mode 100644 application/config/.env.example rename application/config/{database.php.tmpl => database.php} (93%) create mode 100644 vendor/vlucas/phpdotenv/LICENSE.txt create mode 100644 vendor/vlucas/phpdotenv/composer.json create mode 100644 vendor/vlucas/phpdotenv/src/Dotenv.php create mode 100644 vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php create mode 100644 vendor/vlucas/phpdotenv/src/Exception/InvalidCallbackException.php create mode 100644 vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php create mode 100644 vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php create mode 100644 vendor/vlucas/phpdotenv/src/Exception/ValidationException.php create mode 100644 vendor/vlucas/phpdotenv/src/Loader.php create mode 100644 vendor/vlucas/phpdotenv/src/Validator.php diff --git a/.gitignore b/.gitignore index 2060815f8..c6e4d5649 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ node_modules tmp application/config/email.php -application/config/database.php application/sessions/* application/logs/* application/uploads/* @@ -22,3 +21,4 @@ git-svn-diff.py *~ *.~ *.log +.env diff --git a/README.md b/README.md index bf793d227..0fc210145 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,9 @@ Local install 1. Create/locate a new mysql database to install open source point of sale into 2. Execute the file database/database.sql to create the tables needed 3. unzip and upload Open Source Point of Sale files to web server -4. Copy application/config/database.php.tmpl to application/config/database.php -5. Modify application/config/database.php to connect to your database -6. Modify application/config/config.php encryption key with your own +4. Copy application/config/.env.example to application/config/.env +5. Modify database settings in application/config/.env to connect to your database +6. Modify encryption key in application/config/.env with your own 7. Go to your point of sale install public dir via the browser 8. LOGIN using * username: admin diff --git a/UPGRADE.txt b/UPGRADE.txt index 1a8317f1f..d4ba743c8 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -7,9 +7,8 @@ How to Upgrade 5. Run the database upgrade scripts from database/ dir (check which ones you need according to the version you are upgrading from) 6. Take the saved old config.php and upgrade the new config.php with any additional changes you made in the old. Take time to understand if new config rules require some changes (e.g. encryption keys) -7. Copy application/config/database.php.tmpl to application/config/database.php -8. Take the saved old database.php and change the new database.php to contain all the configuration you had in the old setup. +7. Take the saved old database.php and change the new database.php to contain all the configuration you had in the old setup. Please try not to use the old layout, use the new one and just copy the content of the config variables -9. Restore the content of the old uploads/ folder into public/uploads/ one -10. Once new code is in place, database is updated and config files are sorted you are good to start the new OSPOS -11. If any issue please check FAQ and/or GitHub issues as somebody else might have had your problem already or post a question +8. Restore the content of the old uploads/ folder into public/uploads/ one +9. Once new code is in place, database is updated and config files are sorted you are good to start the new OSPOS +10. If any issue please check FAQ and/or GitHub issues as somebody else might have had your problem already or post a question diff --git a/application/config/.env.example b/application/config/.env.example new file mode 100644 index 000000000..b23a6ba22 --- /dev/null +++ b/application/config/.env.example @@ -0,0 +1,9 @@ +CI_ENV="production" + +ENCRYPTION_KEY="" + +#Database Settings +DB_HOSTNAME="localhost" +DB_USERNAME="" +DB_PASSWORD="" +DB_DATABASE="" \ No newline at end of file diff --git a/application/config/config.php b/application/config/config.php index c8c1d6bb6..f8a9d3ec2 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -41,7 +41,7 @@ $config['ospos_xss_clean'] = TRUE; | Logs are stored in application/logs | */ -$config['db_log_enabled'] = FALSE; +$config['db_log_enabled'] = (ENVIRONMENT !== 'production'); /* |-------------------------------------------------------------------------- @@ -358,7 +358,7 @@ $config['cache_query_string'] = FALSE; | https://codeigniter.com/user_guide/libraries/encryption.html | */ -$config['encryption_key'] = ''; +$config['encryption_key'] = isset($_SERVER['ENCRYPTION_KEY']) ? $_SERVER['ENCRYPTION_KEY'] : ''; /* |-------------------------------------------------------------------------- diff --git a/application/config/database.php.tmpl b/application/config/database.php similarity index 93% rename from application/config/database.php.tmpl rename to application/config/database.php index 9f1cf6c2e..5f0d883ff 100644 --- a/application/config/database.php.tmpl +++ b/application/config/database.php @@ -75,10 +75,10 @@ $query_builder = TRUE; $db['default'] = array( 'dsn' => '', - 'hostname' => 'localhost', - 'username' => '', - 'password' => '', - 'database' => '', + 'hostname' => isset($_SERVER['DB_HOSTNAME']) ? $_SERVER['DB_HOSTNAME'] : '', + 'username' => isset($_SERVER['DB_USERNAME']) ? $_SERVER['DB_USERNAME'] : '', + 'password' => isset($_SERVER['DB_PASSWORD']) ? $_SERVER['DB_PASSWORD'] : '', + 'database' => isset($_SERVER['DB_DATABASE']) ? $_SERVER['DB_DATABASE'] : '', 'dbdriver' => 'mysqli', 'dbprefix' => 'ospos_', 'pconnect' => FALSE, @@ -93,4 +93,4 @@ $db['default'] = array( 'stricton' => FALSE, 'failover' => array(), 'save_queries' => TRUE -); +); \ No newline at end of file diff --git a/application/config/hooks.php b/application/config/hooks.php index 736e1c00e..037c85a6e 100644 --- a/application/config/hooks.php +++ b/application/config/hooks.php @@ -31,4 +31,10 @@ $hook['post_controller'] = array( 'function' => 'db_log_queries', 'filename' => 'db_log.php', 'filepath' => 'hooks' - ); \ No newline at end of file + ); + +$hook['pre_system'] = function() { + $config_path = APPPATH . 'config/'; + $dotenv = new Dotenv\Dotenv($config_path); + $dotenv->load(); +}; \ No newline at end of file diff --git a/composer.json b/composer.json index 88ad994b0..3ca280395 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,8 @@ "php": "^5.5 || ^7.0", "codeigniter/framework": "^3.1", "ins0/google-measurement-php-client": "dev-master#2b3aef2375837339f5b2bfe88e76994481f86264", - "dompdf/dompdf": "^0.7.0" + "dompdf/dompdf": "^0.7.0", + "vlucas/phpdotenv": "^2.4" }, "require-dev": { "mikey179/vfsStream": "1.1.*" diff --git a/composer.lock b/composer.lock index 381966c08..923e55489 100644 --- a/composer.lock +++ b/composer.lock @@ -4,29 +4,28 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2adedc5ea963263556434a21c7ac3dd1", - "content-hash": "265dc91d3b8d1bde2c83238b29c94c34", + "hash": "69501c018b057a249944072b172211c8", + "content-hash": "d4832d21deaba922e934cbc70b36be0f", "packages": [ { "name": "codeigniter/framework", - "version": "3.1.4", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/bcit-ci/CodeIgniter.git", - "reference": "873608df8be83420474e3cf9fc749a8ed12a6c09" + "reference": "2afa6b6b58a73fa26a7a93045ccb1fc8a087a141" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/873608df8be83420474e3cf9fc749a8ed12a6c09", - "reference": "873608df8be83420474e3cf9fc749a8ed12a6c09", + "url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/2afa6b6b58a73fa26a7a93045ccb1fc8a087a141", + "reference": "2afa6b6b58a73fa26a7a93045ccb1fc8a087a141", "shasum": "" }, "require": { "php": ">=5.2.4" }, "require-dev": { - "mikey179/vfsstream": "1.1.*", - "phpunit/phpunit": "4.* || 5.*" + "mikey179/vfsstream": "1.1.*" }, "suggest": { "paragonie/random_compat": "Provides better randomness in PHP 5.x" @@ -38,7 +37,7 @@ ], "description": "The CodeIgniter framework", "homepage": "https://codeigniter.com", - "time": "2017-03-20 15:51:08" + "time": "2016-10-28 15:13:14" }, { "name": "dompdf/dompdf", @@ -111,7 +110,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ins0/google-measurement-php-client/zipball/415cabca0c6d83cd0bd6a8ed6fb695b35f892018", + "url": "https://api.github.com/repos/ins0/google-measurement-php-client/zipball/2b3aef2375837339f5b2bfe88e76994481f86264", "reference": "2b3aef2375837339f5b2bfe88e76994481f86264", "shasum": "" }, @@ -221,6 +220,56 @@ "description": "A library to read, parse and export to PDF SVG files.", "homepage": "https://github.com/PhenX/php-svg-lib", "time": "2015-05-06 18:49:49" + }, + { + "name": "vlucas/phpdotenv", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c", + "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause-Attribution" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "time": "2016-09-01 10:05:43" } ], "packages-dev": [ @@ -263,7 +312,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^5.5 || ^7.0" + "php": ">=5.5" }, "platform-dev": [] } diff --git a/vendor/autoload.php b/vendor/autoload.php index f55b9817a..255f41407 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,6 @@ // autoload.php @generated by Composer -require_once __DIR__ . '/composer' . '/autoload_real.php'; +require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInit4fe73a8b8bda5131fdc94f85e4d193c1::getLoader(); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 84a101be9..7d52b46ca 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'), 'Dompdf\\' => array($vendorDir . '/dompdf/dompdf/src'), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 84e2eb9d5..8938591d8 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -255,5 +255,57 @@ ], "description": "The CodeIgniter framework", "homepage": "https://codeigniter.com" + }, + { + "name": "vlucas/phpdotenv", + "version": "v2.4.0", + "version_normalized": "2.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c", + "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "time": "2016-09-01 10:05:43", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause-Attribution" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ] } ] diff --git a/vendor/vlucas/phpdotenv/LICENSE.txt b/vendor/vlucas/phpdotenv/LICENSE.txt new file mode 100644 index 000000000..70ee47ea4 --- /dev/null +++ b/vendor/vlucas/phpdotenv/LICENSE.txt @@ -0,0 +1,32 @@ +The BSD 3-Clause License +http://opensource.org/licenses/BSD-3-Clause + +Copyright (c) 2013, Vance Lucas +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, +this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + * Neither the name of the Vance Lucas nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/vlucas/phpdotenv/composer.json b/vendor/vlucas/phpdotenv/composer.json new file mode 100644 index 000000000..2abf464f6 --- /dev/null +++ b/vendor/vlucas/phpdotenv/composer.json @@ -0,0 +1,29 @@ +{ + "name": "vlucas/phpdotenv", + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": ["env", "dotenv", "environment"], + "license" : "BSD-3-Clause-Attribution", + "authors" : [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + } +} diff --git a/vendor/vlucas/phpdotenv/src/Dotenv.php b/vendor/vlucas/phpdotenv/src/Dotenv.php new file mode 100644 index 000000000..e77802f57 --- /dev/null +++ b/vendor/vlucas/phpdotenv/src/Dotenv.php @@ -0,0 +1,105 @@ +filePath = $this->getFilePath($path, $file); + $this->loader = new Loader($this->filePath, true); + } + + /** + * Load environment file in given directory. + * + * @return array + */ + public function load() + { + return $this->loadData(); + } + + /** + * Load environment file in given directory. + * + * @return array + */ + public function overload() + { + return $this->loadData(true); + } + + /** + * Returns the full path to the file. + * + * @param string $path + * @param string $file + * + * @return string + */ + protected function getFilePath($path, $file) + { + if (!is_string($file)) { + $file = '.env'; + } + + $filePath = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$file; + + return $filePath; + } + + /** + * Actually load the data. + * + * @param bool $overload + * + * @return array + */ + protected function loadData($overload = false) + { + $this->loader = new Loader($this->filePath, !$overload); + + return $this->loader->load(); + } + + /** + * Required ensures that the specified variables exist, and returns a new validator object. + * + * @param string|string[] $variable + * + * @return \Dotenv\Validator + */ + public function required($variable) + { + return new Validator((array) $variable, $this->loader); + } +} diff --git a/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php b/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php new file mode 100644 index 000000000..781eeabef --- /dev/null +++ b/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php @@ -0,0 +1,11 @@ +filePath = $filePath; + $this->immutable = $immutable; + } + + /** + * Load `.env` file in given directory. + * + * @return array + */ + public function load() + { + $this->ensureFileIsReadable(); + + $filePath = $this->filePath; + $lines = $this->readLinesFromFile($filePath); + foreach ($lines as $line) { + if (!$this->isComment($line) && $this->looksLikeSetter($line)) { + $this->setEnvironmentVariable($line); + } + } + + return $lines; + } + + /** + * Ensures the given filePath is readable. + * + * @throws \Dotenv\Exception\InvalidPathException + * + * @return void + */ + protected function ensureFileIsReadable() + { + if (!is_readable($this->filePath) || !is_file($this->filePath)) { + throw new InvalidPathException(sprintf('Unable to read the environment file at %s.', $this->filePath)); + } + } + + /** + * Normalise the given environment variable. + * + * Takes value as passed in by developer and: + * - ensures we're dealing with a separate name and value, breaking apart the name string if needed, + * - cleaning the value of quotes, + * - cleaning the name of quotes, + * - resolving nested variables. + * + * @param string $name + * @param string $value + * + * @return array + */ + protected function normaliseEnvironmentVariable($name, $value) + { + list($name, $value) = $this->splitCompoundStringIntoParts($name, $value); + list($name, $value) = $this->sanitiseVariableName($name, $value); + list($name, $value) = $this->sanitiseVariableValue($name, $value); + + $value = $this->resolveNestedVariables($value); + + return array($name, $value); + } + + /** + * Process the runtime filters. + * + * Called from the `VariableFactory`, passed as a callback in `$this->loadFromFile()`. + * + * @param string $name + * @param string $value + * + * @return array + */ + public function processFilters($name, $value) + { + list($name, $value) = $this->splitCompoundStringIntoParts($name, $value); + list($name, $value) = $this->sanitiseVariableName($name, $value); + list($name, $value) = $this->sanitiseVariableValue($name, $value); + + return array($name, $value); + } + + /** + * Read lines from the file, auto detecting line endings. + * + * @param string $filePath + * + * @return array + */ + protected function readLinesFromFile($filePath) + { + // Read file into an array of lines with auto-detected line endings + $autodetect = ini_get('auto_detect_line_endings'); + ini_set('auto_detect_line_endings', '1'); + $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + ini_set('auto_detect_line_endings', $autodetect); + + return $lines; + } + + /** + * Determine if the line in the file is a comment, e.g. begins with a #. + * + * @param string $line + * + * @return bool + */ + protected function isComment($line) + { + return strpos(ltrim($line), '#') === 0; + } + + /** + * Determine if the given line looks like it's setting a variable. + * + * @param string $line + * + * @return bool + */ + protected function looksLikeSetter($line) + { + return strpos($line, '=') !== false; + } + + /** + * Split the compound string into parts. + * + * If the `$name` contains an `=` sign, then we split it into 2 parts, a `name` & `value` + * disregarding the `$value` passed in. + * + * @param string $name + * @param string $value + * + * @return array + */ + protected function splitCompoundStringIntoParts($name, $value) + { + if (strpos($name, '=') !== false) { + list($name, $value) = array_map('trim', explode('=', $name, 2)); + } + + return array($name, $value); + } + + /** + * Strips quotes from the environment variable value. + * + * @param string $name + * @param string $value + * + * @throws \Dotenv\Exception\InvalidFileException + * + * @return array + */ + protected function sanitiseVariableValue($name, $value) + { + $value = trim($value); + if (!$value) { + return array($name, $value); + } + + if ($this->beginsWithAQuote($value)) { // value starts with a quote + $quote = $value[0]; + $regexPattern = sprintf( + '/^ + %1$s # match a quote at the start of the value + ( # capturing sub-pattern used + (?: # we do not need to capture this + [^%1$s\\\\] # any character other than a quote or backslash + |\\\\\\\\ # or two backslashes together + |\\\\%1$s # or an escaped quote e.g \" + )* # as many characters that match the previous rules + ) # end of the capturing sub-pattern + %1$s # and the closing quote + .*$ # and discard any string after the closing quote + /mx', + $quote + ); + $value = preg_replace($regexPattern, '$1', $value); + $value = str_replace("\\$quote", $quote, $value); + $value = str_replace('\\\\', '\\', $value); + } else { + $parts = explode(' #', $value, 2); + $value = trim($parts[0]); + + // Unquoted values cannot contain whitespace + if (preg_match('/\s+/', $value) > 0) { + throw new InvalidFileException('Dotenv values containing spaces must be surrounded by quotes.'); + } + } + + return array($name, trim($value)); + } + + /** + * Resolve the nested variables. + * + * Look for {$varname} patterns in the variable value and replace with an + * existing environment variable. + * + * @param string $value + * + * @return mixed + */ + protected function resolveNestedVariables($value) + { + if (strpos($value, '$') !== false) { + $loader = $this; + $value = preg_replace_callback( + '/\${([a-zA-Z0-9_]+)}/', + function ($matchedPatterns) use ($loader) { + $nestedVariable = $loader->getEnvironmentVariable($matchedPatterns[1]); + if ($nestedVariable === null) { + return $matchedPatterns[0]; + } else { + return $nestedVariable; + } + }, + $value + ); + } + + return $value; + } + + /** + * Strips quotes and the optional leading "export " from the environment variable name. + * + * @param string $name + * @param string $value + * + * @return array + */ + protected function sanitiseVariableName($name, $value) + { + $name = trim(str_replace(array('export ', '\'', '"'), '', $name)); + + return array($name, $value); + } + + /** + * Determine if the given string begins with a quote. + * + * @param string $value + * + * @return bool + */ + protected function beginsWithAQuote($value) + { + return strpbrk($value[0], '"\'') !== false; + } + + /** + * Search the different places for environment variables and return first value found. + * + * @param string $name + * + * @return string|null + */ + public function getEnvironmentVariable($name) + { + switch (true) { + case array_key_exists($name, $_ENV): + return $_ENV[$name]; + case array_key_exists($name, $_SERVER): + return $_SERVER[$name]; + default: + $value = getenv($name); + return $value === false ? null : $value; // switch getenv default to null + } + } + + /** + * Set an environment variable. + * + * This is done using: + * - putenv, + * - $_ENV, + * - $_SERVER. + * + * The environment variable value is stripped of single and double quotes. + * + * @param string $name + * @param string|null $value + * + * @return void + */ + public function setEnvironmentVariable($name, $value = null) + { + list($name, $value) = $this->normaliseEnvironmentVariable($name, $value); + + // Don't overwrite existing environment variables if we're immutable + // Ruby's dotenv does this with `ENV[key] ||= value`. + if ($this->immutable && $this->getEnvironmentVariable($name) !== null) { + return; + } + + // If PHP is running as an Apache module and an existing + // Apache environment variable exists, overwrite it + if (function_exists('apache_getenv') && function_exists('apache_setenv') && apache_getenv($name)) { + apache_setenv($name, $value); + } + + if (function_exists('putenv')) { + putenv("$name=$value"); + } + + $_ENV[$name] = $value; + $_SERVER[$name] = $value; + } + + /** + * Clear an environment variable. + * + * This is not (currently) used by Dotenv but is provided as a utility + * method for 3rd party code. + * + * This is done using: + * - putenv, + * - unset($_ENV, $_SERVER). + * + * @param string $name + * + * @see setEnvironmentVariable() + * + * @return void + */ + public function clearEnvironmentVariable($name) + { + // Don't clear anything if we're immutable. + if ($this->immutable) { + return; + } + + if (function_exists('putenv')) { + putenv($name); + } + + unset($_ENV[$name], $_SERVER[$name]); + } +} diff --git a/vendor/vlucas/phpdotenv/src/Validator.php b/vendor/vlucas/phpdotenv/src/Validator.php new file mode 100644 index 000000000..aa3cb0e40 --- /dev/null +++ b/vendor/vlucas/phpdotenv/src/Validator.php @@ -0,0 +1,130 @@ +variables = $variables; + $this->loader = $loader; + + $this->assertCallback( + function ($value) { + return $value !== null; + }, + 'is missing' + ); + } + + /** + * Assert that each variable is not empty. + * + * @return \Dotenv\Validator + */ + public function notEmpty() + { + return $this->assertCallback( + function ($value) { + return strlen(trim($value)) > 0; + }, + 'is empty' + ); + } + + /** + * Assert that each specified variable is an integer. + * + * @return \Dotenv\Validator + */ + public function isInteger() + { + return $this->assertCallback( + function ($value) { + return ctype_digit($value); + }, + 'is not an integer' + ); + } + + /** + * Assert that each variable is amongst the given choices. + * + * @param string[] $choices + * + * @return \Dotenv\Validator + */ + public function allowedValues(array $choices) + { + return $this->assertCallback( + function ($value) use ($choices) { + return in_array($value, $choices); + }, + 'is not an allowed value' + ); + } + + /** + * Assert that the callback returns true for each variable. + * + * @param callable $callback + * @param string $message + * + * @throws \Dotenv\Exception\InvalidCallbackException|\Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + protected function assertCallback($callback, $message = 'failed callback assertion') + { + if (!is_callable($callback)) { + throw new InvalidCallbackException('The provided callback must be callable.'); + } + + $variablesFailingAssertion = array(); + foreach ($this->variables as $variableName) { + $variableValue = $this->loader->getEnvironmentVariable($variableName); + if (call_user_func($callback, $variableValue) === false) { + $variablesFailingAssertion[] = $variableName." $message"; + } + } + + if (count($variablesFailingAssertion) > 0) { + throw new ValidationException(sprintf( + 'One or more environment variables failed assertions: %s.', + implode(', ', $variablesFailingAssertion) + )); + } + + return $this; + } +}