diff options
263 files changed, 1722 insertions, 891 deletions
diff --git a/.gitattributes b/.gitattributes index 51fea4174..b4f0b6cbb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -18,5 +18,6 @@ readme.rst tests/codeigniter/ export-ignore tests/travis/ export-ignore -# User Guide Source Files -user_guide_src +# User Guide source files and compiled files +user_guide_src export-ignore +user_guide export-ignore diff --git a/.github/workflows/test-phpunit.yml b/.github/workflows/test-phpunit.yml new file mode 100644 index 000000000..a0765e883 --- /dev/null +++ b/.github/workflows/test-phpunit.yml @@ -0,0 +1,119 @@ +name: PHPUnit + +on: [push, pull_request] + +jobs: + tests: + runs-on: ubuntu-18.04 + if: "!contains(github.event.head_commit.message, '[ci skip]')" + env: + PHP_INI_VALUES: assert.exception=1, zend.assertions=1 + + strategy: + fail-fast: false + matrix: + php: [ '8.1', '8.0', '7.4', '7.3', '7.2', '7.1', '7.0', '5.6', '5.5', '5.4'] + DB: [ 'pdo/mysql', 'pdo/pgsql', 'pdo/sqlite', 'mysqli', 'pgsql', 'sqlite' ] + compiler: [ default ] + include: + - php: '8.1' + DB: 'pdo/mysql' + compiler: jit + - php: '8.1' + DB: 'pdo/pgsql' + compiler: jit + - php: '8.1' + DB: 'pdo/sqlite' + compiler: jit + - php: '8.1' + DB: 'mysqli' + compiler: jit + - php: '8.1' + DB: 'pgsql' + compiler: jit + - php: '8.1' + DB: 'sqlite' + compiler: jit + - php: '8.0' + DB: 'pdo/mysql' + compiler: jit + - php: '8.0' + DB: 'pdo/pgsql' + compiler: jit + - php: '8.0' + DB: 'pdo/sqlite' + compiler: jit + - php: '8.0' + DB: 'mysqli' + compiler: jit + - php: '8.0' + DB: 'pgsql' + compiler: jit + - php: '8.0' + DB: 'sqlite' + compiler: jit + - php: '5.6' + DB: 'mysql' + compiler: default + - php: '5.5' + DB: 'mysql' + compiler: default + - php: '5.4' + DB: 'mysql' + compiler: default + + services: + postgres: + image: postgres:12 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: ci_test + ports: + - 5432:5432 + options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3 + + mysql: + image: mysql:5.7 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: true + MYSQL_USER: travis + MYSQL_PASSWORD: travis + MYSQL_DATABASE: ci_test + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Override PHP ini values for JIT compiler + if: matrix.compiler == 'jit' + run: echo "PHP_INI_VALUES::assert.exception=1, zend.assertions=1, opcache.enable=1, opcache.enable_cli=1, opcache.optimization_level=-1, opcache.jit=1255, opcache.jit_buffer_size=64M" >> $GITHUB_ENV + + - name: Install PHP${{ matrix.php }} - DB ${{ matrix.DB }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer, pecl + extensions: imagick, sqlite3, pgsql, mysqli, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, mbstring + ini-values: ${{ env.PHP_INI_VALUES }} + coverage: xdebug + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache composer dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + - name: Install composer dependencies + run: composer install --no-progress --prefer-dist --optimize-autoloader + + - name: PHPUnit Test + run: | + php -d zend.enable_gc=0 -d date.timezone=UTC -d mbstring.func_overload=7 -d mbstring.internal_encoding=UTF-8 vendor/bin/phpunit --coverage-text --configuration tests/travis/${{ matrix.DB }}.phpunit.xml + env: + XDEBUG_MODE: coverage diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 963d2cd2f..000000000 --- a/.travis.yml +++ /dev/null @@ -1,59 +0,0 @@ -language: php -dist: precise - -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - 7.3 - - master - - hhvm - -env: - - DB=mysql - - DB=mysqli - - DB=pgsql - - DB=sqlite - - DB=pdo/mysql - - DB=pdo/pgsql - - DB=pdo/sqlite - -sudo: false - -before_script: - - sh -c "composer install --dev --no-progress" - - sh -c "if [ '$DB' = 'pgsql' ] || [ '$DB' = 'pdo/pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS ci_test;' -U postgres; fi" - - sh -c "if [ '$DB' = 'pgsql' ] || [ '$DB' = 'pdo/pgsql' ]; then psql -c 'create database ci_test;' -U postgres; fi" - - sh -c "if [ '$DB' = 'mysql' ] || [ '$DB' = 'mysqli' ] || [ '$DB' = 'pdo/mysql' ]; then mysql -e 'create database IF NOT EXISTS ci_test;'; fi" - -script: php -d zend.enable_gc=0 -d date.timezone=UTC -d mbstring.func_overload=7 -d mbstring.internal_encoding=UTF-8 vendor/bin/phpunit --coverage-text --configuration tests/travis/$DB.phpunit.xml - -matrix: - allow_failures: - - php: hhvm - - php: master - exclude: - - php: hhvm - env: DB=pgsql - - php: hhvm - env: DB=pdo/pgsql - - php: 7.0 - env: DB=mysql - - php: 7.1 - env: DB=mysql - - php: 7.2 - env: DB=mysql - - php: 7.3 - env: DB=mysql - - php: master - env: DB=mysql - -branches: - only: - - develop - - 3.0-stable - - 3.1-stable - - /^feature\/.+$/ diff --git a/application/cache/index.html b/application/cache/index.html index b702fbc39..bcb7cae34 100644 --- a/application/cache/index.html +++ b/application/cache/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/config/config.php b/application/config/config.php index 6710a4b88..83d8802fb 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -13,9 +13,9 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | | WARNING: You MUST set this value! | -| If it is not set, then CodeIgniter will try guess the protocol and path -| your installation, but due to security concerns the hostname will be set -| to $_SERVER['SERVER_ADDR'] if available, or localhost otherwise. +| If it is not set, then CodeIgniter will try to guess the protocol and +| path to your installation, but due to security concerns the hostname will +| be set to $_SERVER['SERVER_ADDR'] if available, or localhost otherwise. | The auto-detection mechanism exists only for convenience during | development and MUST NOT be used in production! | @@ -62,7 +62,7 @@ $config['uri_protocol'] = 'REQUEST_URI'; | This option allows you to add a suffix to all URLs generated by CodeIgniter. | For more information please see the user guide: | -| https://codeigniter.com/user_guide/general/urls.html +| https://codeigniter.com/userguide3/general/urls.html | | Note: This option is ignored for CLI requests. */ @@ -112,8 +112,8 @@ $config['enable_hooks'] = FALSE; | This item allows you to set the filename/classname prefix when extending | native libraries. For more information please see the user guide: | -| https://codeigniter.com/user_guide/general/core_classes.html -| https://codeigniter.com/user_guide/general/creating_libraries.html +| https://codeigniter.com/userguide3/general/core_classes.html +| https://codeigniter.com/userguide3/general/creating_libraries.html | */ $config['subclass_prefix'] = 'MY_'; @@ -322,7 +322,7 @@ $config['cache_query_string'] = FALSE; | If you use the Encryption class, you must set an encryption key. | See the user guide for more info. | -| https://codeigniter.com/user_guide/libraries/encryption.html +| https://codeigniter.com/userguide3/libraries/encryption.html | */ $config['encryption_key'] = ''; @@ -340,6 +340,10 @@ $config['encryption_key'] = ''; | | The session cookie name, must contain only [0-9a-z_-] characters | +| 'sess_samesite' +| +| Session cookie SameSite attribute: Lax (default), Strict or None +| | 'sess_expiration' | | The number of SECONDS you want the session to last. @@ -380,6 +384,7 @@ $config['encryption_key'] = ''; */ $config['sess_driver'] = 'files'; $config['sess_cookie_name'] = 'ci_session'; +$config['sess_samesite'] = 'Lax'; $config['sess_expiration'] = 7200; $config['sess_save_path'] = NULL; $config['sess_match_ip'] = FALSE; @@ -396,6 +401,7 @@ $config['sess_regenerate_destroy'] = FALSE; | 'cookie_path' = Typically will be a forward slash | 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists. | 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) +| 'cookie_samesite' = Cookie's samesite attribute (Lax, Strict or None) | | Note: These settings (with the exception of 'cookie_prefix' and | 'cookie_httponly') will also affect sessions. @@ -406,6 +412,7 @@ $config['cookie_domain'] = ''; $config['cookie_path'] = '/'; $config['cookie_secure'] = FALSE; $config['cookie_httponly'] = FALSE; +$config['cookie_samesite'] = 'Lax'; /* |-------------------------------------------------------------------------- diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php index 995f48304..0231f3592 100644 --- a/application/config/foreign_chars.php +++ b/application/config/foreign_chars.php @@ -22,10 +22,10 @@ $foreign_characters = array( '/б/' => 'b', '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', '/ç|ć|ĉ|ċ|č/' => 'c', - '/Д/' => 'D', - '/д/' => 'd', - '/Ð|Ď|Đ|Δ/' => 'Dj', - '/ð|ď|đ|δ/' => 'dj', + '/Д|Δ/' => 'D', + '/д|δ/' => 'd', + '/Ð|Ď|Đ/' => 'Dj', + '/ð|ď|đ/' => 'dj', '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E', '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e', '/Ф/' => 'F', @@ -38,6 +38,8 @@ $foreign_characters = array( '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i', '/Ĵ/' => 'J', '/ĵ/' => 'j', + '/Θ/' => 'TH', + '/θ/' => 'th', '/Ķ|Κ|К/' => 'K', '/ķ|κ|к/' => 'k', '/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L', @@ -54,8 +56,8 @@ $foreign_characters = array( '/ŕ|ŗ|ř|ρ|р/' => 'r', '/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S', '/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's', - '/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T', - '/ț|ţ|ť|ŧ|т/' => 't', + '/Ț|Ţ|Ť|Ŧ|Τ|Т/' => 'T', + '/ț|ţ|ť|ŧ|τ|т/' => 't', '/Þ|þ/' => 'th', '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U', '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u', @@ -65,6 +67,10 @@ $foreign_characters = array( '/в/' => 'v', '/Ŵ/' => 'W', '/ŵ/' => 'w', + '/Φ/' => 'F', + '/φ/' => 'f', + '/Χ/' => 'CH', + '/χ/' => 'ch', '/Ź|Ż|Ž|Ζ|З/' => 'Z', '/ź|ż|ž|ζ|з/' => 'z', '/Æ|Ǽ/' => 'AE', @@ -73,10 +79,15 @@ $foreign_characters = array( '/ij/' => 'ij', '/Œ/' => 'OE', '/ƒ/' => 'f', + '/Ξ/' => 'KS', '/ξ/' => 'ks', + '/Π/' => 'P', '/π/' => 'p', + '/Β/' => 'V', '/β/' => 'v', + '/Μ/' => 'M', '/μ/' => 'm', + '/Ψ/' => 'PS', '/ψ/' => 'ps', '/Ё/' => 'Yo', '/ё/' => 'yo', diff --git a/application/config/hooks.php b/application/config/hooks.php index a8f38a5dc..79c5c162f 100644 --- a/application/config/hooks.php +++ b/application/config/hooks.php @@ -8,6 +8,6 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | This file lets you define "hooks" to extend CI without hacking the core | files. Please see the user guide for info: | -| https://codeigniter.com/user_guide/general/hooks.html +| https://codeigniter.com/userguide3/general/hooks.html | */ diff --git a/application/config/index.html b/application/config/index.html index b702fbc39..bcb7cae34 100644 --- a/application/config/index.html +++ b/application/config/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/config/memcached.php b/application/config/memcached.php index 5c23b39c1..65a149617 100644 --- a/application/config/memcached.php +++ b/application/config/memcached.php @@ -7,7 +7,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | ------------------------------------------------------------------------- | Your Memcached servers can be specified below. | -| See: https://codeigniter.com/user_guide/libraries/caching.html#memcached +| See: https://codeigniter.com/userguide3/libraries/caching.html#memcached | */ $config = array( diff --git a/application/config/mimes.php b/application/config/mimes.php index 0ec9db0a0..b2e989fea 100644 --- a/application/config/mimes.php +++ b/application/config/mimes.php @@ -5,7 +5,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | ------------------------------------------------------------------- | MIME TYPES | ------------------------------------------------------------------- -| This file contains an array of mime types. It is used by the +| This file contains an array of mime types. It is used by the | Upload class to help identify allowed file types. | */ @@ -85,9 +85,11 @@ return array( 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), - 'png' => array('image/png', 'image/x-png'), + 'png' => array('image/png', 'image/x-png'), 'tiff' => 'image/tiff', 'tif' => 'image/tiff', + 'heic' => 'image/heic', + 'heif' => 'image/heif', 'css' => array('text/css', 'text/plain'), 'html' => array('text/html', 'text/plain'), 'htm' => array('text/html', 'text/plain'), @@ -140,7 +142,7 @@ return array( 'f4v' => array('video/mp4', 'video/x-f4v'), 'flv' => 'video/x-flv', 'webm' => 'video/webm', - 'aac' => 'audio/x-acc', + 'aac' => array('audio/x-aac', 'audio/aac'), 'm4u' => 'application/vnd.mpegurl', 'm3u' => 'text/plain', 'xspf' => 'application/xspf+xml', @@ -160,7 +162,7 @@ return array( 'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'), 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), - 'svg' => array('image/svg+xml', 'application/xml', 'text/xml'), + 'svg' => array('image/svg+xml', 'image/svg', 'application/xml', 'text/xml'), 'vcf' => 'text/x-vcard', 'srt' => array('text/srt', 'text/plain'), 'vtt' => array('text/vtt', 'text/plain'), diff --git a/application/config/profiler.php b/application/config/profiler.php index 3db22e39c..3436e931e 100644 --- a/application/config/profiler.php +++ b/application/config/profiler.php @@ -9,6 +9,6 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | data are displayed when the Profiler is enabled. | Please see the user guide for info: | -| https://codeigniter.com/user_guide/general/profiling.html +| https://codeigniter.com/userguide3/general/profiling.html | */ diff --git a/application/config/routes.php b/application/config/routes.php index 8ebf62bfa..4c70d921c 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -19,7 +19,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | | Please see the user guide for complete details: | -| https://codeigniter.com/user_guide/general/routing.html +| https://codeigniter.com/userguide3/general/routing.html | | ------------------------------------------------------------------------- | RESERVED ROUTES diff --git a/application/config/user_agents.php b/application/config/user_agents.php index 9aa403eca..21251f46f 100644 --- a/application/config/user_agents.php +++ b/application/config/user_agents.php @@ -152,6 +152,12 @@ $mobiles = array( 'wii' => 'Nintendo Wii', 'open web' => 'Open Web', 'openweb' => 'OpenWeb', + 'meizu' => 'Meizu', + 'huawei' => 'Huawei', + 'xiaomi' => 'Xiaomi', + 'oppo' => 'Oppo', + 'vivo' => 'Vivo', + 'infinix' => 'Infinix', // Operating Systems 'android' => 'Android', @@ -212,5 +218,6 @@ $robots = array( 'curious george' => 'Curious George', 'ia_archiver' => 'Alexa Crawler', 'MJ12bot' => 'Majestic-12', - 'Uptimebot' => 'Uptimebot' + 'Uptimebot' => 'Uptimebot', + 'UptimeRobot' => 'UptimeRobot' ); diff --git a/application/controllers/Welcome.php b/application/controllers/Welcome.php index 9213c0cf5..5f82771b6 100644 --- a/application/controllers/Welcome.php +++ b/application/controllers/Welcome.php @@ -16,7 +16,7 @@ class Welcome extends CI_Controller { * * So any other public methods not prefixed with an underscore will * map to /index.php/welcome/<method_name> - * @see https://codeigniter.com/user_guide/general/urls.html + * @see https://codeigniter.com/userguide3/general/urls.html */ public function index() { diff --git a/application/controllers/index.html b/application/controllers/index.html index b702fbc39..bcb7cae34 100644 --- a/application/controllers/index.html +++ b/application/controllers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/core/index.html b/application/core/index.html index b702fbc39..bcb7cae34 100644 --- a/application/core/index.html +++ b/application/core/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/helpers/index.html b/application/helpers/index.html index b702fbc39..bcb7cae34 100644 --- a/application/helpers/index.html +++ b/application/helpers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/hooks/index.html b/application/hooks/index.html index b702fbc39..bcb7cae34 100644 --- a/application/hooks/index.html +++ b/application/hooks/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/index.html b/application/index.html index b702fbc39..bcb7cae34 100644 --- a/application/index.html +++ b/application/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/language/english/index.html b/application/language/english/index.html index b702fbc39..bcb7cae34 100644 --- a/application/language/english/index.html +++ b/application/language/english/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/language/index.html b/application/language/index.html index b702fbc39..bcb7cae34 100644 --- a/application/language/index.html +++ b/application/language/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/libraries/index.html b/application/libraries/index.html index b702fbc39..bcb7cae34 100644 --- a/application/libraries/index.html +++ b/application/libraries/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/logs/index.html b/application/logs/index.html index b702fbc39..bcb7cae34 100644 --- a/application/logs/index.html +++ b/application/logs/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/models/index.html b/application/models/index.html index b702fbc39..bcb7cae34 100644 --- a/application/models/index.html +++ b/application/models/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/third_party/index.html b/application/third_party/index.html index b702fbc39..bcb7cae34 100644 --- a/application/third_party/index.html +++ b/application/third_party/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/views/errors/cli/index.html b/application/views/errors/cli/index.html index b702fbc39..bcb7cae34 100644 --- a/application/views/errors/cli/index.html +++ b/application/views/errors/cli/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/views/errors/html/index.html b/application/views/errors/html/index.html index b702fbc39..bcb7cae34 100644 --- a/application/views/errors/html/index.html +++ b/application/views/errors/html/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/views/errors/index.html b/application/views/errors/index.html index b702fbc39..bcb7cae34 100644 --- a/application/views/errors/index.html +++ b/application/views/errors/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/views/index.html b/application/views/index.html index b702fbc39..bcb7cae34 100644 --- a/application/views/index.html +++ b/application/views/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php index bc5b441a9..dae768bc8 100644 --- a/application/views/welcome_message.php +++ b/application/views/welcome_message.php @@ -27,7 +27,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); } a:hover { - color: #97310e; + color: #97310e; } h1 { @@ -69,8 +69,8 @@ defined('BASEPATH') OR exit('No direct script access allowed'); } p { - margin: 0 0 10px; - padding:0; + margin: 0 0 10px; + padding:0; } p.footer { diff --git a/build-release.sh b/build-release.sh index 6b3b31d12..30967fc2e 100755 --- a/build-release.sh +++ b/build-release.sh @@ -47,7 +47,7 @@ fi echo "Running tests ..." -cd tests/ +php -d zend.enable_gc=0 -d date.timezone=UTC -d mbstring.func_overload=7 -d mbstring.internal_encoding=UTF-8 vendor/bin/phpunit --coverage-text --configuration tests/travis/sqlite.phpunit.xml phpunit if [ $? -ne 0 ] @@ -56,7 +56,6 @@ then exit 1 fi -cd .. cd user_guide_src/ echo "" diff --git a/composer.json b/composer.json index 6769e9545..f5b4e8db4 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,20 @@ "suggest": { "paragonie/random_compat": "Provides better randomness in PHP 5.x" }, + "scripts": { + "test:coverage": [ + "@putenv XDEBUG_MODE=coverage", + "phpunit --color=always --coverage-text --configuration tests/travis/sqlite.phpunit.xml" + ], + "post-install-cmd": [ + "sed -i s/name{0}/name[0]/ vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php" + ], + "post-update-cmd": [ + "sed -i s/name{0}/name[0]/ vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php" + ] + }, "require-dev": { - "mikey179/vfsStream": "1.1.*", - "phpunit/phpunit": "4.* || 5.*" + "mikey179/vfsstream": "1.6.*", + "phpunit/phpunit": "4.* || 5.* || 9.*" } } diff --git a/contributing.md b/contributing.md index 65ff9501a..206784d1f 100644 --- a/contributing.md +++ b/contributing.md @@ -1,6 +1,5 @@ # Contributing to CodeIgniter - CodeIgniter 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 [CodeIgniter repository](https://github.com/bcit-ci/CodeIgniter) on GitHub. Issues are a quick way to point out a bug. If you find a bug or documentation error in CodeIgniter then please check a few things first: @@ -20,7 +19,7 @@ for us to maintain quality of the code-base. ### PHP Style -All code must meet the [Style Guide](https://codeigniter.com/user_guide/general/styleguide.html), which is +All code must meet the [Style Guide](https://codeigniter.com/userguide3/general/styleguide.html), which is essentially the [Allman indent style](https://en.wikipedia.org/wiki/Indent_style#Allman_style), underscores and readable operators. This makes certain that all code is the same format as the existing code and means it will be as readable as possible. ### Documentation @@ -59,7 +58,6 @@ If you are using [Tower](https://www.git-tower.com/) there is a "Sign-Off" check By signing your work in this manner, you certify to a "Developer's Certificate of Origin". The current version of this certificate is in the `DCO.txt` file in the root of this repository. - ## How-to Guide There are two ways to make changes, the easy way and the hard way. Either way you will need to [create a GitHub account](https://github.com/signup/free). @@ -68,15 +66,15 @@ Easy way GitHub allows in-line editing of files for making simple typo changes a Hard way The best way to contribute is to "clone" your fork of CodeIgniter to your development area. That sounds like some jargon, but "forking" on GitHub means "making a copy of that repo to your account" and "cloning" means "copying that code to your environment so you can work on it". -1. Set up Git (Windows, Mac & Linux) -2. Go to the CodeIgniter repo -3. Fork it -4. Clone your CodeIgniter repo: git@github.com:<your-name>/CodeIgniter.git -5. Checkout the "develop" branch At this point you are ready to start making changes. +1. [Set up Git](https://help.github.com/en/articles/set-up-git) (Windows, Mac & Linux) +2. Go to the [CodeIgniter repo](https://github.com/bcit-ci/CodeIgniter) +3. [Fork it](https://help.github.com/en/articles/fork-a-repo) +4. [Clone](https://help.github.com/en/articles/fetching-a-remote#clone) your forked CodeIgniter repo: git@github.com:<your-name>/CodeIgniter.git. +5. Checkout the "develop" branch. At this point you are ready to start making changes. 6. Fix existing bugs on the Issue tracker after taking a look to see nobody else is working on them. -7. Commit the files -8. Push your develop branch to your fork -9. Send a pull request [http://help.github.com/send-pull-requests/](http://help.github.com/send-pull-requests/) +7. [Commit](https://help.github.com/en/articles/adding-a-file-to-a-repository-using-the-command-line) the files +8. [Push](https://help.github.com/en/articles/pushing-to-a-remote) your develop branch to your fork +9. [Send a pull request](https://help.github.com/en/articles/creating-a-pull-request) The Reactor Engineers will now be alerted about the change and at least one of the team will respond. If your change fails to meet the guidelines it will be bounced, or feedback will be provided to help you improve it. @@ -103,7 +103,7 @@ switch (ENVIRONMENT) * use an absolute (full) server path. * For more info please see the user guide: * - * https://codeigniter.com/user_guide/general/managing_apps.html + * https://codeigniter.com/userguide3/general/managing_apps.html * * NO TRAILING SLASH! */ diff --git a/readme.rst b/readme.rst index 3e1382fbd..fa6d242e8 100644 --- a/readme.rst +++ b/readme.rst @@ -39,7 +39,7 @@ issues, as well as missing features. Installation ************ -Please see the `installation section <https://codeigniter.com/user_guide/installation/index.html>`_ +Please see the `installation section <https://codeigniter.com/userguide3/installation/index.html>`_ of the CodeIgniter User Guide. ******* @@ -54,6 +54,7 @@ Resources ********* - `User Guide <https://codeigniter.com/docs>`_ +- `Contributing Guide <https://github.com/bcit-ci/CodeIgniter/blob/develop/contributing.md>`_ - `Language File Translations <https://github.com/bcit-ci/codeigniter3-translations>`_ - `Community Forums <https://forum.codeigniter.com/>`_ - `Community Wiki <https://github.com/bcit-ci/CodeIgniter/wiki>`_ diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php index 014220a44..0b48d4d0c 100644 --- a/system/core/Benchmark.php +++ b/system/core/Benchmark.php @@ -47,7 +47,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/benchmark.html + * @link https://codeigniter.com/userguide3/libraries/benchmark.html */ class CI_Benchmark { diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 9bf60a4ac..704539ef4 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage CodeIgniter * @category Front-controller * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/ + * @link https://codeigniter.com/userguide3/ */ /** @@ -383,7 +383,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ReflectionMethod::isConstructor() is the ONLY reliable check, * knowing which method will be executed as a constructor. */ - elseif ( ! is_callable(array($class, $method))) + else { $reflection = new ReflectionMethod($class, $method); if ( ! $reflection->isPublic() OR $reflection->isConstructor()) diff --git a/system/core/Common.php b/system/core/Common.php index fadc0a0b1..52cb7114e 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage CodeIgniter * @category Common Functions * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/ + * @link https://codeigniter.com/userguide3/ */ // ------------------------------------------------------------------------ @@ -569,7 +569,7 @@ if ( ! function_exists('set_status_header')) return; } - $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2'), TRUE)) + $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0'), TRUE)) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; header($server_protocol.' '.$code.' '.$text, TRUE, $code); } @@ -782,11 +782,9 @@ if ( ! function_exists('_stringify_attributes')) */ function _stringify_attributes($attributes, $js = FALSE) { - $atts = NULL; - if (empty($attributes)) { - return $atts; + return NULL; } if (is_string($attributes)) @@ -796,6 +794,7 @@ if ( ! function_exists('_stringify_attributes')) $attributes = (array) $attributes; + $atts = ''; foreach ($attributes as $key => $val) { $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"'; diff --git a/system/core/Config.php b/system/core/Config.php index 13cc087d0..e6eb0ad95 100644 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/config.html + * @link https://codeigniter.com/userguide3/libraries/config.html */ class CI_Config { diff --git a/system/core/Controller.php b/system/core/Controller.php index 2bb157802..ac27989f3 100644 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -47,7 +47,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/general/controllers.html + * @link https://codeigniter.com/userguide3/general/controllers.html */ class CI_Controller { @@ -59,6 +59,13 @@ class CI_Controller { private static $instance; /** + * CI_Loader + * + * @var CI_Loader + */ + public $load; + + /** * Class constructor * * @return void diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index e8e7f6c29..92c635f97 100644 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Exceptions * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/exceptions.html + * @link https://codeigniter.com/userguide3/libraries/exceptions.html */ class CI_Exceptions { diff --git a/system/core/Hooks.php b/system/core/Hooks.php index 353e22e21..864c59d25 100644 --- a/system/core/Hooks.php +++ b/system/core/Hooks.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/general/hooks.html + * @link https://codeigniter.com/userguide3/general/hooks.html */ class CI_Hooks { diff --git a/system/core/Input.php b/system/core/Input.php index 053970b01..0beb252ed 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Input * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/input.html + * @link https://codeigniter.com/userguide3/libraries/input.html */ class CI_Input { @@ -300,14 +300,15 @@ class CI_Input { * @param string $prefix Cookie name prefix * @param bool $secure Whether to only transfer cookies via SSL * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) + * @param string $samesite SameSite attribute * @return void */ - public function set_cookie($name, $value = '', $expire = 0, $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL) + public function set_cookie($name, $value = '', $expire = 0, $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL, $samesite = NULL) { if (is_array($name)) { // always leave 'name' in last place, as the loop will break otherwise, due to $$item - foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item) + foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name', 'samesite') as $item) { if (isset($name[$item])) { @@ -348,7 +349,47 @@ class CI_Input { $expire = ($expire > 0) ? time() + $expire : 0; } - setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly); + isset($samesite) OR $samesite = config_item('cookie_samesite'); + if (isset($samesite)) + { + $samesite = ucfirst(strtolower($samesite)); + in_array($samesite, array('Lax', 'Strict', 'None'), TRUE) OR $samesite = 'Lax'; + } + else + { + $samesite = 'Lax'; + } + + if ($samesite === 'None' && ! $secure) + { + log_message('error', $name.' cookie sent with SameSite=None, but without Secure attribute.'); + } + + if ( ! is_php('7.3')) + { + $maxage = $expire - time(); + if ($maxage < 1) + { + $maxage = 0; + } + + $cookie_header = 'Set-Cookie: '.$prefix.$name.'='.rawurlencode($value); + $cookie_header .= ($expire === 0 ? '' : '; Expires='.gmdate('D, d-M-Y H:i:s T', $expire)).'; Max-Age='.$maxage; + $cookie_header .= '; Path='.$path.($domain !== '' ? '; Domain='.$domain : ''); + $cookie_header .= ($secure ? '; Secure' : '').($httponly ? '; HttpOnly' : '').'; SameSite='.$samesite; + header($cookie_header); + return; + } + + $setcookie_options = array( + 'expires' => $expire, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure, + 'httponly' => $httponly, + 'samesite' => $samesite, + ); + setcookie($prefix.$name, $value, $setcookie_options); } // -------------------------------------------------------------------- @@ -508,7 +549,7 @@ class CI_Input { $which = FILTER_FLAG_IPV6; break; default: - $which = NULL; + $which = 0; break; } diff --git a/system/core/Lang.php b/system/core/Lang.php index 2c8654dcf..5cfeaf37e 100644 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Language * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/language.html + * @link https://codeigniter.com/userguide3/libraries/language.html */ class CI_Lang { diff --git a/system/core/Loader.php b/system/core/Loader.php index 0710b1611..d9a1539aa 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Loader * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/loader.html + * @link https://codeigniter.com/userguide3/libraries/loader.html */ class CI_Loader { diff --git a/system/core/Log.php b/system/core/Log.php index 01407cfcf..8ce1b83a2 100644 --- a/system/core/Log.php +++ b/system/core/Log.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Logging * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/general/errors.html + * @link https://codeigniter.com/userguide3/general/errors.html */ class CI_Log { @@ -129,7 +129,7 @@ class CI_Log { { $config =& get_config(); - isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); $this->_log_path = ($config['log_path'] !== '') ? rtrim($config['log_path'], '/\\').DIRECTORY_SEPARATOR : APPPATH.'logs'.DIRECTORY_SEPARATOR; @@ -259,11 +259,11 @@ class CI_Log { * @param string $level The error level * @param string $date Formatted date string * @param string $message The log message - * @return string Formatted log line with a new line character '\n' at the end + * @return string Formatted log line with a new line character at the end */ protected function _format_line($level, $date, $message) { - return $level.' - '.$date.' --> '.$message."\n"; + return $level.' - '.$date.' --> '.$message.PHP_EOL; } // -------------------------------------------------------------------- diff --git a/system/core/Model.php b/system/core/Model.php index 4c497d21e..585148298 100644 --- a/system/core/Model.php +++ b/system/core/Model.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/config.html + * @link https://codeigniter.com/userguide3/libraries/config.html */ class CI_Model { diff --git a/system/core/Output.php b/system/core/Output.php index f386d3ad4..7f153ef77 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Output * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/output.html + * @link https://codeigniter.com/userguide3/libraries/output.html */ class CI_Output { @@ -145,7 +145,7 @@ class CI_Output { && extension_loaded('zlib') ); - isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); // Get mime types for later $this->mimes =& get_mimes(); @@ -299,10 +299,14 @@ class CI_Output { */ public function get_header($header) { - // Combine headers already sent with our batched headers + // We only need [x][0] from our multi-dimensional array + $header_lines = array_map(function ($headers) + { + return array_shift($headers); + }, $this->headers); + $headers = array_merge( - // We only need [x][0] from our multi-dimensional array - array_map('array_shift', $this->headers), + $header_lines, headers_list() ); diff --git a/system/core/Router.php b/system/core/Router.php index dcdd1ed1f..0d9662559 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/general/routing.html + * @link https://codeigniter.com/userguide3/general/routing.html */ class CI_Router { diff --git a/system/core/Security.php b/system/core/Security.php index 27b4db69d..aac308194 100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Security * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/security.html + * @link https://codeigniter.com/userguide3/libraries/security.html */ class CI_Security { @@ -229,6 +229,7 @@ class CI_Security { // Check CSRF token validity, but don't error on mismatch just yet - we'll want to regenerate $valid = isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) + && is_string($_POST[$this->_csrf_token_name]) && is_string($_COOKIE[$this->_csrf_cookie_name]) && hash_equals($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]); // We kill this since we're done and we don't want to pollute the _POST array @@ -272,15 +273,35 @@ class CI_Security { return FALSE; } - setcookie( - $this->_csrf_cookie_name, - $this->_csrf_hash, - $expire, - config_item('cookie_path'), - config_item('cookie_domain'), - $secure_cookie, - config_item('cookie_httponly') - ); + if (is_php('7.3')) + { + setcookie( + $this->_csrf_cookie_name, + $this->_csrf_hash, + array( + 'expires' => $expire, + 'path' => config_item('cookie_path'), + 'domain' => config_item('cookie_domain'), + 'secure' => $secure_cookie, + 'httponly' => config_item('cookie_httponly'), + 'samesite' => 'Strict' + ) + ); + } + else + { + $domain = trim(config_item('cookie_domain')); + header('Set-Cookie: '.$this->_csrf_cookie_name.'='.$this->_csrf_hash + .'; Expires='.gmdate('D, d-M-Y H:i:s T', $expire) + .'; Max-Age='.$this->_csrf_expire + .'; Path='.rawurlencode(config_item('cookie_path')) + .($domain === '' ? '' : '; Domain='.$domain) + .($secure_cookie ? '; Secure' : '') + .(config_item('cookie_httponly') ? '; HttpOnly' : '') + .'; SameSite=Strict' + ); + } + log_message('info', 'CSRF cookie sent'); return $this; diff --git a/system/core/URI.php b/system/core/URI.php index 3670ef29d..9bef22d6c 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category URI * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/uri.html + * @link https://codeigniter.com/userguide3/libraries/uri.html */ class CI_URI { diff --git a/system/core/Utf8.php b/system/core/Utf8.php index 39954c428..5e18f07bb 100644 --- a/system/core/Utf8.php +++ b/system/core/Utf8.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category UTF-8 * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/utf8.html + * @link https://codeigniter.com/userguide3/libraries/utf8.html */ class CI_Utf8 { diff --git a/system/core/compat/hash.php b/system/core/compat/hash.php index 8d905ad68..f1829a3a6 100644 --- a/system/core/compat/hash.php +++ b/system/core/compat/hash.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/ + * @link https://codeigniter.com/userguide3/ * @link https://secure.php.net/hash */ diff --git a/system/core/compat/index.html b/system/core/compat/index.html index b702fbc39..bcb7cae34 100644 --- a/system/core/compat/index.html +++ b/system/core/compat/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/core/compat/mbstring.php b/system/core/compat/mbstring.php index 41c86376c..af73b8cce 100644 --- a/system/core/compat/mbstring.php +++ b/system/core/compat/mbstring.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/ + * @link https://codeigniter.com/userguide3/ * @link https://secure.php.net/mbstring */ diff --git a/system/core/compat/password.php b/system/core/compat/password.php index f6517b46d..306300eda 100644 --- a/system/core/compat/password.php +++ b/system/core/compat/password.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/ + * @link https://codeigniter.com/userguide3/ * @link https://secure.php.net/password */ diff --git a/system/core/compat/standard.php b/system/core/compat/standard.php index 31c39ca25..21feeb04e 100644 --- a/system/core/compat/standard.php +++ b/system/core/compat/standard.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/ + * @link https://codeigniter.com/userguide3/ */ // ------------------------------------------------------------------------ diff --git a/system/core/index.html b/system/core/index.html index b702fbc39..bcb7cae34 100644 --- a/system/core/index.html +++ b/system/core/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/DB.php b/system/database/DB.php index dddcf758c..c42bb6b91 100644 --- a/system/database/DB.php +++ b/system/database/DB.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ * * @param string|string[] $params * @param bool $query_builder_override @@ -185,7 +185,7 @@ function &DB($params = '', $query_builder_override = NULL) elseif ( ! class_exists('CI_DB', FALSE)) { /** - * @ignore + * @ignore */ class CI_DB extends CI_DB_driver { } } diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php index afcfc4cf9..2467a30f2 100644 --- a/system/database/DB_cache.php +++ b/system/database/DB_cache.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_Cache { diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index b4f16b905..a213d5cba 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ abstract class CI_DB_driver { @@ -829,6 +829,18 @@ abstract class CI_DB_driver { // -------------------------------------------------------------------- /** + * Returns TRUE if a transaction is currently active + * + * @return bool + */ + public function trans_active() + { + return (bool) $this->_trans_depth; + } + + // -------------------------------------------------------------------- + + /** * Begin Transaction * * @param bool $test_mode diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php index b086f7a81..ce9b30d82 100644 --- a/system/database/DB_forge.php +++ b/system/database/DB_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ abstract class CI_DB_forge { diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index 296a2eed5..5480ed44f 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ abstract class CI_DB_query_builder extends CI_DB_driver { @@ -526,7 +526,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { public function join($table, $cond, $type = '', $escape = NULL) { $type = trim(strtoupper($type).' JOIN'); - preg_match('#^(NATURAL\s+)?((LEFT|RIGHT)\s+)?((INNER|OUTER)\s+)?JOIN$#', $type) OR $type = 'JOIN'; + preg_match('#^(NATURAL\s+)?((LEFT|RIGHT|FULL)\s+)?((INNER|OUTER)\s+)?JOIN$#', $type) OR $type = 'JOIN'; // Extract any aliases that might exist. We use this information // in the protect_identifiers to know whether to add a table prefix @@ -717,7 +717,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function where_in($key = NULL, $values = NULL, $escape = NULL) + public function where_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_where', $key, $values, FALSE, 'AND ', $escape); } @@ -735,7 +735,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function or_where_in($key = NULL, $values = NULL, $escape = NULL) + public function or_where_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_where', $key, $values, FALSE, 'OR ', $escape); } @@ -753,7 +753,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function where_not_in($key = NULL, $values = NULL, $escape = NULL) + public function where_not_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_where', $key, $values, TRUE, 'AND ', $escape); } @@ -771,7 +771,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function or_where_not_in($key = NULL, $values = NULL, $escape = NULL) + public function or_where_not_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_where', $key, $values, TRUE, 'OR ', $escape); } @@ -789,7 +789,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function having_in($key = NULL, $values = NULL, $escape = NULL) + public function having_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_having', $key, $values, FALSE, 'AND ', $escape); } @@ -807,7 +807,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function or_having_in($key = NULL, $values = NULL, $escape = NULL) + public function or_having_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_having', $key, $values, FALSE, 'OR ', $escape); } @@ -825,7 +825,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function having_not_in($key = NULL, $values = NULL, $escape = NULL) + public function having_not_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_having', $key, $values, TRUE, 'AND ', $escape); } @@ -843,7 +843,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - public function or_having_not_in($key = NULL, $values = NULL, $escape = NULL) + public function or_having_not_in($key, array $values, $escape = NULL) { return $this->_wh_in('qb_having', $key, $values, TRUE, 'OR ', $escape); } @@ -870,18 +870,18 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * @param bool $escape * @return CI_DB_query_builder */ - protected function _wh_in($qb_key, $key = NULL, $values = NULL, $not = FALSE, $type = 'AND ', $escape = NULL) + protected function _wh_in($qb_key, $key, array $values, $not = FALSE, $type = 'AND ', $escape = NULL) { $qb_cache_key = ($qb_key === 'qb_having') ? 'qb_cache_having' : 'qb_cache_where'; - if ($key === NULL OR $values === NULL) + if (empty($key) OR ! is_string($key)) { - return $this; + throw new InvalidArgumentException(sprintf('%s() expects $key to be a non-empty string', debug_backtrace(0, 2)[1]['function'])); } - if ( ! is_array($values)) + if (empty($values)) { - $values = array($values); + throw new InvalidArgumentException(sprintf('%s() expects $values to be a non-empty array', debug_backtrace(0, 2)[1]['function'])); } is_bool($escape) OR $escape = $this->_protect_identifiers; @@ -1191,7 +1191,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { /** * GROUP BY * - * @param string $by + * @param mixed $by * @param bool $escape * @return CI_DB_query_builder */ @@ -1484,7 +1484,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $qb_cache_orderby = $this->qb_cache_orderby; $this->qb_orderby = $this->qb_cache_orderby = array(); - $result = ($this->qb_distinct === TRUE OR ! empty($this->qb_groupby) OR ! empty($this->qb_cache_groupby) OR $this->qb_limit OR $this->qb_offset) + $result = ($this->qb_distinct === TRUE OR ! empty($this->qb_groupby) OR ! empty($this->qb_cache_groupby) OR ! empty($this->qb_having) OR $this->qb_limit OR $this->qb_offset) ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results") : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows'))); diff --git a/system/database/DB_result.php b/system/database/DB_result.php index 0dbac1633..b481de475 100644 --- a/system/database/DB_result.php +++ b/system/database/DB_result.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_result { @@ -381,7 +381,7 @@ class CI_DB_result { */ public function custom_row_object($n, $type) { - isset($this->custom_result_object[$type]) OR $this->custom_result_object($type); + isset($this->custom_result_object[$type]) OR $this->custom_result_object[$type] = $this->custom_result_object($type); if (count($this->custom_result_object[$type]) === 0) { diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php index c2edfc9f3..a1450f099 100644 --- a/system/database/DB_utility.php +++ b/system/database/DB_utility.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ abstract class CI_DB_utility { diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php index b3b436fed..b133c1025 100644 --- a/system/database/drivers/cubrid/cubrid_driver.php +++ b/system/database/drivers/cubrid/cubrid_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_cubrid_driver extends CI_DB { diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php index 69b53dd49..8c7cd52db 100644 --- a/system/database/drivers/cubrid/cubrid_forge.php +++ b/system/database/drivers/cubrid/cubrid_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_cubrid_forge extends CI_DB_forge { diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php index 75d702558..988fba6d8 100644 --- a/system/database/drivers/cubrid/cubrid_result.php +++ b/system/database/drivers/cubrid/cubrid_result.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_cubrid_result extends CI_DB_result { diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php index ccf794b75..d860bee08 100644 --- a/system/database/drivers/cubrid/cubrid_utility.php +++ b/system/database/drivers/cubrid/cubrid_utility.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author Esen Sagynov - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_cubrid_utility extends CI_DB_utility { diff --git a/system/database/drivers/cubrid/index.html b/system/database/drivers/cubrid/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/cubrid/index.html +++ b/system/database/drivers/cubrid/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php index 27e87d427..85badc2fe 100644 --- a/system/database/drivers/ibase/ibase_driver.php +++ b/system/database/drivers/ibase/ibase_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_ibase_driver extends CI_DB { diff --git a/system/database/drivers/ibase/ibase_forge.php b/system/database/drivers/ibase/ibase_forge.php index 29a3acf69..940080320 100644 --- a/system/database/drivers/ibase/ibase_forge.php +++ b/system/database/drivers/ibase/ibase_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_ibase_forge extends CI_DB_forge { @@ -140,7 +140,7 @@ class CI_DB_ibase_forge extends CI_DB_forge { * @return string|string[] */ protected function _alter_table($alter_type, $table, $field) - { + { if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) { return parent::_alter_table($alter_type, $table, $field); @@ -183,7 +183,7 @@ class CI_DB_ibase_forge extends CI_DB_forge { } return $sqls; - } + } // -------------------------------------------------------------------- diff --git a/system/database/drivers/ibase/ibase_result.php b/system/database/drivers/ibase/ibase_result.php index 86530973b..c3e4ed7a6 100644 --- a/system/database/drivers/ibase/ibase_result.php +++ b/system/database/drivers/ibase/ibase_result.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_ibase_result extends CI_DB_result { diff --git a/system/database/drivers/ibase/ibase_utility.php b/system/database/drivers/ibase/ibase_utility.php index a80874924..1fc34254e 100644 --- a/system/database/drivers/ibase/ibase_utility.php +++ b/system/database/drivers/ibase/ibase_utility.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_ibase_utility extends CI_DB_utility { diff --git a/system/database/drivers/ibase/index.html b/system/database/drivers/ibase/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/ibase/index.html +++ b/system/database/drivers/ibase/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/index.html b/system/database/drivers/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/index.html +++ b/system/database/drivers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/mssql/index.html b/system/database/drivers/mssql/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/mssql/index.html +++ b/system/database/drivers/mssql/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php index 51352e314..a20b01237 100644 --- a/system/database/drivers/mssql/mssql_driver.php +++ b/system/database/drivers/mssql/mssql_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mssql_driver extends CI_DB { diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php index 07b93c24d..f79416031 100644 --- a/system/database/drivers/mssql/mssql_forge.php +++ b/system/database/drivers/mssql/mssql_forge.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mssql_forge extends CI_DB_forge { diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php index 5d7d3bedc..6cae3050d 100644 --- a/system/database/drivers/mssql/mssql_result.php +++ b/system/database/drivers/mssql/mssql_result.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mssql_result extends CI_DB_result { diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php index 5c9941aca..1aad485b7 100644 --- a/system/database/drivers/mssql/mssql_utility.php +++ b/system/database/drivers/mssql/mssql_utility.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mssql_utility extends CI_DB_utility { diff --git a/system/database/drivers/mysql/index.html b/system/database/drivers/mysql/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/mysql/index.html +++ b/system/database/drivers/mysql/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php index 388a46c82..61337cdd3 100644 --- a/system/database/drivers/mysql/mysql_driver.php +++ b/system/database/drivers/mysql/mysql_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysql_driver extends CI_DB { @@ -382,7 +382,7 @@ class CI_DB_mysql_driver extends CI_DB { */ protected function _list_tables($prefix_limit = FALSE) { - $sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database); + $sql = 'SHOW TABLES FROM '.$this->_escape_char.$this->database.$this->_escape_char; if ($prefix_limit !== FALSE && $this->dbprefix !== '') { diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php index b69aa36b4..e59366bed 100644 --- a/system/database/drivers/mysql/mysql_forge.php +++ b/system/database/drivers/mysql/mysql_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysql_forge extends CI_DB_forge { diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php index 842d7d399..461f643df 100644 --- a/system/database/drivers/mysql/mysql_result.php +++ b/system/database/drivers/mysql/mysql_result.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysql_result extends CI_DB_result { diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php index a54892975..6089da533 100644 --- a/system/database/drivers/mysql/mysql_utility.php +++ b/system/database/drivers/mysql/mysql_utility.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysql_utility extends CI_DB_utility { diff --git a/system/database/drivers/mysqli/index.html b/system/database/drivers/mysqli/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/mysqli/index.html +++ b/system/database/drivers/mysqli/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index 4f0c28e78..dc3d0cf48 100644 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysqli_driver extends CI_DB { @@ -116,6 +116,13 @@ class CI_DB_mysqli_driver extends CI_DB { */ public function db_connect($persistent = FALSE) { + // PHP 8.1 changes default error handling mode from silent to exceptions - reverse that + if (is_php('8.1')) + { + $mysqli_driver = new mysqli_driver(); + $mysqli_driver->report_mode = MYSQLI_REPORT_OFF; + } + // Do we have a socket path? if ($this->hostname[0] === '/') { @@ -423,7 +430,7 @@ class CI_DB_mysqli_driver extends CI_DB { */ protected function _list_tables($prefix_limit = FALSE) { - $sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database); + $sql = 'SHOW TABLES FROM '.$this->_escape_char.$this->database.$this->_escape_char; if ($prefix_limit !== FALSE && $this->dbprefix !== '') { diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php index 92b1e94d1..b67fe56cb 100644 --- a/system/database/drivers/mysqli/mysqli_forge.php +++ b/system/database/drivers/mysqli/mysqli_forge.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysqli_forge extends CI_DB_forge { diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php index 0856eca4e..7e4e45f39 100644 --- a/system/database/drivers/mysqli/mysqli_result.php +++ b/system/database/drivers/mysqli/mysqli_result.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysqli_result extends CI_DB_result { diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php index 606424655..75e35d116 100644 --- a/system/database/drivers/mysqli/mysqli_utility.php +++ b/system/database/drivers/mysqli/mysqli_utility.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_mysqli_utility extends CI_DB_utility { diff --git a/system/database/drivers/oci8/index.html b/system/database/drivers/oci8/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/oci8/index.html +++ b/system/database/drivers/oci8/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php index a825c4a38..16646efea 100644 --- a/system/database/drivers/oci8/oci8_driver.php +++ b/system/database/drivers/oci8/oci8_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ /** @@ -69,20 +69,6 @@ class CI_DB_oci8_driver extends CI_DB { public $dbdriver = 'oci8'; /** - * Statement ID - * - * @var resource - */ - public $stmt_id; - - /** - * Cursor ID - * - * @var resource - */ - public $curs_id; - - /** * Commit mode flag * * @var int @@ -99,15 +85,27 @@ class CI_DB_oci8_driver extends CI_DB { */ public $limit_used = FALSE; - // -------------------------------------------------------------------- + /** + * Error cache + * + * Cached error info about failed queries. + * Used so that statement IDs can be released immediately. + * + * @var array|false + */ + protected $_error = FALSE; /** - * Reset $stmt_id flag + * Affected rows * - * Used by stored_procedure() to prevent _execute() from - * re-setting the statement ID. + * Cached result of oci_num_rows(). + * Used so that statement IDs can be released immediately. + * + * @var int|false */ - protected $_reset_stmt_id = TRUE; + protected $_affected_rows = FALSE; + + // -------------------------------------------------------------------- /** * List of reserved identifiers @@ -277,104 +275,19 @@ class CI_DB_oci8_driver extends CI_DB { /* Oracle must parse the query before it is run. All of the actions with * the query are based on the statement id returned by oci_parse(). */ - if ($this->_reset_stmt_id === TRUE) - { - $this->stmt_id = oci_parse($this->conn_id, $sql); - } - - oci_set_prefetch($this->stmt_id, 1000); - return oci_execute($this->stmt_id, $this->commit_mode); - } - - // -------------------------------------------------------------------- - - /** - * Get cursor. Returns a cursor from the database - * - * @return resource - */ - public function get_cursor() - { - return $this->curs_id = oci_new_cursor($this->conn_id); - } - - // -------------------------------------------------------------------- - - /** - * Stored Procedure. Executes a stored procedure - * - * @param string package name in which the stored procedure is in - * @param string stored procedure name to execute - * @param array parameters - * @return mixed - * - * params array keys - * - * KEY OPTIONAL NOTES - * name no the name of the parameter should be in :<param_name> format - * value no the value of the parameter. If this is an OUT or IN OUT parameter, - * this should be a reference to a variable - * type yes the type of the parameter - * length yes the max size of the parameter - */ - public function stored_procedure($package, $procedure, array $params) - { - if ($package === '' OR $procedure === '') - { - log_message('error', 'Invalid query: '.$package.'.'.$procedure); - return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; - } + $this->result_id = oci_parse($this->conn_id, $sql); + oci_set_prefetch($this->result_id, 1000); + $result = oci_execute($this->result_id, $this->commit_mode); + $this->_error = oci_error($this->result_id); + $this->is_write_type($sql) && $this->_affected_rows = oci_num_rows($this->result_id); - // Build the query string - $sql = 'BEGIN '.$package.'.'.$procedure.'('; - - $have_cursor = FALSE; - foreach ($params as $param) + if ($this->is_write_type($sql) OR $result === FALSE) { - $sql .= $param['name'].','; - - if (isset($param['type']) && $param['type'] === OCI_B_CURSOR) - { - $have_cursor = TRUE; - } + oci_free_statement($this->result_id); + return $result; } - $sql = trim($sql, ',').'); END;'; - - $this->_reset_stmt_id = FALSE; - $this->stmt_id = oci_parse($this->conn_id, $sql); - $this->_bind_params($params); - $result = $this->query($sql, FALSE, $have_cursor); - $this->_reset_stmt_id = TRUE; - return $result; - } - - // -------------------------------------------------------------------- - /** - * Bind parameters - * - * @param array $params - * @return void - */ - protected function _bind_params($params) - { - if ( ! is_array($params) OR ! is_resource($this->stmt_id)) - { - return; - } - - foreach ($params as $param) - { - foreach (array('name', 'value', 'type', 'length') as $val) - { - if ( ! isset($param[$val])) - { - $param[$val] = ''; - } - } - - oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']); - } + return $this->result_id; } // -------------------------------------------------------------------- @@ -426,7 +339,7 @@ class CI_DB_oci8_driver extends CI_DB { */ public function affected_rows() { - return oci_num_rows($this->stmt_id); + return $this->_affected_rows; } // -------------------------------------------------------------------- @@ -559,18 +472,15 @@ class CI_DB_oci8_driver extends CI_DB { */ public function error() { + if ( ! empty($this->_error)) + { + return $this->_error; + } + // oci_error() returns an array that already contains // 'code' and 'message' keys, but it can return false // if there was no error .... - if (is_resource($this->curs_id)) - { - $error = oci_error($this->curs_id); - } - elseif (is_resource($this->stmt_id)) - { - $error = oci_error($this->stmt_id); - } - elseif (is_resource($this->conn_id)) + if (is_resource($this->conn_id)) { $error = oci_error($this->conn_id); } @@ -682,6 +592,11 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _close() { + if (is_resource($this->result_id)) + { + oci_free_statement($this->result_id); + } + oci_close($this->conn_id); } diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php index 20217f2b8..7dc7b2ade 100644 --- a/system/database/drivers/oci8/oci8_forge.php +++ b/system/database/drivers/oci8/oci8_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_oci8_forge extends CI_DB_forge { @@ -81,6 +81,13 @@ class CI_DB_oci8_forge extends CI_DB_forge { */ protected $_unsigned = FALSE; + /** + * NULL value representation in CREATE/ALTER TABLE statements + * + * @var string + */ + protected $_null = 'NULL'; + // -------------------------------------------------------------------- /** @@ -152,7 +159,29 @@ class CI_DB_oci8_forge extends CI_DB_forge { */ protected function _attr_auto_increment(&$attributes, &$field) { - // Not supported - sequences and triggers must be used instead + if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'number') !== FALSE && version_compare($this->db->version(), '12.1', '>=')) + { + $field['auto_increment'] = ' GENERATED ALWAYS AS IDENTITY'; + } + } + + // -------------------------------------------------------------------- + + /** + * Process column + * + * @param array $field + * @return string + */ + protected function _process_column($field) + { + return $this->db->escape_identifiers($field['name']) + .' '.$field['type'].$field['length'] + .$field['unsigned'] + .$field['default'] + .$field['auto_increment'] + .$field['null'] + .$field['unique']; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php index 3da49aa76..0d57d9428 100644 --- a/system/database/drivers/oci8/oci8_result.php +++ b/system/database/drivers/oci8/oci8_result.php @@ -44,25 +44,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_oci8_result extends CI_DB_result { /** - * Statement ID - * - * @var resource - */ - public $stmt_id; - - /** - * Cursor ID - * - * @var resource - */ - public $curs_id; - - /** * Limit used flag * * @var bool @@ -88,11 +74,10 @@ class CI_DB_oci8_result extends CI_DB_result { { parent::__construct($driver_object); - $this->stmt_id = $driver_object->stmt_id; - $this->curs_id = $driver_object->curs_id; + $this->result_id = $driver_object->result_id; $this->limit_used = $driver_object->limit_used; $this->commit_mode =& $driver_object->commit_mode; - $driver_object->stmt_id = FALSE; + $driver_object->result_id = FALSE; } // -------------------------------------------------------------------- @@ -104,7 +89,7 @@ class CI_DB_oci8_result extends CI_DB_result { */ public function num_fields() { - $count = oci_num_fields($this->stmt_id); + $count = oci_num_fields($this->result_id); // if we used a limit we subtract it return ($this->limit_used) ? $count - 1 : $count; @@ -124,7 +109,7 @@ class CI_DB_oci8_result extends CI_DB_result { $field_names = array(); for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++) { - $field_names[] = oci_field_name($this->stmt_id, $c); + $field_names[] = oci_field_name($this->result_id, $c); } return $field_names; } @@ -144,9 +129,9 @@ class CI_DB_oci8_result extends CI_DB_result { for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++) { $F = new stdClass(); - $F->name = oci_field_name($this->stmt_id, $c); - $F->type = oci_field_type($this->stmt_id, $c); - $F->max_length = oci_field_size($this->stmt_id, $c); + $F->name = oci_field_name($this->result_id, $c); + $F->type = oci_field_type($this->result_id, $c); + $F->max_length = oci_field_size($this->result_id, $c); $retval[] = $F; } @@ -168,17 +153,6 @@ class CI_DB_oci8_result extends CI_DB_result { oci_free_statement($this->result_id); $this->result_id = FALSE; } - - if (is_resource($this->stmt_id)) - { - oci_free_statement($this->stmt_id); - } - - if (is_resource($this->curs_id)) - { - oci_cancel($this->curs_id); - $this->curs_id = NULL; - } } // -------------------------------------------------------------------- @@ -192,8 +166,7 @@ class CI_DB_oci8_result extends CI_DB_result { */ protected function _fetch_assoc() { - $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id; - return oci_fetch_assoc($id); + return oci_fetch_assoc($this->result_id); } // -------------------------------------------------------------------- @@ -208,9 +181,7 @@ class CI_DB_oci8_result extends CI_DB_result { */ protected function _fetch_object($class_name = 'stdClass') { - $row = ($this->curs_id) - ? oci_fetch_object($this->curs_id) - : oci_fetch_object($this->stmt_id); + $row = oci_fetch_object($this->result_id); if ($class_name === 'stdClass' OR ! $row) { @@ -226,4 +197,18 @@ class CI_DB_oci8_result extends CI_DB_result { return $class_name; } + // -------------------------------------------------------------------- + + /** + * Destructor + * + * Attempt to free remaining statement IDs. + * + * @see https://github.com/bcit-ci/CodeIgniter/pull/5896 + * @return void + */ + public function __destruct() + { + $this->free_result(); + } } diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php index 3a7261c15..a0a9c2c95 100644 --- a/system/database/drivers/oci8/oci8_utility.php +++ b/system/database/drivers/oci8/oci8_utility.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_oci8_utility extends CI_DB_utility { diff --git a/system/database/drivers/odbc/index.html b/system/database/drivers/odbc/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/odbc/index.html +++ b/system/database/drivers/odbc/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php index 72289bf9f..f02da4d13 100644 --- a/system/database/drivers/odbc/odbc_driver.php +++ b/system/database/drivers/odbc/odbc_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_odbc_driver extends CI_DB_driver { diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php index a06ac4b9e..6aff76941 100644 --- a/system/database/drivers/odbc/odbc_result.php +++ b/system/database/drivers/odbc/odbc_result.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_odbc_result extends CI_DB_result { diff --git a/system/database/drivers/pdo/index.html b/system/database/drivers/pdo/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/pdo/index.html +++ b/system/database/drivers/pdo/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php index c5d120fd3..b2178b684 100644 --- a/system/database/drivers/pdo/pdo_driver.php +++ b/system/database/drivers/pdo/pdo_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_driver extends CI_DB { @@ -131,6 +131,14 @@ class CI_DB_pdo_driver extends CI_DB { $this->options[PDO::ATTR_PERSISTENT] = TRUE; } + // From PHP8.0, default PDO::ATTR_ERRMODE is changed + // from PDO::ERRMODE_SILENT to PDO::ERRMODE_EXCEPTION + // as https://wiki.php.net/rfc/pdo_default_errmode + if ( ! isset($this->options[PDO::ATTR_ERRMODE])) + { + $this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT; + } + try { return new PDO($this->dsn, $this->username, $this->password, $this->options); @@ -302,7 +310,7 @@ class CI_DB_pdo_driver extends CI_DB { $error['code'] = isset($pdo_error[1]) ? $pdo_error[0].'/'.$pdo_error[1] : $pdo_error[0]; if (isset($pdo_error[2])) { - $error['message'] = $pdo_error[2]; + $error['message'] = $pdo_error[2]; } return $error; @@ -326,4 +334,17 @@ class CI_DB_pdo_driver extends CI_DB { return 'TRUNCATE TABLE '.$table; } + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @return void + */ + protected function _close() + { + $this->result_id = FALSE; + $this->conn_id = FALSE; + } + } diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php index 03c0f9f9d..f0f56c3f7 100644 --- a/system/database/drivers/pdo/pdo_result.php +++ b/system/database/drivers/pdo/pdo_result.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_result extends CI_DB_result { @@ -133,7 +133,7 @@ class CI_DB_pdo_result extends CI_DB_result { $retval[$i] = new stdClass(); $retval[$i]->name = $field['name']; - $retval[$i]->type = $field['native_type']; + $retval[$i]->type = isset($field['native_type']) ? $field['native_type'] : null; $retval[$i]->max_length = ($field['len'] > 0) ? $field['len'] : NULL; $retval[$i]->primary_key = (int) ( ! empty($field['flags']) && in_array('primary_key', $field['flags'], TRUE)); } diff --git a/system/database/drivers/pdo/subdrivers/index.html b/system/database/drivers/pdo/subdrivers/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/pdo/subdrivers/index.html +++ b/system/database/drivers/pdo/subdrivers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php index 2e39bb236..63f6f84b5 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_4d_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php index 306150b9a..f7fa54316 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_4d_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php index 9a6b643fc..05887bcfb 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_cubrid_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php index f2ee3f5ea..32ccc8cca 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_cubrid_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php index 09dbdf08f..06f03ccce 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php index f38ac99ba..692b76d89 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_dblib_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php index 2c49f1216..4e4dd27e1 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_firebird_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php index 54752f153..c3d25b6f6 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_firebird_forge extends CI_DB_pdo_forge { @@ -126,7 +126,7 @@ class CI_DB_pdo_firebird_forge extends CI_DB_pdo_forge { * @return string|string[] */ protected function _alter_table($alter_type, $table, $field) - { + { if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) { return parent::_alter_table($alter_type, $table, $field); @@ -150,7 +150,7 @@ class CI_DB_pdo_firebird_forge extends CI_DB_pdo_forge { if ( ! empty($field[$i]['default'])) { $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; + .' SET '.$field[$i]['default']; } if (isset($field[$i]['null'])) @@ -169,7 +169,7 @@ class CI_DB_pdo_firebird_forge extends CI_DB_pdo_forge { } return $sqls; - } + } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php index 00654d7c0..16b1c6e11 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_ibm_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php index 99d75b645..8ea4838db 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_ibm_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php index 114eb7470..98f463895 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_informix_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php index 1f4bcd1af..91a935908 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_informix_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php index 26bc30e14..0f53e3192 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { @@ -279,7 +279,7 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { */ protected function _list_tables($prefix_limit = FALSE) { - $sql = 'SHOW TABLES'; + $sql = 'SHOW TABLES FROM '.$this->_escape_char.$this->database.$this->_escape_char; if ($prefix_limit === TRUE && $this->dbprefix !== '') { diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php index 01595a603..7713f6732 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_mysql_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php index dba49585c..82f0145ba 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_oci_driver extends CI_DB_pdo_driver { @@ -142,9 +142,9 @@ class CI_DB_pdo_oci_driver extends CI_DB_pdo_driver { } $version_string = parent::version(); - if (preg_match('#Release\s(?<version>\d+(?:\.\d+)+)#', $version_string, $match)) + if (preg_match('#(Release\s)?(?<version>\d+(?:\.\d+)+)#', $version_string, $match)) { - return $this->data_cache['version'] = $match[1]; + return $this->data_cache['version'] = $match['version']; } return FALSE; diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php index 0abda5930..0700d6369 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { @@ -74,6 +74,13 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { */ protected $_unsigned = FALSE; + /** + * NULL value representation in CREATE/ALTER TABLE statements + * + * @var string + */ + protected $_null = 'NULL'; + // -------------------------------------------------------------------- /** @@ -143,9 +150,33 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { */ protected function _attr_auto_increment(&$attributes, &$field) { - // Not supported - sequences and triggers must be used instead + if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'number') !== FALSE && version_compare($this->db->version(), '12.1', '>=')) + { + $field['auto_increment'] = ' GENERATED ALWAYS AS IDENTITY'; + } } + // -------------------------------------------------------------------- + + /** + * Process column + * + * @param array $field + * @return string + */ + protected function _process_column($field) + { + return $this->db->escape_identifiers($field['name']) + .' '.$field['type'].$field['length'] + .$field['unsigned'] + .$field['default'] + .$field['auto_increment'] + .$field['null'] + .$field['unique']; + } + + // -------------------------------------------------------------------- + /** * Field attribute TYPE * diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php index 93a6420e5..2522debec 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php index b05d473ee..f6241136d 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { @@ -98,7 +98,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { if ( ! empty($this->username)) { - $this->dsn .= ';username='.$this->username; + $this->dsn .= ';user='.$this->username; empty($this->password) OR $this->dsn .= ';password='.$this->password; } } @@ -255,7 +255,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { { return 'SELECT "column_name" FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); + WHERE "table_schema" = \''.$this->schema.'\' AND LOWER("table_name") = '.$this->escape(strtolower($table)); } // -------------------------------------------------------------------- @@ -270,7 +270,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { { $sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default" FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); + WHERE "table_schema" = \''.$this->schema.'\' AND LOWER("table_name") = '.$this->escape(strtolower($table)); if (($query = $this->query($sql)) === FALSE) { diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php index ff7a11075..4c3a5aaea 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_pgsql_forge extends CI_DB_pdo_forge { @@ -54,6 +54,13 @@ class CI_DB_pdo_pgsql_forge extends CI_DB_pdo_forge { protected $_drop_table_if = 'DROP TABLE IF EXISTS'; /** + * CREATE TABLE IF statement + * + * @var string + */ + protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; + + /** * UNSIGNED support * * @var array @@ -106,7 +113,7 @@ class CI_DB_pdo_pgsql_forge extends CI_DB_pdo_forge { * @return string|string[] */ protected function _alter_table($alter_type, $table, $field) - { + { if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) { return parent::_alter_table($alter_type, $table, $field); @@ -130,7 +137,7 @@ class CI_DB_pdo_pgsql_forge extends CI_DB_pdo_forge { if ( ! empty($field[$i]['default'])) { $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; + .' SET '.$field[$i]['default']; } if (isset($field[$i]['null'])) @@ -154,7 +161,7 @@ class CI_DB_pdo_pgsql_forge extends CI_DB_pdo_forge { } return $sqls; - } + } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php index f55d9a6c7..634b837c9 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_sqlite_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php index 545b2a3d8..fd9696fb8 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_sqlite_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php index 84109ae30..1c83593df 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_sqlsrv_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php index b23c6d44e..22375949a 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_pdo_sqlsrv_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/postgre/index.html b/system/database/drivers/postgre/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/postgre/index.html +++ b/system/database/drivers/postgre/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index 19a09490c..22638f901 100644 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_postgre_driver extends CI_DB { @@ -78,22 +78,12 @@ class CI_DB_postgre_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Class constructor + * Build DSN * - * Creates a DSN string to be used for db_connect() and db_pconnect() - * - * @param array $params * @return void */ - public function __construct($params) + protected function _build_dsn() { - parent::__construct($params); - - if ( ! empty($this->dsn)) - { - return; - } - $this->dsn === '' OR $this->dsn = ''; if (strpos($this->hostname, '/') !== FALSE) @@ -145,10 +135,11 @@ class CI_DB_postgre_driver extends CI_DB { * Database connection * * @param bool $persistent - * @return resource + * @return resource|object */ public function db_connect($persistent = FALSE) { + empty($this->dsn) && $this->_build_dsn(); $this->conn_id = ($persistent === TRUE) ? pg_pconnect($this->dsn) : pg_connect($this->dsn); @@ -229,7 +220,7 @@ class CI_DB_postgre_driver extends CI_DB { * Execute the query * * @param string $sql an SQL query - * @return resource + * @return resource|object */ protected function _execute($sql) { @@ -422,7 +413,7 @@ class CI_DB_postgre_driver extends CI_DB { { return 'SELECT "column_name" FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); + WHERE "table_schema" = \''.$this->schema.'\' AND LOWER("table_name") = '.$this->escape(strtolower($table)); } // -------------------------------------------------------------------- @@ -437,7 +428,7 @@ class CI_DB_postgre_driver extends CI_DB { { $sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default" FROM "information_schema"."columns" - WHERE LOWER("table_name") = '.$this->escape(strtolower($table)); + WHERE "table_schema" = \''.$this->schema.'\' AND LOWER("table_name") = '.$this->escape(strtolower($table)); if (($query = $this->query($sql)) === FALSE) { diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php index 353ddac99..6f214c665 100644 --- a/system/database/drivers/postgre/postgre_forge.php +++ b/system/database/drivers/postgre/postgre_forge.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_postgre_forge extends CI_DB_forge { @@ -101,7 +101,7 @@ class CI_DB_postgre_forge extends CI_DB_forge { * @return string|string[] */ protected function _alter_table($alter_type, $table, $field) - { + { if (in_array($alter_type, array('DROP', 'ADD'), TRUE)) { return parent::_alter_table($alter_type, $table, $field); @@ -125,7 +125,7 @@ class CI_DB_postgre_forge extends CI_DB_forge { if ( ! empty($field[$i]['default'])) { $sqls[] = $sql.' ALTER COLUMN '.$this->db->escape_identifiers($field[$i]['name']) - .' SET DEFAULT '.$field[$i]['default']; + .' SET '.$field[$i]['default']; } if (isset($field[$i]['null'])) @@ -149,7 +149,7 @@ class CI_DB_postgre_forge extends CI_DB_forge { } return $sqls; - } + } // -------------------------------------------------------------------- diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php index b0054ddae..d977a60e3 100644 --- a/system/database/drivers/postgre/postgre_result.php +++ b/system/database/drivers/postgre/postgre_result.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_postgre_result extends CI_DB_result { @@ -126,7 +126,7 @@ class CI_DB_postgre_result extends CI_DB_result { */ public function free_result() { - if (is_resource($this->result_id)) + if ($this->result_id !== FALSE) { pg_free_result($this->result_id); $this->result_id = FALSE; diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php index 450aa36e4..e6e7b28ba 100644 --- a/system/database/drivers/postgre/postgre_utility.php +++ b/system/database/drivers/postgre/postgre_utility.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_postgre_utility extends CI_DB_utility { diff --git a/system/database/drivers/sqlite3/index.html b/system/database/drivers/sqlite3/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/sqlite3/index.html +++ b/system/database/drivers/sqlite3/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php index 5d057ba5a..d456250f2 100644 --- a/system/database/drivers/sqlite3/sqlite3_driver.php +++ b/system/database/drivers/sqlite3/sqlite3_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlite3_driver extends CI_DB { diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php index 4019a9523..52894e857 100644 --- a/system/database/drivers/sqlite3/sqlite3_forge.php +++ b/system/database/drivers/sqlite3/sqlite3_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlite3_forge extends CI_DB_forge { diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php index d656fed12..a48cbcf56 100644 --- a/system/database/drivers/sqlite3/sqlite3_result.php +++ b/system/database/drivers/sqlite3/sqlite3_result.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlite3_result extends CI_DB_result { diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php index 1bdf3ae37..c80dd4f97 100644 --- a/system/database/drivers/sqlite3/sqlite3_utility.php +++ b/system/database/drivers/sqlite3/sqlite3_utility.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlite3_utility extends CI_DB_utility { diff --git a/system/database/drivers/sqlsrv/index.html b/system/database/drivers/sqlsrv/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/drivers/sqlsrv/index.html +++ b/system/database/drivers/sqlsrv/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php index a22a8b316..33f971ff4 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_driver.php +++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php @@ -48,7 +48,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlsrv_driver extends CI_DB { diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php index 90c3120a5..610d2e426 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_forge.php +++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlsrv_forge extends CI_DB_forge { diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php index e2649c666..bf5884429 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_result.php +++ b/system/database/drivers/sqlsrv/sqlsrv_result.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlsrv_result extends CI_DB_result { diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php index 6dd01a990..bb2a67806 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_utility.php +++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php @@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * @category Database * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/userguide3/database/ */ class CI_DB_sqlsrv_utility extends CI_DB_utility { diff --git a/system/database/index.html b/system/database/index.html index b702fbc39..bcb7cae34 100644 --- a/system/database/index.html +++ b/system/database/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/fonts/index.html b/system/fonts/index.html index b702fbc39..bcb7cae34 100644 --- a/system/fonts/index.html +++ b/system/fonts/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php index cb7eca68b..2c359240a 100644 --- a/system/helpers/array_helper.php +++ b/system/helpers/array_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/array_helper.html + * @link https://codeigniter.com/userguide3/helpers/array_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 94365adb5..6fce05267 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/captcha_helper.html + * @link https://codeigniter.com/userguide3/helpers/captcha_helper.html */ // ------------------------------------------------------------------------ @@ -69,6 +69,7 @@ if ( ! function_exists('create_captcha')) 'img_width' => '150', 'img_height' => '30', 'img_alt' => 'captcha', + 'img_class' => '', 'font_path' => '', 'font_size' => 16, 'expiration' => 7200, @@ -99,13 +100,33 @@ if ( ! function_exists('create_captcha')) if ( ! extension_loaded('gd')) { + log_message('error', 'create_captcha(): GD extension is not loaded.'); + return FALSE; + } + + if ($img_path === '' OR $img_url === '') + { + log_message('error', 'create_captcha(): $img_path and $img_url are required.'); + return FALSE; + } + + if ( ! is_dir($img_path) OR ! is_really_writable($img_path)) + { + log_message('error', "create_captcha(): '{$img_path}' is not a dir, nor is it writable."); return FALSE; } if ($img_url !== '' OR $img_path !== '') { - if ($img_path === '' OR $img_url === '' OR ! is_dir($img_path) OR ! is_really_writable($img_path)) + if ($img_path === '' OR $img_url === '') + { + log_message('error', 'create_captcha(): $img_path and $img_url are required.'); + return FALSE; + } + + if ( ! is_dir($img_path) OR ! is_really_writable($img_path)) { + log_message('error', "create_captcha(): '{$img_path}' is not a dir, nor is it writable."); return FALSE; } @@ -352,7 +373,10 @@ if ( ! function_exists('create_captcha')) $img_src = 'data:image/png;base64,'.base64_encode($img_src); } - $img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_src.'" style="width: '.$img_width.'px; height: '.$img_height .'px; border: 0;" alt="'.$img_alt.'" />'; + $img_class = trim($img_class); + $img_class = (bool) strlen($img_class) ? 'class="'.$img_class.'" ' : ''; + + $img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_src.'" style="width: '.$img_width.'px; height: '.$img_height .'px; border: 0;" '.$img_class.'alt="'.$img_alt.'" />'; ImageDestroy($im); return array('word' => $word, 'time' => $now, 'image' => $img, 'filename' => $img_filename); diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php index d9724932e..8183e0541 100644 --- a/system/helpers/cookie_helper.php +++ b/system/helpers/cookie_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/cookie_helper.html + * @link https://codeigniter.com/userguide3/helpers/cookie_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php index 6ee3c3119..db9e9642d 100644 --- a/system/helpers/date_helper.php +++ b/system/helpers/date_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/date_helper.html + * @link https://codeigniter.com/userguide3/helpers/date_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php index 73777bfb5..4732db57b 100644 --- a/system/helpers/directory_helper.php +++ b/system/helpers/directory_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/directory_helper.html + * @link https://codeigniter.com/userguide3/helpers/directory_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index 4d7829640..9bdeea13d 100644 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/download_helper.html + * @link https://codeigniter.com/userguide3/helpers/download_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index ebc863bbc..398d11afd 100644 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/file_helper.html + * @link https://codeigniter.com/userguide3/helpers/file_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 7a2dadaf3..4b88d3b12 100644 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/form_helper.html + * @link https://codeigniter.com/userguide3/helpers/form_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php index 8b06e4406..531ae2251 100644 --- a/system/helpers/html_helper.php +++ b/system/helpers/html_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/html_helper.html + * @link https://codeigniter.com/userguide3/helpers/html_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/index.html b/system/helpers/index.html index b702fbc39..bcb7cae34 100644 --- a/system/helpers/index.html +++ b/system/helpers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php index a36836b00..b7f472bcc 100644 --- a/system/helpers/inflector_helper.php +++ b/system/helpers/inflector_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/inflector_helper.html + * @link https://codeigniter.com/userguide3/helpers/inflector_helper.html */ // -------------------------------------------------------------------- diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php index 2cefcc277..dff6a6b24 100644 --- a/system/helpers/language_helper.php +++ b/system/helpers/language_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/language_helper.html + * @link https://codeigniter.com/userguide3/helpers/language_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php index 15a53ff72..55fa1e5a0 100644 --- a/system/helpers/number_helper.php +++ b/system/helpers/number_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/number_helper.html + * @link https://codeigniter.com/userguide3/helpers/number_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php index 543e4c078..47d10c2f5 100644 --- a/system/helpers/path_helper.php +++ b/system/helpers/path_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/path_helper.html + * @link https://codeigniter.com/userguide3/helpers/path_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php index dcf5b8b58..f6dbafec9 100644 --- a/system/helpers/security_helper.php +++ b/system/helpers/security_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/security_helper.html + * @link https://codeigniter.com/userguide3/helpers/security_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php index 7738bf97f..3a05525db 100644 --- a/system/helpers/string_helper.php +++ b/system/helpers/string_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/string_helper.html + * @link https://codeigniter.com/userguide3/helpers/string_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php index e1c5e246e..5d5a958e2 100644 --- a/system/helpers/text_helper.php +++ b/system/helpers/text_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/text_helper.html + * @link https://codeigniter.com/userguide3/helpers/text_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php index d308a57d5..47617ffb2 100644 --- a/system/helpers/typography_helper.php +++ b/system/helpers/typography_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/typography_helper.html + * @link https://codeigniter.com/userguide3/helpers/typography_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index 6a959f0e6..4c060a203 100644 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/url_helper.html + * @link https://codeigniter.com/userguide3/helpers/url_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php index 2639956fe..f83f3f544 100644 --- a/system/helpers/xml_helper.php +++ b/system/helpers/xml_helper.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/helpers/xml_helper.html + * @link https://codeigniter.com/userguide3/helpers/xml_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/index.html b/system/index.html index b702fbc39..bcb7cae34 100644 --- a/system/index.html +++ b/system/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php index c34b087c7..9a26b8a9b 100644 --- a/system/language/english/imglib_lang.php +++ b/system/language/english/imglib_lang.php @@ -44,6 +44,7 @@ $lang['imglib_unsupported_imagecreate'] = 'Your server does not support the GD f $lang['imglib_gif_not_supported'] = 'GIF images are often not supported due to licensing restrictions. You may have to use JPG or PNG images instead.'; $lang['imglib_jpg_not_supported'] = 'JPG images are not supported.'; $lang['imglib_png_not_supported'] = 'PNG images are not supported.'; +$lang['imglib_webp_not_supported'] = 'WEBP images are not supported.'; $lang['imglib_jpg_or_png_required'] = 'The image resize protocol specified in your preferences only works with JPEG or PNG image types.'; $lang['imglib_copy_error'] = 'An error was encountered while attempting to replace the file. Please make sure your file directory is writable.'; $lang['imglib_rotate_unsupported'] = 'Image rotation does not appear to be supported by your server.'; diff --git a/system/language/english/index.html b/system/language/english/index.html index b702fbc39..bcb7cae34 100644 --- a/system/language/english/index.html +++ b/system/language/english/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/language/index.html b/system/language/index.html index b702fbc39..bcb7cae34 100644 --- a/system/language/index.html +++ b/system/language/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php index 8da8854ee..c0527e665 100644 --- a/system/libraries/Cache/drivers/Cache_apc.php +++ b/system/libraries/Cache/drivers/Cache_apc.php @@ -160,10 +160,10 @@ class CI_Cache_apc extends CI_Driver { * @param string user/filehits * @return mixed array on success, false on failure */ - public function cache_info($type = NULL) - { - return apc_cache_info($type); - } + public function cache_info($type = NULL) + { + return apc_cache_info($type); + } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/Cache_apcu.php b/system/libraries/Cache/drivers/Cache_apcu.php index 0d84f8ee3..01f80e79b 100644 --- a/system/libraries/Cache/drivers/Cache_apcu.php +++ b/system/libraries/Cache/drivers/Cache_apcu.php @@ -171,10 +171,10 @@ class CI_Cache_apcu extends CI_Driver { * * @return mixed array on success, false on failure */ - public function cache_info() - { - return apcu_cache_info(); - } + public function cache_info() + { + return apcu_cache_info(); + } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php index fdb9042ef..0a90d0692 100644 --- a/system/libraries/Cache/drivers/Cache_dummy.php +++ b/system/libraries/Cache/drivers/Cache_dummy.php @@ -138,10 +138,10 @@ class CI_Cache_dummy extends CI_Driver { * @param string user/filehits * @return bool FALSE */ - public function cache_info($type = NULL) - { - return FALSE; - } + public function cache_info($type = NULL) + { + return FALSE; + } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php index 3bc3ccd6c..9b082d11b 100644 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -69,6 +69,21 @@ class CI_Cache_redis extends CI_Driver */ protected $_redis; + + /** + * del()/delete() method name depending on phpRedis version + * + * @var string + */ + protected static $_delete_name; + + /** + * sRem()/sRemove() method name depending on phpRedis version + * + * @var string + */ + protected static $_sRemove_name; + // ------------------------------------------------------------------------ /** @@ -90,6 +105,20 @@ class CI_Cache_redis extends CI_Driver return; } + if ( ! isset(static::$_delete_name, static::$_sRemove_name)) + { + if (version_compare(phpversion('redis'), '5', '>=')) + { + static::$_delete_name = 'del'; + static::$_sRemove_name = 'sRem'; + } + else + { + static::$_delete_name = 'delete'; + static::$_sRemove_name = 'sRemove'; + } + } + $CI =& get_instance(); if ($CI->config->load('redis', TRUE, TRUE)) @@ -138,7 +167,7 @@ class CI_Cache_redis extends CI_Driver { $data = $this->_redis->hMGet($key, array('__ci_type', '__ci_value')); - if ( ! isset($data['__ci_type'], $data['__ci_value']) OR $data['__ci_value'] === FALSE) + if ($value !== FALSE && $this->_redis->sIsMember('_ci_redis_serialized', $key)) { return FALSE; } @@ -196,9 +225,9 @@ class CI_Cache_redis extends CI_Driver { return FALSE; } - elseif ($ttl) + else { - $this->_redis->expireAt($id, time() + $ttl); + $this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $id); } return TRUE; @@ -214,7 +243,14 @@ class CI_Cache_redis extends CI_Driver */ public function delete($key) { - return ($this->_redis->delete($key) === 1); + if ($this->_redis->{static::$_delete_name}($key) !== 1) + { + return FALSE; + } + + $this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $key); + + return TRUE; } // ------------------------------------------------------------------------ @@ -228,7 +264,7 @@ class CI_Cache_redis extends CI_Driver */ public function increment($id, $offset = 1) { - return $this->_redis->hIncrBy($id, 'data', $offset); + return $this->_redis->incrBy($id, $offset); } // ------------------------------------------------------------------------ @@ -242,7 +278,7 @@ class CI_Cache_redis extends CI_Driver */ public function decrement($id, $offset = 1) { - return $this->_redis->hIncrBy($id, 'data', -$offset); + return $this->_redis->decrBy($id, $offset); } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php index e19c6ca99..703fece7a 100644 --- a/system/libraries/Cache/drivers/Cache_wincache.php +++ b/system/libraries/Cache/drivers/Cache_wincache.php @@ -169,10 +169,10 @@ class CI_Cache_wincache extends CI_Driver { * * @return mixed array on success, false on failure */ - public function cache_info() - { - return wincache_ucache_info(TRUE); - } + public function cache_info() + { + return wincache_ucache_info(TRUE); + } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/index.html b/system/libraries/Cache/drivers/index.html index b702fbc39..bcb7cae34 100644 --- a/system/libraries/Cache/drivers/index.html +++ b/system/libraries/Cache/drivers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/libraries/Cache/index.html b/system/libraries/Cache/index.html index b702fbc39..bcb7cae34 100644 --- a/system/libraries/Cache/index.html +++ b/system/libraries/Cache/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php index a6bdae50a..fcfcf62ca 100644 --- a/system/libraries/Calendar.php +++ b/system/libraries/Calendar.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/calendar.html + * @link https://codeigniter.com/userguide3/libraries/calendar.html */ class CI_Calendar { diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 1912e0442..b01e44a63 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/email.html + * @link https://codeigniter.com/userguide3/libraries/email.html */ class CI_Email { @@ -389,7 +389,7 @@ class CI_Email { $this->charset = config_item('charset'); $this->initialize($config); - isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); log_message('info', 'Email Class Initialized'); } diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php index 7ed185f1b..df1af4cf4 100644 --- a/system/libraries/Encrypt.php +++ b/system/libraries/Encrypt.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/encryption.html + * @link https://codeigniter.com/userguide3/libraries/encryption.html */ class CI_Encrypt { @@ -198,7 +198,7 @@ class CI_Encrypt { * This allows for backwards compatibility and a method to transition to the * new encryption algorithms. * - * For more details, see https://codeigniter.com/user_guide/installation/upgrade_200.html#encryption + * For more details, see https://codeigniter.com/userguide3/installation/upgrade_200.html#encryption * * @param string * @param int (mcrypt mode constant) diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php index fd858cb29..7d648dfa3 100644 --- a/system/libraries/Encryption.php +++ b/system/libraries/Encryption.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/libraries/encryption.html + * @link https://codeigniter.com/userguide3/libraries/encryption.html */ class CI_Encryption { @@ -161,7 +161,7 @@ class CI_Encryption { show_error('Encryption: Unable to find an available encryption driver.'); } - isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); $this->initialize($params); if ( ! isset($this->_key) && self::strlen($key = config_item('encryption_key')) > 0) @@ -476,7 +476,7 @@ class CI_Encryption { $iv = ($iv_size = openssl_cipher_iv_length($params['handle'])) ? $this->create_key($iv_size) - : NULL; + : ''; $data = openssl_encrypt( $data, @@ -585,7 +585,7 @@ class CI_Encryption { } else { - $iv = NULL; + $iv = ''; } if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0) @@ -632,7 +632,7 @@ class CI_Encryption { } else { - $iv = NULL; + $iv = ''; } return empty($params['handle']) @@ -910,8 +910,8 @@ class CI_Encryption { protected static function strlen($str) { return (self::$func_overload) - ? mb_strlen($str, '8bit') - : strlen($str); + ? mb_strlen((string) $str, '8bit') + : strlen((string) $str); } // -------------------------------------------------------------------- diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index e38c44277..043a97c6d 100644 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Validation * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/form_validation.html + * @link https://codeigniter.com/userguide3/libraries/form_validation.html */ class CI_Form_validation { @@ -1062,7 +1062,7 @@ class CI_Form_validation { { return is_array($str) ? (empty($str) === FALSE) - : (trim($str) !== ''); + : (trim((string) $str) !== ''); } // -------------------------------------------------------------------- @@ -1214,6 +1214,13 @@ class CI_Form_validation { $str = $matches[2]; } + // Apparently, FILTER_VALIDATE_URL doesn't reject digit-only names for some reason ... + // See https://github.com/bcit-ci/CodeIgniter/issues/5755 + if (ctype_digit($str)) + { + return FALSE; + } + // PHP 7 accepts IPv6 addresses within square brackets as hostnames, // but it appears that the PR that came in with https://bugs.php.net/bug.php?id=68039 // was never merged into a PHP 5 branch ... https://3v4l.org/8PsSN diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php index 4f0f5dfb3..92644153a 100644 --- a/system/libraries/Ftp.php +++ b/system/libraries/Ftp.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/ftp.html + * @link https://codeigniter.com/userguide3/libraries/ftp.html */ class CI_FTP { @@ -202,7 +202,7 @@ class CI_FTP { */ protected function _is_conn() { - if ( ! is_resource($this->conn_id)) + if ($this->conn_id !== FALSE) { if ($this->debug === TRUE) { diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php index 9cd0d1dfa..6aeee1790 100644 --- a/system/libraries/Image_lib.php +++ b/system/libraries/Image_lib.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Image_lib * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/image_lib.html + * @link https://codeigniter.com/userguide3/libraries/image_lib.html */ class CI_Image_lib { @@ -946,6 +946,10 @@ class CI_Image_lib { $cmd_in = 'pngtopnm'; $cmd_out = 'ppmtopng'; break; + case 18 : + $cmd_in = 'webptopnm'; + $cmd_out = 'ppmtowebp'; + break; } if ($action === 'crop') @@ -1472,6 +1476,14 @@ class CI_Image_lib { } return imagecreatefrompng($path); + case 18: + if ( ! function_exists('imagecreatefromwebp')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_webp_not_supported')); + return FALSE; + } + + return imagecreatefromwebp($path); default: $this->set_error(array('imglib_unsupported_imagecreate')); return FALSE; @@ -1532,6 +1544,19 @@ class CI_Image_lib { return FALSE; } break; + case 18: + if ( ! function_exists('imagewebp')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_webp_not_supported')); + return FALSE; + } + + if ( ! @imagewebp($resource, $this->full_dst_path)) + { + $this->set_error('imglib_save_failed'); + return FALSE; + } + break; default: $this->set_error(array('imglib_unsupported_imagecreate')); return FALSE; @@ -1573,6 +1598,8 @@ class CI_Image_lib { break; case 3 : imagepng($resource); break; + case 18 : imagewebp($resource); + break; default: echo 'Unable to display the image'; break; } diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php index 1b7808923..915d4e453 100644 --- a/system/libraries/Migration.php +++ b/system/libraries/Migration.php @@ -288,7 +288,7 @@ class CI_Migration { $this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class); return FALSE; } - elseif ( ! is_callable(array($class, $method))) + elseif ( ! method_exists($class, $method) OR ! (new ReflectionMethod($class, $method))->isPublic()) { $this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class); return FALSE; diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index 11d63fe50..20418c00a 100644 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Pagination * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/pagination.html + * @link https://codeigniter.com/userguide3/libraries/pagination.html */ class CI_Pagination { diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php index d3c6500ae..04476f1a2 100644 --- a/system/libraries/Parser.php +++ b/system/libraries/Parser.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Parser * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/parser.html + * @link https://codeigniter.com/userguide3/libraries/parser.html */ class CI_Parser { diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index 77af7b99b..5531f3366 100644 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/general/profiling.html + * @link https://codeigniter.com/userguide3/general/profiling.html */ class CI_Profiler { @@ -105,7 +105,7 @@ class CI_Profiler { { if ( ! isset($config[$section])) { - $this->_compile_{$section} = TRUE; + $this->{'_compile_'.$section} = TRUE; } } @@ -135,7 +135,7 @@ class CI_Profiler { { if (in_array($method, $this->_available_sections)) { - $this->_compile_{$method} = ($enable !== FALSE); + $this->{'_compile_'.$method} = ($enable !== FALSE); } } } @@ -486,13 +486,13 @@ class CI_Profiler { { $pre = ''; $pre_close = ''; - + if (is_array($val) OR is_object($val)) { $val = print_r($val, TRUE); - + $pre = '<pre>' ; - $pre_close = '</pre>'; + $pre_close = '</pre>'; } $output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">' @@ -524,13 +524,13 @@ class CI_Profiler { { $pre = ''; $pre_close = ''; - + if (is_array($val) OR is_object($val)) { $val = print_r($val, TRUE); - + $pre = '<pre>' ; - $pre_close = '</pre>'; + $pre_close = '</pre>'; } $output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">' @@ -554,7 +554,7 @@ class CI_Profiler { foreach ($this->_available_sections as $section) { - if ($this->_compile_{$section} !== FALSE) + if ($this->{'_compile_'.$section} !== FALSE) { $func = '_compile_'.$section; $output .= $this->{$func}(); diff --git a/system/libraries/Session/CI_Session_driver_interface.php b/system/libraries/Session/CI_Session_driver_interface.php new file mode 100644 index 000000000..a854e92af --- /dev/null +++ b/system/libraries/Session/CI_Session_driver_interface.php @@ -0,0 +1,58 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP + * + * This content is released under the MIT License (MIT) + * + * Copyright (c) 2022, CodeIgniter Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team + * @copyright Copyright (c) 2022, CodeIgniter Foundation (https://codeigniter.com/) + * @license http://opensource.org/licenses/MIT MIT License + * @link https://codeigniter.com + * @since Version 3.0.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +/** + * CI_Session_driver_interface + * + * A compatibility typeless SessionHandlerInterface alias + * + * @package CodeIgniter + * @subpackage Libraries + * @category Sessions + * @author Andrey Andreev + * @link https://codeigniter.com/userguide3/libraries/sessions.html + */ +interface CI_Session_driver_interface { + + public function open($save_path, $name); + public function close(); + public function read($session_id); + public function write($session_id, $session_data); + public function destroy($session_id); + public function gc($maxlifetime); +} diff --git a/system/libraries/Session/OldSessionWrapper.php b/system/libraries/Session/OldSessionWrapper.php new file mode 100644 index 000000000..5934b5218 --- /dev/null +++ b/system/libraries/Session/OldSessionWrapper.php @@ -0,0 +1,88 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP + * + * This content is released under the MIT License (MIT) + * + * Copyright (c) 2022, CodeIgniter Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team + * @copyright Copyright (c) 2022, CodeIgniter Foundation (https://codeigniter.com/) + * @license http://opensource.org/licenses/MIT MIT License + * @link https://codeigniter.com + * @since Version 3.0.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +/** + * OldSessionWrapper + * + * PHP 8 Session handler compatibility wrapper, pre-PHP8 version + * + * @package CodeIgniter + * @subpackage Libraries + * @category Sessions + * @author Andrey Andreev + * @link https://codeigniter.com/userguide3/libraries/sessions.html + */ +class CI_SessionWrapper implements SessionHandlerInterface { + + protected CI_Session_driver_interface $driver; + + public function __construct(CI_Session_driver_interface $driver) + { + $this->driver = $driver; + } + + public function open($save_path, $name) + { + return $this->driver->open($save_path, $name); + } + + public function close() + { + return $this->driver->close(); + } + + public function read($id) + { + return $this->driver->read($id); + } + + public function write($id, $data) + { + return $this->driver->write($id, $data); + } + + public function destroy($id) + { + return $this->driver->destroy($id); + } + + public function gc($maxlifetime) + { + return $this->driver->gc($maxlifetime); + } +} diff --git a/system/libraries/Session/PHP8SessionWrapper.php b/system/libraries/Session/PHP8SessionWrapper.php new file mode 100644 index 000000000..c6dfaf7e0 --- /dev/null +++ b/system/libraries/Session/PHP8SessionWrapper.php @@ -0,0 +1,90 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP + * + * This content is released under the MIT License (MIT) + * + * Copyright (c) 2022, CodeIgniter Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team + * @copyright Copyright (c) 2022, CodeIgniter Foundation (https://codeigniter.com/) + * @license http://opensource.org/licenses/MIT MIT License + * @link https://codeigniter.com + * @since Version 3.0.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +/** + * PHP8SessionWrapper + * + * PHP 8 Session handler compatibility wrapper + * + * @package CodeIgniter + * @subpackage Libraries + * @category Sessions + * @author Andrey Andreev + * @link https://codeigniter.com/userguide3/libraries/sessions.html + */ +class CI_SessionWrapper implements SessionHandlerInterface { + + protected CI_Session_driver_interface $driver; + + public function __construct(CI_Session_driver_interface $driver) + { + $this->driver = $driver; + } + + public function open(string $save_path, string $name): bool + { + return $this->driver->open($save_path, $name); + } + + public function close(): bool + { + return $this->driver->close(); + } + + #[\ReturnTypeWillChange] + public function read(string $id): mixed + { + return $this->driver->read($id); + } + + public function write(string $id, string $data): bool + { + return $this->driver->write($id, $data); + } + + public function destroy(string $id): bool + { + return $this->driver->destroy($id); + } + + #[\ReturnTypeWillChange] + public function gc(int $maxlifetime): mixed + { + return $this->driver->gc($maxlifetime); + } +} diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index dfd0f432e..f370f7f19 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2019, British Columbia Institute of Technology + * Copyright (c) 2019 - 2022, CodeIgniter Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/) + * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/) * @license https://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 @@ -44,7 +45,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/userguide3/libraries/sessions.html */ class CI_Session { @@ -102,15 +103,24 @@ class CI_Session { $this->_configure($params); $this->_config['_sid_regexp'] = $this->_sid_regexp; - $class = new $class($this->_config); - if ($class instanceof SessionHandlerInterface) + $class = new $class($this->_config); + $wrapper = new CI_SessionWrapper($class); + if (is_php('5.4')) { session_set_save_handler($class, TRUE); } else { - log_message('error', "Session: Driver '".$this->_driver."' doesn't implement SessionHandlerInterface. Aborting."); - return; + session_set_save_handler( + array($class, 'open'), + array($class, 'close'), + array($class, 'read'), + array($class, 'write'), + array($class, 'destroy'), + array($class, 'gc') + ); + + register_shutdown_function('session_write_close'); } // Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers @@ -144,15 +154,36 @@ class CI_Session { // unless it is being currently created or regenerated elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id()) { - setcookie( - $this->_config['cookie_name'], - session_id(), - (empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']), - $this->_config['cookie_path'], - $this->_config['cookie_domain'], - $this->_config['cookie_secure'], - TRUE - ); + $expires = empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']; + if (is_php('7.3')) + { + setcookie( + $this->_config['cookie_name'], + session_id(), + array( + 'expires' => $expires, + 'path' => $this->_config['cookie_path'], + 'domain' => $this->_config['cookie_domain'], + 'secure' => $this->_config['cookie_secure'], + 'httponly' => TRUE, + 'samesite' => $this->_config['cookie_samesite'] + ) + ); + } + else + { + $header = 'Set-Cookie: '.$this->_config['cookie_name'].'='.session_id(); + $header .= empty($expires) ? '' : '; Expires='.gmdate('D, d-M-Y H:i:s T', $expires).'; Max-Age='.$this->_config['cookie_lifetime']; + $header .= '; Path='.$this->_config['cookie_path']; + $header .= ($this->_config['cookie_domain'] !== '' ? '; Domain='.$this->_config['cookie_domain'] : ''); + $header .= ($this->_config['cookie_secure'] ? '; Secure' : '').'; HttpOnly; SameSite='.$this->_config['cookie_samesite']; + header($header); + } + + if ( ! $this->_config['cookie_secure'] && $this->_config['cookie_samesite'] === 'None') + { + log_message('error', 'Session:', $this->_config['cookie_name'].' cookie sent with SameSite=None, but without Secure attribute.'); + } } $this->_ci_init_vars(); @@ -174,6 +205,10 @@ class CI_Session { */ protected function _ci_load_classes($driver) { + require_once(BASEPATH.'libraries/Session/CI_Session_driver_interface.php'); + $wrapper = is_php('8.0') ? 'PHP8SessionWrapper' : 'OldSessionWrapper'; + require_once(BASEPATH.'libraries/Session/'.$wrapper.'.php'); + $prefix = config_item('subclass_prefix'); if ( ! class_exists('CI_Session_driver', FALSE)) @@ -267,13 +302,43 @@ class CI_Session { isset($params['cookie_domain']) OR $params['cookie_domain'] = config_item('cookie_domain'); isset($params['cookie_secure']) OR $params['cookie_secure'] = (bool) config_item('cookie_secure'); - session_set_cookie_params( - $params['cookie_lifetime'], - $params['cookie_path'], - $params['cookie_domain'], - $params['cookie_secure'], - TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons - ); + isset($params['cookie_samesite']) OR $params['cookie_samesite'] = config_item('sess_samesite'); + if ( ! isset($params['cookie_samesite']) && is_php('7.3')) + { + $params['cookie_samesite'] = ini_get('session.cookie_samesite'); + } + + if (isset($params['cookie_samesite'])) + { + $params['cookie_samesite'] = ucfirst(strtolower($params['cookie_samesite'])); + in_array($params['cookie_samesite'], array('Lax', 'Strict', 'None'), TRUE) OR $params['cookie_samesite'] = 'Lax'; + } + else + { + $params['cookie_samesite'] = 'Lax'; + } + + if (is_php('7.3')) + { + session_set_cookie_params(array( + 'lifetime' => $params['cookie_lifetime'], + 'path' => $params['cookie_path'], + 'domain' => $params['cookie_domain'], + 'secure' => $params['cookie_secure'], + 'httponly' => $params['cookie_httponly'], + 'samesite' => $params['cookie_samesite'] + )); + } + else + { + session_set_cookie_params( + $params['cookie_lifetime'], + $params['cookie_path'], + $params['cookie_domain'], + $params['cookie_secure'], + TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons + ); + } if (empty($expiration)) { @@ -396,9 +461,7 @@ class CI_Session { { $_SESSION['__ci_vars'][$key] = 'old'; } - // Hacky, but 'old' will (implicitly) always be less than time() ;) - // DO NOT move this above the 'new' check! - elseif ($value < $current_time) + elseif ($value === 'old' || $value < $current_time) { unset($_SESSION[$key], $_SESSION['__ci_vars'][$key]); } @@ -706,7 +769,7 @@ class CI_Session { * * Legacy CI_Session compatibility method * - * @returns array + * @return array */ public function &get_userdata() { diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 14ebdb09f..b1b1b073e 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2019, British Columbia Institute of Technology + * Copyright (c) 2019 - 2022, CodeIgniter Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/) + * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/) * @license https://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/userguide3/libraries/sessions.html */ -abstract class CI_Session_driver implements SessionHandlerInterface { +abstract class CI_Session_driver { protected $_config; @@ -139,14 +140,28 @@ abstract class CI_Session_driver implements SessionHandlerInterface { */ protected function _cookie_destroy() { + if ( ! is_php('7.3')) + { + $header = 'Set-Cookie: '.$this->_config['cookie_name'].'='; + $header .= '; Expires='.gmdate('D, d-M-Y H:i:s T', 1).'; Max-Age=-1'; + $header .= '; Path='.$this->_config['cookie_path']; + $header .= ($this->_config['cookie_domain'] !== '' ? '; Domain='.$this->_config['cookie_domain'] : ''); + $header .= ($this->_config['cookie_secure'] ? '; Secure' : '').'; HttpOnly; SameSite='.$this->_config['cookie_samesite']; + header($header); + return; + } + return setcookie( $this->_config['cookie_name'], NULL, - 1, - $this->_config['cookie_path'], - $this->_config['cookie_domain'], - $this->_config['cookie_secure'], - TRUE + array( + 'expires' => 1, + 'path' => $this->_config['cookie_path'], + 'domain' => $this->_config['cookie_domain'], + 'secure' => $this->_config['cookie_secure'], + 'httponly' => TRUE, + 'samesite' => $this->_config['cookie_samesite'] + ) ); } @@ -184,25 +199,4 @@ abstract class CI_Session_driver implements SessionHandlerInterface { return TRUE; } - - // ------------------------------------------------------------------------ - - /** - * Fail - * - * Drivers other than the 'files' one don't (need to) use the - * session.save_path INI setting, but that leads to confusing - * error messages emitted by PHP when open() or write() fail, - * as the message contains session.save_path ... - * To work around the problem, the drivers will call this method - * so that the INI is set just in time for the error message to - * be properly generated. - * - * @return mixed - */ - protected function _fail() - { - ini_set('session.save_path', config_item('sess_save_path')); - return $this->_failure; - } } diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 734fe624f..2f788a1a1 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2019, British Columbia Institute of Technology + * Copyright (c) 2019 - 2022, CodeIgniter Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/) + * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/) * @license https://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/userguide3/libraries/sessions.html */ -class CI_Session_database_driver extends CI_Session_driver implements SessionHandlerInterface { +class CI_Session_database_driver extends CI_Session_driver implements CI_Session_driver_interface { /** * DB object @@ -130,7 +131,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if (empty($this->_db->conn_id) && ! $this->_db->db_connect()) { - return $this->_fail(); + return $this->_failure; } $this->php5_validate_id(); @@ -150,48 +151,47 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ public function read($session_id) { - if ($this->_get_lock($session_id) !== FALSE) + if ($this->_get_lock($session_id) === FALSE) { - // Prevent previous QB calls from messing with our queries - $this->_db->reset_query(); - - // Needed by write() to detect session_regenerate_id() calls - $this->_session_id = $session_id; + return $this->_failure; + } - $this->_db - ->select('data') - ->from($this->_config['save_path']) - ->where('id', $session_id); + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); - if ($this->_config['match_ip']) - { - $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); - } + // Needed by write() to detect session_regenerate_id() calls + $this->_session_id = $session_id; - if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL) - { - // PHP7 will reuse the same SessionHandler object after - // ID regeneration, so we need to explicitly set this to - // FALSE instead of relying on the default ... - $this->_row_exists = FALSE; - $this->_fingerprint = md5(''); - return ''; - } + $this->_db + ->select('data') + ->from($this->_config['save_path']) + ->where('id', $session_id); - // PostgreSQL's variant of a BLOB datatype is Bytea, which is a - // PITA to work with, so we use base64-encoded data in a TEXT - // field instead. - $result = ($this->_platform === 'postgre') - ? base64_decode(rtrim($result->data)) - : $result->data; + if ($this->_config['match_ip']) + { + $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); + } - $this->_fingerprint = md5($result); - $this->_row_exists = TRUE; - return $result; + if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL) + { + // PHP7 will reuse the same SessionHandler object after + // ID regeneration, so we need to explicitly set this to + // FALSE instead of relying on the default ... + $this->_row_exists = FALSE; + $this->_fingerprint = md5(''); + return ''; } - $this->_fingerprint = md5(''); - return ''; + // PostgreSQL's variant of a BLOB datatype is Bytea, which is a + // PITA to work with, so we use base64-encoded data in a TEXT + // field instead. + $result = ($this->_platform === 'postgre') + ? base64_decode(rtrim($result->data)) + : $result->data; + + $this->_fingerprint = md5($result); + $this->_row_exists = TRUE; + return $result; } // ------------------------------------------------------------------------ @@ -215,7 +215,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return $this->_fail(); + return $this->_failure; } $this->_row_exists = FALSE; @@ -223,7 +223,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } elseif ($this->_lock === FALSE) { - return $this->_fail(); + return $this->_failure; } if ($this->_row_exists === FALSE) @@ -242,7 +242,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return $this->_success; } - return $this->_fail(); + return $this->_failure; } $this->_db->where('id', $session_id); @@ -265,7 +265,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return $this->_success; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -280,7 +280,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan public function close() { return ($this->_lock && ! $this->_release_lock()) - ? $this->_fail() + ? $this->_failure : $this->_success; } @@ -309,7 +309,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ( ! $this->_db->delete($this->_config['save_path'])) { - return $this->_fail(); + return $this->_failure; } } @@ -319,7 +319,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return $this->_success; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -339,7 +339,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime))) ? $this->_success - : $this->_fail(); + : $this->_failure; } // -------------------------------------------------------------------- diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 467059434..4b7b9878b 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2019, British Columbia Institute of Technology + * Copyright (c) 2019 - 2022, CodeIgniter Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/) + * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/) * @license https://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/userguide3/libraries/sessions.html */ -class CI_Session_files_driver extends CI_Session_driver implements SessionHandlerInterface { +class CI_Session_files_driver extends CI_Session_driver implements CI_Session_driver_interface { /** * Save path @@ -115,7 +116,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $this->_sid_regexp = $this->_config['_sid_regexp']; - isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); } // ------------------------------------------------------------------------ @@ -135,12 +136,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { if ( ! mkdir($save_path, 0700, TRUE)) { - throw new Exception("Session: Configured save path '".$this->_config['save_path']."' is not a directory, doesn't exist or cannot be created."); + log_message('error', "Session: Configured save path '".$this->_config['save_path']."' is not a directory, doesn't exist or cannot be created."); + return $this->_failure; } } elseif ( ! is_writable($save_path)) { - throw new Exception("Session: Configured save path '".$this->_config['save_path']."' is not writable by the PHP process."); + log_message('error', "Session: Configured save path '".$this->_config['save_path']."' is not writable by the PHP process."); + return $this->_failure; } $this->_config['save_path'] = $save_path; @@ -194,6 +197,10 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $this->_fingerprint = md5(''); return ''; } + + // Prevent possible data corruption + // See https://github.com/bcit-ci/CodeIgniter/issues/5857 + clearstatcache(TRUE, $this->_file_path.$session_id); } // We shouldn't need this, but apparently we do ... // See https://github.com/bcit-ci/CodeIgniter/issues/4039 diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index ab54f029f..d84a9df1d 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2019, British Columbia Institute of Technology + * Copyright (c) 2019 - 2022, CodeIgniter Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/) + * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/) * @license https://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/userguide3/libraries/sessions.html */ -class CI_Session_memcached_driver extends CI_Session_driver implements SessionHandlerInterface { +class CI_Session_memcached_driver extends CI_Session_driver implements CI_Session_driver_interface { /** * Memcached instance @@ -117,7 +118,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { $this->_memcached = NULL; log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']); - return $this->_fail(); + return $this->_failure; } foreach ($matches as $match) @@ -142,7 +143,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if (empty($server_list)) { log_message('error', 'Session: Memcached server pool is empty.'); - return $this->_fail(); + return $this->_failure; } $this->php5_validate_id(); @@ -172,7 +173,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $session_data; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -190,14 +191,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if ( ! isset($this->_memcached, $this->_lock_key)) { - return $this->_fail(); + return $this->_failure; } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return $this->_fail(); + return $this->_failure; } $this->_fingerprint = md5(''); @@ -215,7 +216,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_success; } - return $this->_fail(); + return $this->_failure; } elseif ( $this->_memcached->touch($key, $this->_config['expiration']) @@ -225,7 +226,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_success; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -244,14 +245,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_release_lock(); if ( ! $this->_memcached->quit()) { - return $this->_fail(); + return $this->_failure; } $this->_memcached = NULL; return $this->_success; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -273,7 +274,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_success; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 07511e555..fae024bee 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2019, British Columbia Institute of Technology + * Copyright (c) 2019 - 2022, CodeIgniter Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/) + * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/) * @license https://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -44,9 +45,9 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link https://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/userguide3/libraries/sessions.html */ -class CI_Session_redis_driver extends CI_Session_driver implements SessionHandlerInterface { +class CI_Session_redis_driver extends CI_Session_driver implements CI_Session_driver_interface { /** * phpRedis instance @@ -76,6 +77,33 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle */ protected $_key_exists = FALSE; + /** + * Name of setTimeout() method in phpRedis + * + * Due to some deprecated methods in phpRedis, we need to call the + * specific methods depending on the version of phpRedis. + * + * @var string + */ + protected $_setTimeout_name; + + /** + * Name of delete() method in phpRedis + * + * Due to some deprecated methods in phpRedis, we need to call the + * specific methods depending on the version of phpRedis. + * + * @var string + */ + protected $_delete_name; + + /** + * Success return value of ping() method in phpRedis + * + * @var mixed + */ + protected $_ping_success; + // ------------------------------------------------------------------------ /** @@ -88,6 +116,20 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { parent::__construct($params); + // Detect the names of some methods in phpRedis instance + if (version_compare(phpversion('redis'), '5', '>=')) + { + $this->_setTimeout_name = 'expire'; + $this->_delete_name = 'del'; + $this->_ping_success = TRUE; + } + else + { + $this->_setTimeout_name = 'setTimeout'; + $this->_delete_name = 'delete'; + $this->_ping_success = '+PONG'; + } + if (empty($this->_config['save_path'])) { log_message('error', 'Session: No Redis save path configured.'); @@ -96,7 +138,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { $save_path = array('path' => $matches[1]); } - elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(?<options>\?.+)?#', $this->_config['save_path'], $matches)) + elseif (preg_match('#(?:(?:tcp|tls)://)?([^:?]+)(?:\:(\d+))?(?<options>\?.+)?#', $this->_config['save_path'], $matches)) { $save_path = array( 'host' => $matches[1], @@ -144,7 +186,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (empty($this->_config['save_path'])) { - return $this->_fail(); + return $this->_failure; } $redis = new Redis(); @@ -169,17 +211,18 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle else { $this->_redis = $redis; + $this->php5_validate_id(); return $this->_success; } } else { - log_message('error', 'Session: Unable to connect to Redis with the configured settings.'); + $this->_redis = $redis; + $this->php5_validate_id(); + return $this->_success; } - $this->php5_validate_id(); - - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -209,7 +252,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $session_data; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -227,21 +270,21 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if ( ! isset($this->_redis, $this->_lock_key)) { - return $this->_fail(); + return $this->_failure; } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return $this->_fail(); + return $this->_failure; } $this->_key_exists = FALSE; $this->_session_id = $session_id; } - $this->_redis->setTimeout($this->_lock_key, 300); + $this->_redis->{$this->_setTimeout_name}($this->_lock_key, 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) { if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) @@ -251,12 +294,12 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $this->_success; } - return $this->_fail(); + return $this->_failure; } - return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) + return ($this->_redis->{$this->_setTimeout_name}($this->_key_prefix.$session_id, $this->_config['expiration'])) ? $this->_success - : $this->_fail(); + : $this->_failure; } // ------------------------------------------------------------------------ @@ -273,12 +316,12 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if (isset($this->_redis)) { try { - if ($this->_redis->ping() === '+PONG') + if ($this->_redis->ping() === $this->_ping_success) { $this->_release_lock(); if ($this->_redis->close() === FALSE) { - return $this->_fail(); + return $this->_failure; } } } @@ -308,16 +351,16 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (isset($this->_redis, $this->_lock_key)) { - if (($result = $this->_redis->delete($this->_key_prefix.$session_id)) !== 1) + if (($result = $this->_redis->{$this->_delete_name}($this->_key_prefix.$session_id)) !== 1) { - log_message('debug', 'Session: Redis::delete() expected to return 1, got '.var_export($result, TRUE).' instead.'); + log_message('debug', 'Session: Redis::'.$this->_delete_name.'() expected to return 1, got '.var_export($result, TRUE).' instead.'); } $this->_cookie_destroy(); return $this->_success; } - return $this->_fail(); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -369,7 +412,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // correct session ID. if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { - return $this->_redis->setTimeout($this->_lock_key, 300); + return $this->_redis->{$this->_setTimeout_name}($this->_lock_key, 300); } // 30 attempts to obtain a lock, in case another request already has it @@ -383,11 +426,13 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle continue; } - $result = ($ttl === -2) - ? $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300)) - : $this->_redis->setex($lock_key, 300, time()); - - if ( ! $result) + if ($ttl === -2 && ! $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300))) + { + // Sleep for 1s to wait for lock releases. + sleep(1); + continue; + } + elseif ( ! $this->_redis->setex($lock_key, 300, time())) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); return FALSE; @@ -425,7 +470,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (isset($this->_redis, $this->_lock_key) && $this->_lock) { - if ( ! $this->_redis->delete($this->_lock_key)) + if ( ! $this->_redis->{$this->_delete_name}($this->_lock_key)) { log_message('error', 'Session: Error while trying to free lock for '.$this->_lock_key); return FALSE; diff --git a/system/libraries/Session/drivers/index.html b/system/libraries/Session/drivers/index.html index b702fbc39..bcb7cae34 100644 --- a/system/libraries/Session/drivers/index.html +++ b/system/libraries/Session/drivers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/libraries/Session/index.html b/system/libraries/Session/index.html index b702fbc39..bcb7cae34 100644 --- a/system/libraries/Session/index.html +++ b/system/libraries/Session/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/libraries/Table.php b/system/libraries/Table.php index 055512698..98258b63d 100644 --- a/system/libraries/Table.php +++ b/system/libraries/Table.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category HTML Tables * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/table.html + * @link https://codeigniter.com/userguide3/libraries/table.html */ class CI_Table { diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php index 07f066d01..75ccae8f8 100644 --- a/system/libraries/Trackback.php +++ b/system/libraries/Trackback.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Trackbacks * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/trackback.html + * @link https://codeigniter.com/userguide3/libraries/trackback.html */ class CI_Trackback { diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php index e67138c1a..d919d484a 100644 --- a/system/libraries/Typography.php +++ b/system/libraries/Typography.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Helpers * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/typography.html + * @link https://codeigniter.com/userguide3/libraries/typography.html */ class CI_Typography { diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php index 631d583ba..55e3bfcb2 100644 --- a/system/libraries/Unit_test.php +++ b/system/libraries/Unit_test.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category UnitTesting * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/unit_testing.html + * @link https://codeigniter.com/userguide3/libraries/unit_testing.html */ class CI_Unit_test { diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 8c891cff6..281ebef1a 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Uploads * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/file_uploading.html + * @link https://codeigniter.com/userguide3/libraries/file_uploading.html */ class CI_Upload { @@ -867,7 +867,7 @@ class CI_Upload { $this->file_type = 'image/jpeg'; } - $img_mimes = array('image/gif', 'image/jpeg', 'image/png'); + $img_mimes = array('image/gif', 'image/jpeg', 'image/png', 'image/webp'); return in_array($this->file_type, $img_mimes, TRUE); } @@ -901,7 +901,7 @@ class CI_Upload { } // Images get some additional checks - if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png'), TRUE) && @getimagesize($this->file_temp) === FALSE) + if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png', 'webp'), TRUE) && @getimagesize($this->file_temp) === FALSE) { return FALSE; } @@ -1227,7 +1227,7 @@ class CI_Upload { if (function_exists('finfo_file')) { $finfo = @finfo_open(FILEINFO_MIME); - if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system + if ($finfo !== FALSE) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system { $mime = @finfo_file($finfo, $file['tmp_name']); finfo_close($finfo); diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index a70511fc3..c144db7a8 100644 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category User Agent * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/user_agent.html + * @link https://codeigniter.com/userguide3/libraries/user_agent.html */ class CI_User_agent { @@ -498,7 +498,7 @@ class CI_User_agent { else { $referer_host = @parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); - $own_host = parse_url(config_item('base_url'), PHP_URL_HOST); + $own_host = parse_url((string) config_item('base_url'), PHP_URL_HOST); $this->referer = ($referer_host && $referer_host !== $own_host); } diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index 4e8c303c7..11d4400fe 100644 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -51,7 +51,7 @@ if ( ! function_exists('xml_parser_create')) * @subpackage Libraries * @category XML-RPC * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html */ class CI_Xmlrpc { @@ -559,7 +559,7 @@ class CI_Xmlrpc { * * @category XML-RPC * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html */ class XML_RPC_Client extends CI_Xmlrpc { @@ -780,7 +780,7 @@ class XML_RPC_Client extends CI_Xmlrpc * * @category XML-RPC * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html */ class XML_RPC_Response { @@ -1028,7 +1028,7 @@ class XML_RPC_Response * * @category XML-RPC * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html */ class XML_RPC_Message extends CI_Xmlrpc { @@ -1647,7 +1647,7 @@ class XML_RPC_Message extends CI_Xmlrpc * * @category XML-RPC * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html */ class XML_RPC_Values extends CI_Xmlrpc { @@ -1912,7 +1912,7 @@ class XML_RPC_Values extends CI_Xmlrpc */ public function iso8601_encode($time, $utc = FALSE) { - return ($utc) ? strftime('%Y%m%dT%H:%i:%s', $time) : gmstrftime('%Y%m%dT%H:%i:%s', $time); + return ($utc) ? date('Ymd\TH:i:s', $time) : gmdate('Ymd\TH:i:s', $time); } } // END XML_RPC_Values Class diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php index e70b80397..e20bf4836 100644 --- a/system/libraries/Xmlrpcs.php +++ b/system/libraries/Xmlrpcs.php @@ -56,7 +56,7 @@ if ( ! class_exists('CI_Xmlrpc', FALSE)) * @subpackage Libraries * @category XML-RPC * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/userguide3/libraries/xmlrpc.html */ class CI_Xmlrpcs extends CI_Xmlrpc { @@ -348,7 +348,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc { return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); } } - elseif (($objectCall && ! is_callable(array($method_parts[0], $method_parts[1]))) + elseif (($objectCall && ( ! method_exists($method_parts[0], $method_parts[1]) OR ! (new ReflectionMethod($method_parts[0], $method_parts[1]))->isPublic())) OR ( ! $objectCall && ! is_callable($this->methods[$methName]['function'])) ) { diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php index 094f4c802..f744493a9 100644 --- a/system/libraries/Zip.php +++ b/system/libraries/Zip.php @@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Encryption * @author EllisLab Dev Team - * @link https://codeigniter.com/user_guide/libraries/zip.html + * @link https://codeigniter.com/userguide3/libraries/zip.html */ class CI_Zip { @@ -119,7 +119,7 @@ class CI_Zip { */ public function __construct() { - isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); $this->now = time(); log_message('info', 'Zip Compression Class Initialized'); @@ -406,13 +406,14 @@ class CI_Zip { return FALSE; } - return $this->zipdata - .$this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00" + // @see https://github.com/bcit-ci/CodeIgniter/issues/5864 + $footer = $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00" .pack('v', $this->entries) // total # of entries "on this disk" .pack('v', $this->entries) // total # of entries overall .pack('V', self::strlen($this->directory)) // size of central dir .pack('V', self::strlen($this->zipdata)) // offset to start of central dir ."\x00\x00"; // .zip file comment length + return $this->zipdata.$footer; } // -------------------------------------------------------------------- diff --git a/system/libraries/index.html b/system/libraries/index.html index b702fbc39..bcb7cae34 100644 --- a/system/libraries/index.html +++ b/system/libraries/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index b4e56bdae..ada6a5998 100644 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -65,6 +65,13 @@ else is_php('5.6') && ini_set('php.internal_encoding', 'UTF-8'); +if (is_php('7.0')) +{ + $test_case_code = file_get_contents(PROJECT_BASE.'vendor/phpunit/phpunit/src/Framework/TestCase.php'); + $test_case_code = preg_replace('/^\s+((?:protected|public)(?: static)? function \w+\(\)): void/m', '$1', $test_case_code); + file_put_contents(PROJECT_BASE.'vendor/phpunit/phpunit/src/Framework/TestCase.php', $test_case_code); +} + include_once SYSTEM_PATH.'core/compat/mbstring.php'; include_once SYSTEM_PATH.'core/compat/hash.php'; include_once SYSTEM_PATH.'core/compat/password.php'; diff --git a/tests/codeigniter/Setup_test.php b/tests/codeigniter/Setup_test.php index 5317c56c7..43545822a 100644 --- a/tests/codeigniter/Setup_test.php +++ b/tests/codeigniter/Setup_test.php @@ -1,6 +1,6 @@ <?php -class Setup_test extends PHPUnit_Framework_TestCase { +class Setup_test extends \PHPUnit\Framework\TestCase { public function test_bootstrap_constants() { diff --git a/tests/codeigniter/core/Input_test.php b/tests/codeigniter/core/Input_test.php index 07a99e136..93d1b7118 100644 --- a/tests/codeigniter/core/Input_test.php +++ b/tests/codeigniter/core/Input_test.php @@ -18,6 +18,14 @@ class Input_test extends CI_TestCase { // -------------------------------------------------------------------- + public function tear_down() + { + $_POST = []; + $_GET = []; + } + + // -------------------------------------------------------------------- + public function test_get_not_exists() { $this->assertSame(array(), $this->input->get()); @@ -93,7 +101,7 @@ class Input_test extends CI_TestCase { public function test_post_get_array_notation() { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_POST['foo']['bar'] = 'baz'; + $_POST['foo'] = array('bar' => 'baz'); $barArray = array('bar' => 'baz'); $this->assertEquals('baz', $this->input->get_post('foo[bar]')); @@ -120,7 +128,7 @@ class Input_test extends CI_TestCase { public function test_get_post_array_notation() { $_SERVER['REQUEST_METHOD'] = 'GET'; - $_GET['foo']['bar'] = 'baz'; + $_GET['foo'] = array('bar' => 'baz'); $barArray = array('bar' => 'baz'); $this->assertEquals('baz', $this->input->get_post('foo[bar]')); @@ -169,7 +177,7 @@ class Input_test extends CI_TestCase { $this->assertEquals("Hello, i try to [removed]alert('Hack');[removed] your site", $harmless); $_SERVER['REQUEST_METHOD'] = 'POST'; - $_POST['foo']['bar'] = 'baz'; + $_POST['foo'] = array('bar' => 'baz'); $barArray = array('bar' => 'baz'); $this->assertEquals('baz', $this->input->post('foo[bar]')); diff --git a/tests/codeigniter/core/Loader_test.php b/tests/codeigniter/core/Loader_test.php index df698f30c..4fa6d6869 100644 --- a/tests/codeigniter/core/Loader_test.php +++ b/tests/codeigniter/core/Loader_test.php @@ -36,7 +36,8 @@ class Loader_test extends CI_TestCase { // Test loading as an array. $this->assertInstanceOf('CI_Loader', $this->load->library(array($lib))); $this->assertTrue(class_exists($class), $class.' does not exist'); - $this->assertAttributeInstanceOf($class, $lib, $this->ci_obj); + $this->assertObjectHasAttribute($lib, $this->ci_obj); + $this->assertInstanceOf($class, $this->ci_obj->$lib); // Create library in VFS $lib = array('unit_test_lib' => 'unit_test_lib'); @@ -87,14 +88,16 @@ class Loader_test extends CI_TestCase { $this->assertInstanceOf('CI_Loader', $this->load->library($lib)); $this->assertTrue(class_exists($class), $class.' does not exist'); $this->assertTrue(class_exists($ext), $ext.' does not exist'); - $this->assertAttributeInstanceOf($class, $name, $this->ci_obj); - $this->assertAttributeInstanceOf($ext, $name, $this->ci_obj); + $this->assertObjectHasAttribute($name, $this->ci_obj); + $this->assertInstanceOf($class, $this->ci_obj->$name); + $this->assertInstanceOf($ext, $this->ci_obj->$name); // Test reloading with object name $obj = 'exttest'; $this->assertInstanceOf('CI_Loader', $this->load->library($lib, NULL, $obj)); - $this->assertAttributeInstanceOf($class, $obj, $this->ci_obj); - $this->assertAttributeInstanceOf($ext, $obj, $this->ci_obj); + $this->assertObjectHasAttribute($obj, $this->ci_obj); + $this->assertInstanceOf($class, $this->ci_obj->$obj); + $this->assertInstanceOf($ext, $this->ci_obj->$obj); // Test reloading unset($this->ci_obj->$name); @@ -137,7 +140,8 @@ class Loader_test extends CI_TestCase { $obj = 'testy'; $this->assertInstanceOf('CI_Loader', $this->load->library($lib, NULL, $obj)); $this->assertTrue(class_exists($class), $class.' does not exist'); - $this->assertAttributeInstanceOf($class, $obj, $this->ci_obj); + $this->assertObjectHasAttribute($obj, $this->ci_obj); + $this->assertInstanceOf($class, $this->ci_obj->$obj); $this->assertEquals($cfg, $this->ci_obj->$obj->config); // Test is_loaded @@ -168,7 +172,8 @@ class Loader_test extends CI_TestCase { // Was the model class instantiated. $this->assertTrue(class_exists($class), $class.' does not exist'); - $this->assertAttributeInstanceOf($class, $lib, $this->ci_obj); + $this->assertObjectHasAttribute($lib, $this->ci_obj); + $this->assertInstanceOf($class, $this->ci_obj->$lib); } // -------------------------------------------------------------------- @@ -188,12 +193,14 @@ class Loader_test extends CI_TestCase { // Test loading as an array. $this->assertInstanceOf('CI_Loader', $this->load->driver(array($driver))); $this->assertTrue(class_exists($class), $class.' does not exist'); - $this->assertAttributeInstanceOf($class, $driver, $this->ci_obj); + $this->assertObjectHasAttribute($driver, $this->ci_obj); + $this->assertInstanceOf($class, $this->ci_obj->$driver); // Test loading as a library with a name $obj = 'testdrive'; $this->assertInstanceOf('CI_Loader', $this->load->library($driver, NULL, $obj)); - $this->assertAttributeInstanceOf($class, $obj, $this->ci_obj); + $this->assertObjectHasAttribute($obj, $this->ci_obj); + $this->assertInstanceOf($class, $this->ci_obj->$obj); // Test a string given to params $this->assertInstanceOf('CI_Loader', $this->load->driver($driver, ' ')); @@ -242,8 +249,9 @@ class Loader_test extends CI_TestCase { // Was the model class instantiated? $this->assertTrue(class_exists($model)); $this->assertObjectHasAttribute($name, $this->ci_obj); - $this->assertAttributeInstanceOf($base, $name, $this->ci_obj); - $this->assertAttributeInstanceOf($model, $name, $this->ci_obj); + $this->assertObjectHasAttribute($name, $this->ci_obj); + $this->assertInstanceOf($base, $this->ci_obj->$name); + $this->assertInstanceOf($model, $this->ci_obj->$name); // Test name conflict $obj = 'conflict'; @@ -586,15 +594,18 @@ class Loader_test extends CI_TestCase { // Verify library $this->assertTrue(class_exists($lib_class), $lib_class.' does not exist'); - $this->assertAttributeInstanceOf($lib_class, $lib, $this->ci_obj); + $this->assertObjectHasAttribute($lib, $this->ci_obj); + $this->assertInstanceOf($lib_class, $this->ci_obj->$lib); // Verify driver $this->assertTrue(class_exists($drv_class), $drv_class.' does not exist'); - $this->assertAttributeInstanceOf($drv_class, $drv, $this->ci_obj); + $this->assertObjectHasAttribute($drv, $this->ci_obj); + $this->assertInstanceOf($drv_class, $this->ci_obj->$drv); // Verify model $this->assertTrue(class_exists($model), $model.' does not exist'); - $this->assertAttributeInstanceOf($model, $model, $this->ci_obj); + $this->assertObjectHasAttribute($model, $this->ci_obj); + $this->assertInstanceOf($model, $this->ci_obj->$model); // Verify config calls $this->assertEquals($cfg['config'], $this->ci_obj->config->loaded); diff --git a/tests/codeigniter/core/Log_test.php b/tests/codeigniter/core/Log_test.php index 103af342b..927984385 100644 --- a/tests/codeigniter/core/Log_test.php +++ b/tests/codeigniter/core/Log_test.php @@ -57,7 +57,7 @@ class Log_test extends CI_TestCase { $format_line->setAccessible(TRUE); $this->assertEquals( $format_line->invoke($instance, 'LEVEL', 'Timestamp', 'Message'), - "LEVEL - Timestamp --> Message\n" + "LEVEL - Timestamp --> Message".PHP_EOL ); } } diff --git a/tests/codeigniter/core/Output_test.php b/tests/codeigniter/core/Output_test.php index 887c077d7..8c99c1fc5 100644 --- a/tests/codeigniter/core/Output_test.php +++ b/tests/codeigniter/core/Output_test.php @@ -8,7 +8,7 @@ class Output_test extends CI_TestCase { public function set_up() { $this->_output_data =<<<HTML - <html> + <html lang="en"> <head> <title>Basic HTML</title> </head> diff --git a/tests/codeigniter/core/Security_test.php b/tests/codeigniter/core/Security_test.php index 64efdf9c8..5132e5887 100644 --- a/tests/codeigniter/core/Security_test.php +++ b/tests/codeigniter/core/Security_test.php @@ -253,7 +253,10 @@ class Security_test extends CI_TestCase { // Perform hash $this->security->xss_hash(); - $this->assertRegExp('#^[0-9a-f]{32}$#iS', $this->security->xss_hash); + $assertRegExp = class_exists('PHPUnit_Runner_Version') + ? 'assertRegExp' + : 'assertMatchesRegularExpression'; + $this->$assertRegExp('#^[0-9a-f]{32}$#iS', $this->security->xss_hash); } // -------------------------------------------------------------------- diff --git a/tests/codeigniter/core/compat/mbstring_test.php b/tests/codeigniter/core/compat/mbstring_test.php index 415222446..39f48ac10 100644 --- a/tests/codeigniter/core/compat/mbstring_test.php +++ b/tests/codeigniter/core/compat/mbstring_test.php @@ -27,28 +27,28 @@ class mbstring_test extends CI_TestCase { // ------------------------------------------------------------------------ /** - * @depends test_boostrap + * @depends test_bootstrap */ public function test_mb_strpos() { - $this->assertEquals(ICONV_ENABLED ? 3 : 6, mb_strpos('тест', 'с')); + $this->assertEquals(ICONV_ENABLED ? 2 : 4, mb_strpos('тест', 'с')); $this->assertFalse(mb_strpos('тест', 'с', 3)); - $this->assertEquals(ICONV_ENABLED ? 3 : 6, mb_strpos('тест', 'с', 1, 'UTF-8')); + $this->assertEquals(ICONV_ENABLED ? 2 : 4, mb_strpos('тест', 'с', 1, 'UTF-8')); } // ------------------------------------------------------------------------ /** - * @depends test_boostrap + * @depends test_bootstrap */ public function test_mb_substr() { $this->assertEquals(ICONV_ENABLED ? 'стинг' : 'естинг', mb_substr('тестинг', 2)); $this->assertEquals(ICONV_ENABLED ? 'нг' : 'г', mb_substr('тестинг', -2)); $this->assertEquals(ICONV_ENABLED ? 'ст' : 'е', mb_substr('тестинг', 2, 2)); - $this->assertEquals(ICONV_ENABLED ? 'стинг' : 'естинг', mb_substr('тестинг', 2, 'UTF-8')); - $this->assertEquals(ICONV_ENABLED ? 'нг' : 'г', mb_substr('тестинг', -2, 'UTF-8')); + $this->assertEquals(ICONV_ENABLED ? 'стинг' : 'естинг', mb_substr('тестинг', 2, NULL, 'UTF-8')); + $this->assertEquals(ICONV_ENABLED ? 'нг' : 'г', mb_substr('тестинг', -2, NULL, 'UTF-8')); $this->assertEquals(ICONV_ENABLED ? 'ст' : 'е', mb_substr('тестинг', 2, 2, 'UTF-8')); } -}
\ No newline at end of file +} diff --git a/tests/codeigniter/database/query_builder/select_test.php b/tests/codeigniter/database/query_builder/select_test.php index 93b5c3d46..facda791f 100644 --- a/tests/codeigniter/database/query_builder/select_test.php +++ b/tests/codeigniter/database/query_builder/select_test.php @@ -74,7 +74,7 @@ class Select_test extends CI_TestCase { ->row(); // Average should be 2.5 - $this->assertEquals('2.5', $job_avg->id); + $this->assertEquals(2.5, (float) $job_avg->id); } // ------------------------------------------------------------------------ diff --git a/tests/codeigniter/helpers/array_helper_test.php b/tests/codeigniter/helpers/array_helper_test.php index b2409c330..f4e344673 100644 --- a/tests/codeigniter/helpers/array_helper_test.php +++ b/tests/codeigniter/helpers/array_helper_test.php @@ -38,8 +38,8 @@ class Array_helper_test extends CI_TestCase { public function test_elements() { - $this->assertInternalType('array', elements('test', $this->my_array)); - $this->assertInternalType('array', elements('foo', $this->my_array)); + $this->assertEquals('array', gettype(elements('test', $this->my_array))); + $this->assertEquals('array', gettype(elements('foo', $this->my_array))); } } diff --git a/tests/codeigniter/helpers/file_helper_test.php b/tests/codeigniter/helpers/file_helper_test.php index 5ed8cb5c0..8d7f8e1eb 100644 --- a/tests/codeigniter/helpers/file_helper_test.php +++ b/tests/codeigniter/helpers/file_helper_test.php @@ -6,10 +6,7 @@ class File_helper_Test extends CI_TestCase { { $this->helper('file'); - vfsStreamWrapper::register(); - vfsStreamWrapper::setRoot(new vfsStreamDirectory('testDir')); - - $this->_test_dir = vfsStreamWrapper::getRoot(); + $this->_test_dir = vfsStream::setup(''); } // -------------------------------------------------------------------- @@ -119,8 +116,8 @@ class File_helper_Test extends CI_TestCase { // -------------------------------------------------------------------- - public function test_write_file() - { + public function test_write_file() + { $content = 'Jack and Jill went up the mountain to fight a billy goat.'; $file = vfsStream::newFile('write.txt', 0777) @@ -129,6 +126,6 @@ class File_helper_Test extends CI_TestCase { ->at($this->_test_dir); $this->assertTrue(write_file(vfsStream::url('write.txt'), $content)); - } + } } diff --git a/tests/codeigniter/helpers/string_helper_test.php b/tests/codeigniter/helpers/string_helper_test.php index 6de336b01..4f15909ff 100644 --- a/tests/codeigniter/helpers/string_helper_test.php +++ b/tests/codeigniter/helpers/string_helper_test.php @@ -99,7 +99,7 @@ class String_helper_test extends CI_TestCase { { $this->assertEquals(16, strlen(random_string('alnum', 16))); $this->assertEquals(32, strlen(random_string('unique', 16))); - $this->assertInternalType('string', random_string('numeric', 16)); + $this->assertEquals('string', gettype(random_string('numeric', 16))); } // -------------------------------------------------------------------- diff --git a/tests/codeigniter/helpers/text_helper_test.php b/tests/codeigniter/helpers/text_helper_test.php index 36465f203..0713775da 100644 --- a/tests/codeigniter/helpers/text_helper_test.php +++ b/tests/codeigniter/helpers/text_helper_test.php @@ -64,6 +64,11 @@ class Text_helper_test extends CI_TestCase { public function test_convert_accented_characters() { + if (substr(PHP_VERSION, 0, 3) === '7.4') + { + return $this->markTestSkipped('For some reason all PHP 7.4 instances on GitHub Actions trigger a parse error when foreign_chars.php is loaded'); + } + $this->ci_vfs_clone('application/config/foreign_chars.php'); $this->assertEquals('AAAeEEEIIOOEUUUeY', convert_accented_characters('ÀÂÄÈÊËÎÏÔŒÙÛÜŸ')); $this->assertEquals('a e i o u n ue', convert_accented_characters('á é í ó ú ñ ü')); diff --git a/tests/codeigniter/libraries/Driver_test.php b/tests/codeigniter/libraries/Driver_test.php index e4401e688..ea5cfa235 100644 --- a/tests/codeigniter/libraries/Driver_test.php +++ b/tests/codeigniter/libraries/Driver_test.php @@ -5,6 +5,8 @@ */ class Driver_test extends CI_TestCase { + private $name; + /** * Set up test framework */ @@ -50,8 +52,8 @@ class Driver_test extends CI_TestCase { // Was driver loaded? $this->assertObjectHasAttribute($driver, $this->lib); - $this->assertAttributeInstanceOf($class, $driver, $this->lib); - $this->assertAttributeInstanceOf('CI_Driver', $driver, $this->lib); + $this->assertInstanceOf($class, $this->lib->$driver); + $this->assertInstanceOf('CI_Driver', $this->lib->$driver); // Was decorate called? $this->assertObjectHasAttribute($prop, $this->lib->$driver); @@ -85,8 +87,8 @@ class Driver_test extends CI_TestCase { // Was driver loaded? $this->assertObjectHasAttribute($driver, $this->lib); - $this->assertAttributeInstanceOf($class, $driver, $this->lib); - $this->assertAttributeInstanceOf('CI_Driver', $driver, $this->lib); + $this->assertInstanceOf($class, $this->lib->$driver); + $this->assertInstanceOf('CI_Driver', $this->lib->$driver); // Do we get an error for a non-existent driver? $this->setExpectedException('RuntimeException', 'CI Error: Unable to load the requested driver: CI_'. @@ -119,9 +121,9 @@ class Driver_test extends CI_TestCase { // Was driver loaded? $this->assertObjectHasAttribute($driver, $this->lib); - $this->assertAttributeInstanceOf($class, $driver, $this->lib); - $this->assertAttributeInstanceOf($baseclass, $driver, $this->lib); - $this->assertAttributeInstanceOf('CI_Driver', $driver, $this->lib); + $this->assertInstanceOf($class, $this->lib->$driver); + $this->assertInstanceOf($baseclass, $this->lib->$driver); + $this->assertInstanceOf('CI_Driver', $this->lib->$driver); // Create driver extension without base $driver = 'baseless'; diff --git a/tests/codeigniter/libraries/Encryption_test.php b/tests/codeigniter/libraries/Encryption_test.php index 8e411d9fa..68bc3d804 100644 --- a/tests/codeigniter/libraries/Encryption_test.php +++ b/tests/codeigniter/libraries/Encryption_test.php @@ -151,7 +151,7 @@ class Encryption_test extends CI_TestCase { 'hmac_key' => str_repeat("\x0", 16) ); - $this->assertInternalType('array', $this->encryption->__get_params($params)); + $this->assertEquals('array', gettype($this->encryption->__get_params($params))); $params['base64'] = TRUE; $params['hmac_digest'] = 'sha512'; @@ -217,7 +217,7 @@ class Encryption_test extends CI_TestCase { /** * encrypt(), decrypt test with custom parameters * - * @depends test___get_params + * @depends test__get_params */ public function test_encrypt_decrypt_custom() { diff --git a/tests/codeigniter/libraries/Form_validation_test.php b/tests/codeigniter/libraries/Form_validation_test.php index 04bd670ad..1bafd50c3 100644 --- a/tests/codeigniter/libraries/Form_validation_test.php +++ b/tests/codeigniter/libraries/Form_validation_test.php @@ -266,6 +266,9 @@ class Form_validation_test extends CI_TestCase { // URI scheme case-sensitivity: https://github.com/bcit-ci/CodeIgniter/pull/4758 $this->assertTrue($this->form_validation->valid_url('HtTp://127.0.0.1/')); + // https://github.com/bcit-ci/CodeIgniter/issues/5755 + $this->assertFalse($this->form_validation->valid_url('1')); + $this->assertFalse($this->form_validation->valid_url('htt://www.codeIgniter.com')); $this->assertFalse($this->form_validation->valid_url('')); $this->assertFalse($this->form_validation->valid_url('code igniter')); diff --git a/tests/codeigniter/libraries/Table_test.php b/tests/codeigniter/libraries/Table_test.php index f505a43fc..6efae5d18 100644 --- a/tests/codeigniter/libraries/Table_test.php +++ b/tests/codeigniter/libraries/Table_test.php @@ -270,14 +270,14 @@ class Table_test extends CI_TestCase { $table = $this->table->generate($data); // Test the table header - $this->assertContains('<th>Name</th>', $table); - $this->assertContains('<th>Color</th>', $table); - $this->assertContains('<th>Size</th>', $table); + $this->assertEquals(1, substr_count($table, '<th>Name</th>')); + $this->assertEquals(1, substr_count($table, '<th>Color</th>')); + $this->assertEquals(1, substr_count($table, '<th>Size</th>')); // Test the first entry - $this->assertContains('<td>Fred</td>', $table); - $this->assertContains('<td>Blue</td>', $table); - $this->assertContains('<td>Small</td>', $table); + $this->assertEquals(1, substr_count($table, '<td>Fred</td>')); + $this->assertEquals(1, substr_count($table, '<td>Blue</td>')); + $this->assertEquals(1, substr_count($table, '<td>Small</td>')); } } diff --git a/tests/codeigniter/libraries/Useragent_test.php b/tests/codeigniter/libraries/Useragent_test.php index c02f2bd9d..087544a1a 100644 --- a/tests/codeigniter/libraries/Useragent_test.php +++ b/tests/codeigniter/libraries/Useragent_test.php @@ -51,9 +51,9 @@ class UserAgent_test extends CI_TestCase { public function test_referrer() { - $_SERVER['HTTP_REFERER'] = 'http://codeigniter.com/user_guide/'; + $_SERVER['HTTP_REFERER'] = 'http://codeigniter.com/userguide3/'; $this->assertTrue($this->agent->is_referral()); - $this->assertEquals('http://codeigniter.com/user_guide/', $this->agent->referrer()); + $this->assertEquals('http://codeigniter.com/userguide3/', $this->agent->referrer()); $this->agent->referer = NULL; unset($_SERVER['HTTP_REFERER']); diff --git a/tests/mocks/autoloader.php b/tests/mocks/autoloader.php index a912327ca..4dd53d4af 100644 --- a/tests/mocks/autoloader.php +++ b/tests/mocks/autoloader.php @@ -47,10 +47,10 @@ function autoload($class) 'Profiler', 'Table', 'Trackback', - 'Typography', + 'Typography', 'Unit_test', 'Upload', - 'User_agent', + 'User_agent', 'Xmlrpc', 'Zip' ); diff --git a/tests/mocks/ci_testcase.php b/tests/mocks/ci_testcase.php index 4f478fb4e..de46f6df6 100644 --- a/tests/mocks/ci_testcase.php +++ b/tests/mocks/ci_testcase.php @@ -1,6 +1,6 @@ <?php -class CI_TestCase extends PHPUnit_Framework_TestCase { +class CI_TestCase extends \PHPUnit\Framework\TestCase { public $ci_vfs_root; public $ci_app_root; @@ -35,7 +35,7 @@ class CI_TestCase extends PHPUnit_Framework_TestCase { public function setUp() { // Setup VFS with base directories - $this->ci_vfs_root = vfsStream::setup(); + $this->ci_vfs_root = vfsStream::setup(''); $this->ci_app_root = vfsStream::newDirectory('application')->at($this->ci_vfs_root); $this->ci_base_root = vfsStream::newDirectory('system')->at($this->ci_vfs_root); $this->ci_view_root = vfsStream::newDirectory('views')->at($this->ci_app_root); @@ -241,7 +241,7 @@ class CI_TestCase extends PHPUnit_Framework_TestCase { $dir_root = $root->getChild($dir); if ($dir_root) { - // Yes - recurse into subdir + // Yes - recurse into subdir $root = $dir_root; } else @@ -381,4 +381,18 @@ class CI_TestCase extends PHPUnit_Framework_TestCase { return parent::__call($method, $args); } + public function setExpectedException($exception_class, $exception_message = '', $exception_code = null) + { + $use_expect_exception = method_exists($this, 'expectException'); + + if ($use_expect_exception) + { + $this->expectException($exception_class); + $exception_message !== '' && $this->expectExceptionMessage($exception_message); + } + else + { + parent::setExpectedException($exception_class, $exception_message, $exception_code); + } + } } diff --git a/tests/mocks/database/ci_test.sqlite b/tests/mocks/database/ci_test.sqlite Binary files differindex 574d3ae53..721fbd525 100755 --- a/tests/mocks/database/ci_test.sqlite +++ b/tests/mocks/database/ci_test.sqlite diff --git a/tests/mocks/database/config/mysql.php b/tests/mocks/database/config/mysql.php index a590b9f53..ca30cb9ca 100644 --- a/tests/mocks/database/config/mysql.php +++ b/tests/mocks/database/config/mysql.php @@ -5,9 +5,9 @@ return array( // Typical Database configuration 'mysql' => array( 'dsn' => '', - 'hostname' => 'localhost', + 'hostname' => '127.0.0.1', 'username' => 'travis', - 'password' => '', + 'password' => 'travis', 'database' => 'ci_test', 'dbdriver' => 'mysql' ), @@ -15,7 +15,7 @@ return array( // Database configuration with failover 'mysql_failover' => array( 'dsn' => '', - 'hostname' => 'localhost', + 'hostname' => '127.0.0.1', 'username' => 'not_travis', 'password' => 'wrong password', 'database' => 'not_ci_test', @@ -23,9 +23,9 @@ return array( 'failover' => array( array( 'dsn' => '', - 'hostname' => 'localhost', + 'hostname' => '127.0.0.1', 'username' => 'travis', - 'password' => '', + 'password' => 'travis', 'database' => 'ci_test', 'dbdriver' => 'mysql', ) diff --git a/tests/mocks/database/config/mysqli.php b/tests/mocks/database/config/mysqli.php index 5dd08abb2..fd8fec962 100644 --- a/tests/mocks/database/config/mysqli.php +++ b/tests/mocks/database/config/mysqli.php @@ -5,9 +5,9 @@ return array( // Typical Database configuration 'mysqli' => array( 'dsn' => '', - 'hostname' => 'localhost', + 'hostname' => '127.0.0.1', 'username' => 'travis', - 'password' => '', + 'password' => 'travis', 'database' => 'ci_test', 'dbdriver' => 'mysqli' ), @@ -15,7 +15,7 @@ return array( // Database configuration with failover 'mysqli_failover' => array( 'dsn' => '', - 'hostname' => 'localhost', + 'hostname' => '127.0.0.1', 'username' => 'not_travis', 'password' => 'wrong password', 'database' => 'not_ci_test', @@ -23,9 +23,9 @@ return array( 'failover' => array( array( 'dsn' => '', - 'hostname' => 'localhost', + 'hostname' => '127.0.0.1', 'username' => 'travis', - 'password' => '', + 'password' => 'travis', 'database' => 'ci_test', 'dbdriver' => 'mysqli', ) diff --git a/tests/mocks/database/config/pdo/mysql.php b/tests/mocks/database/config/pdo/mysql.php index 96608f787..89e9fb130 100644 --- a/tests/mocks/database/config/pdo/mysql.php +++ b/tests/mocks/database/config/pdo/mysql.php @@ -4,10 +4,10 @@ return array( // Typical Database configuration 'pdo/mysql' => array( - 'dsn' => 'mysql:host=localhost;dbname=ci_test', - 'hostname' => 'localhost', + 'dsn' => 'mysql:host=127.0.0.1;dbname=ci_test', + 'hostname' => '127.0.0.1', 'username' => 'travis', - 'password' => '', + 'password' => 'travis', 'database' => 'ci_test', 'dbdriver' => 'pdo', 'subdriver' => 'mysql' @@ -16,7 +16,7 @@ return array( // Database configuration with failover 'pdo/mysql_failover' => array( 'dsn' => '', - 'hostname' => 'localhost', + 'hostname' => '127.0.0.1', 'username' => 'not_travis', 'password' => 'wrong password', 'database' => 'not_ci_test', @@ -24,10 +24,10 @@ return array( 'subdriver' => 'mysql', 'failover' => array( array( - 'dsn' => 'mysql:host=localhost;dbname=ci_test', - 'hostname' => 'localhost', + 'dsn' => 'mysql:host=127.0.0.1;dbname=ci_test', + 'hostname' => '127.0.0.1', 'username' => 'travis', - 'password' => '', + 'password' => 'travis', 'database' => 'ci_test', 'dbdriver' => 'pdo', 'subdriver' => 'mysql' diff --git a/tests/mocks/database/config/pdo/pgsql.php b/tests/mocks/database/config/pdo/pgsql.php index e55e3ea77..846c70be9 100644 --- a/tests/mocks/database/config/pdo/pgsql.php +++ b/tests/mocks/database/config/pdo/pgsql.php @@ -7,7 +7,7 @@ return array( 'dsn' => 'pgsql:host=localhost;port=5432;dbname=ci_test;', 'hostname' => 'localhost', 'username' => 'postgres', - 'password' => '', + 'password' => 'postgres', 'database' => 'ci_test', 'dbdriver' => 'pdo', 'subdriver' => 'pgsql' @@ -27,7 +27,7 @@ return array( 'dsn' => 'pgsql:host=localhost;port=5432;dbname=ci_test;', 'hostname' => 'localhost', 'username' => 'postgres', - 'password' => '', + 'password' => 'postgres', 'database' => 'ci_test', 'dbdriver' => 'pdo', 'subdriver' => 'pgsql' diff --git a/tests/mocks/database/config/pgsql.php b/tests/mocks/database/config/pgsql.php index 1444b0066..ce4583728 100644 --- a/tests/mocks/database/config/pgsql.php +++ b/tests/mocks/database/config/pgsql.php @@ -7,7 +7,7 @@ return array( 'dsn' => '', 'hostname' => 'localhost', 'username' => 'postgres', - 'password' => '', + 'password' => 'postgres', 'database' => 'ci_test', 'dbdriver' => 'postgre' ), @@ -25,7 +25,7 @@ return array( 'dsn' => '', 'hostname' => 'localhost', 'username' => 'postgres', - 'password' => '', + 'password' => 'postgres', 'database' => 'ci_test', 'dbdriver' => 'postgre', ) diff --git a/tests/mocks/database/schema/skeleton.php b/tests/mocks/database/schema/skeleton.php index 888236ff3..e2b6e7d0e 100644 --- a/tests/mocks/database/schema/skeleton.php +++ b/tests/mocks/database/schema/skeleton.php @@ -76,7 +76,7 @@ class Mock_Database_Schema_Skeleton { ) )); self::$forge->add_key('id', TRUE); - self::$forge->create_table('user', TRUE); + self::$forge->create_table('user', TRUE) OR show_error('Unable to create the `user` table'); // Job Table self::$forge->add_field(array( @@ -93,7 +93,7 @@ class Mock_Database_Schema_Skeleton { ) )); self::$forge->add_key('id', TRUE); - self::$forge->create_table('job', TRUE); + self::$forge->create_table('job', TRUE) OR show_error('Unable to create the `job` table'); // Misc Table self::$forge->add_field(array( @@ -110,7 +110,7 @@ class Mock_Database_Schema_Skeleton { ) )); self::$forge->add_key('id', TRUE); - self::$forge->create_table('misc', TRUE); + self::$forge->create_table('misc', TRUE) OR show_error('Unable to create the `misc` table'); } /** @@ -143,11 +143,11 @@ class Mock_Database_Schema_Skeleton { foreach ($data as $table => $dummy_data) { - self::$db->truncate($table); + self::$db->truncate($table) OR show_error("Unable to truncate `{$table}` table"); foreach ($dummy_data as $single_dummy_data) { - self::$db->insert($table, $single_dummy_data); + self::$db->insert($table, $single_dummy_data) OR show_error("Unable to insert data into `{$table}` table"); } } } diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 875198c4e..a1626ce91 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -8,7 +8,8 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false"> <testsuites> <testsuite name="CodeIgniter Core Test Suite"> <directory suffix="test.php">./codeigniter/core</directory> diff --git a/tests/travis/mysql.phpunit.xml b/tests/travis/mysql.phpunit.xml index 06d4a011b..15063fd5a 100644 --- a/tests/travis/mysql.phpunit.xml +++ b/tests/travis/mysql.phpunit.xml @@ -8,7 +8,8 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false"> <php> <const name="DB_DRIVER" value="mysql"/> </php> diff --git a/tests/travis/mysqli.phpunit.xml b/tests/travis/mysqli.phpunit.xml index 1364f8bfa..c77aaa303 100644 --- a/tests/travis/mysqli.phpunit.xml +++ b/tests/travis/mysqli.phpunit.xml @@ -8,7 +8,8 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false"> <php> <const name="DB_DRIVER" value="mysqli"/> </php> diff --git a/tests/travis/pdo/mysql.phpunit.xml b/tests/travis/pdo/mysql.phpunit.xml index 7121edc45..1a9030ddf 100644 --- a/tests/travis/pdo/mysql.phpunit.xml +++ b/tests/travis/pdo/mysql.phpunit.xml @@ -8,7 +8,8 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false"> <php> <const name="DB_DRIVER" value="pdo/mysql"/> </php> diff --git a/tests/travis/pdo/pgsql.phpunit.xml b/tests/travis/pdo/pgsql.phpunit.xml index df3ff986e..22261ee7d 100644 --- a/tests/travis/pdo/pgsql.phpunit.xml +++ b/tests/travis/pdo/pgsql.phpunit.xml @@ -8,7 +8,8 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false"> <php> <const name="DB_DRIVER" value="pdo/pgsql"/> </php> diff --git a/tests/travis/pdo/sqlite.phpunit.xml b/tests/travis/pdo/sqlite.phpunit.xml index 7d867f6d1..4b0ca2fe7 100644 --- a/tests/travis/pdo/sqlite.phpunit.xml +++ b/tests/travis/pdo/sqlite.phpunit.xml @@ -8,7 +8,8 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false"> <php> <const name="DB_DRIVER" value="pdo/sqlite"/> </php> diff --git a/tests/travis/pgsql.phpunit.xml b/tests/travis/pgsql.phpunit.xml index bfddbf6b5..8d7979a0f 100644 --- a/tests/travis/pgsql.phpunit.xml +++ b/tests/travis/pgsql.phpunit.xml @@ -8,7 +8,8 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false"> <php> <const name="DB_DRIVER" value="pgsql"/> </php> diff --git a/tests/travis/sqlite.phpunit.xml b/tests/travis/sqlite.phpunit.xml index 75c946aee..4eaafc19f 100644 --- a/tests/travis/sqlite.phpunit.xml +++ b/tests/travis/sqlite.phpunit.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> - -<phpunit +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="../Bootstrap.php" colors="true" convertNoticesToExceptions="true" @@ -8,18 +7,21 @@ stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" - stopOnSkipped="false"> - <php> - <const name="DB_DRIVER" value="sqlite"/> - </php> - <testsuites> - <testsuite name="CodeIgniter Core Test Suite"> - <directory suffix="test.php">../codeigniter</directory> - </testsuite> - </testsuites> - <filter> - <whitelist addUncoveredFilesFromWhitelist="false"> - <directory suffix=".php">../../system</directory> - </whitelist> - </filter> -</phpunit>
\ No newline at end of file + stopOnSkipped="false" + beStrictAboutTestsThatDoNotTestAnything="false" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" +> + <coverage includeUncoveredFiles="false"> + <include> + <directory suffix=".php">../../system</directory> + </include> + </coverage> + <php> + <const name="DB_DRIVER" value="sqlite"/> + </php> + <testsuites> + <testsuite name="CodeIgniter Core Test Suite"> + <directory suffix="test.php">../codeigniter</directory> + </testsuite> + </testsuites> +</phpunit> diff --git a/user_guide_src/source/_themes/sphinx_rtd_theme/static/css/theme.css b/user_guide_src/source/_themes/sphinx_rtd_theme/static/css/theme.css index 64d41142a..fe7e2cbcc 100644 --- a/user_guide_src/source/_themes/sphinx_rtd_theme/static/css/theme.css +++ b/user_guide_src/source/_themes/sphinx_rtd_theme/static/css/theme.css @@ -1,5 +1,5 @@ *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:1.5cm 0.5cm 2.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.1.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.1.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.1.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.pull-left.icon{margin-right:.3em}.fa.pull-right,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-square:before,.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .icon,.nav .fa,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .icon{display:inline}.btn .fa.fa-large,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#dedede}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#8ba8af;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#dedede}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#8ba8af}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dedede}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#dd4814}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#dd4814}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#dd4814}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#dd4814 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#dd4814;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#97310e}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#dd4814;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#dd4814;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#f3f6f6;color:#cad2d3}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fff;color:#cad2d3;border-color:transparent}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#dd4814}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}a{color:#dd4814;text-decoration:none;cursor:pointer}a:hover{color:#97310e}a:visited{color:#97310e}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#dd4814 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#97310e;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#dd4814;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:active{background-color:#dd4814;cursor:pointer;color:#fff}.wy-side-nav-search{z-index:200;background-color:#dd4814;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#97310e}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#dd4814;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-nav .wy-menu-vertical header{color:#dd4814}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#dd4814;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:absolute;top:0;left:0;width:300px;overflow:hidden;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#dd4814;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#dd4814;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100x;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}nav.stickynav{position:fixed;top:0}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#dd4814;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt{color:#000}.rst-content tt big,.rst-content tt em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt{font-weight:bold}.rst-content a tt{color:#dd4814}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#dedede;color:#dd4814;border-top:solid 3px #8ba8af;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#8ba8af}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center} + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.1.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.1.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.1.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.pull-left.icon{margin-right:.3em}.fa.pull-right,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-square:before,.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .icon,.nav .fa,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .icon{display:inline}.btn .fa.fa-large,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#dedede}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#8ba8af;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#dedede}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#8ba8af}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dedede}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#dd4814}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#dd4814}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#dd4814}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#dd4814 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#dd4814;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#97310e}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#dd4814;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#dd4814;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#f3f6f6;color:#cad2d3}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fff;color:#cad2d3;border-color:transparent}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#dd4814}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}a{color:#dd4814;text-decoration:none;cursor:pointer}a:hover{color:#97310e}a:visited{color:#97310e}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#dd4814 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#97310e;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#dd4814;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:active{background-color:#dd4814;cursor:pointer;color:#fff}.wy-side-nav-search{z-index:200;background-color:#dd4814;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#97310e}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#dd4814;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-nav .wy-menu-vertical header{color:#dd4814}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#dd4814;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:absolute;top:0;left:0;width:300px;overflow:hidden;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#dd4814;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#dd4814;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100x;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0!important}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}nav.stickynav{position:fixed;top:0}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#dd4814;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt{color:#000}.rst-content tt big,.rst-content tt em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt{font-weight:bold}.rst-content a tt{color:#dd4814}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#dedede;color:#dd4814;border-top:solid 3px #8ba8af;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#8ba8af}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center} /*# sourceMappingURL=theme.css.map */ diff --git a/user_guide_src/source/_themes/sphinx_rtd_theme/static/js/theme.js b/user_guide_src/source/_themes/sphinx_rtd_theme/static/js/theme.js index 081d77bdf..911dad29b 100644 --- a/user_guide_src/source/_themes/sphinx_rtd_theme/static/js/theme.js +++ b/user_guide_src/source/_themes/sphinx_rtd_theme/static/js/theme.js @@ -22,31 +22,34 @@ $(document).ready(function () { $('#openToc').click(function () { $('#nav').slideToggle(); }); - $('#closeMe').toggle( - function () - { + $('#closeMe').click(function () { + if (getCookie('ciNav') != 'yes') { setCookie('ciNav', 'yes', 365); + } else { + setCookie('ciNav', 'no', 365); + } + tocFlip(); + }); + var tocFlip = function(){ + if (getCookie('ciNav') == 'yes') { $('#nav2').show(); $('#topMenu').remove(); - $('body').css({background: 'none'}); - $('.wy-nav-content-wrap').css({background: 'none', 'margin-left': 0}); + $('body').css({ background: 'none' }); + $('.wy-nav-content-wrap').css({ background: 'none', 'margin-left': 0 }); $('.wy-breadcrumbs').append('<div style="float:right;"><div style="float:left;" id="topMenu">' + $('.wy-form').parent().html() + '</div></div>'); $('.wy-nav-side').toggle(); - }, - function () - { - setCookie('ciNav', 'no', 365); + } else { $('#topMenu').remove(); $('#nav').hide(); $('#nav2').hide(); - $('body').css({background: '#edf0f2;'}); - $('.wy-nav-content-wrap').css({background: 'none repeat scroll 0 0 #fcfcfc;', 'margin-left': '300px'}); + $('body').css({ background: '#edf0f2;' }); + $('.wy-nav-content-wrap').css({ background: 'none repeat scroll 0 0 #fcfcfc;', 'margin-left': '300px' }); $('.wy-nav-side').show(); } - ); + }; if (getCookie('ciNav') == 'yes') { - $('#closeMe').trigger('click'); + tocFlip(); //$('#nav').slideToggle(); } // END MODIFICATION --- diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 9d6bce4c7..704652381 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -37,7 +37,7 @@ Release Date: Not Released - Removed previously deprecated *Cart Library*. - Removed previously deprecated *Javascript Library* (it was always experimental in the first place). - - Added UNIX socket connection support to :doc:`Session Library <libraries/sessions>` 'redis' driver. + - Added TLS and UNIX socket connection support to :doc:`Session Library <libraries/sessions>` 'redis' driver. - Updated :doc:`ZIP Library <libraries/zip>` method ``read_dir()`` to include hidden (dot-prefixed) files. - :doc:`Cache Library <libraries/caching>` changes include: @@ -72,9 +72,11 @@ Release Date: Not Released - Added option to change the output filename via the ``new_name`` option when rendering images with ``dynamic_output``. - Updated to serve multibyte filenames when rendering images with ``dynamic_output``, if possible. + - Added WebP image support. - :doc:`Database <database/index>` changes include: + - Removed driver-specific ``$curs_id`` property and ``get_cursor()``, ``stored_procedure()`` methods from OCI8 driver. - Removed previously deprecated 'sqlite' driver (used for SQLite version 2; no longer shipped with PHP 5.4+). - Removed method ``db_set_charset()`` and the ability to change a connection character set at runtime. - Changed method ``initialize()`` to return void and instead throw a ``RuntimeException`` in case of failure. @@ -87,6 +89,7 @@ Release Date: Not Released - :doc:`Query Builder <database/query_builder>`: - Added methods ``having_in()``, ``or_having_in()``, ``not_having_in()``, ``or_not_having_in()``. + - Updated methods ``where_in()``, ``or_where_in()``, ``not_where_in()``, ``or_not_where_in()`` to reject non-array inputs for the second parameter. - Updated method ``join()`` to allow accepting ``NATURAL`` clauses in its third parameter. - Updated logic to allow dots in alias names. @@ -125,15 +128,71 @@ Release Date: Not Released - :doc:`CAPTCHA Helper <helpers/captcha_helper>` changes include: - Added 'img_alt' option with a default value of 'captcha'. + - Added 'img_class' option. - Added ability to generate ``data:image/png;base64`` URIs instead of writing image files to disk. - Updated to always create PNG images instead of JPEG. -Version 3.1.11 +Version 3.1.12 ============== Release Date: Not Released +- General Changes + + - Improved logging of error conditions in :doc:`CAPTCHA Helper <helpers/captcha_helper>` function :php:func:`create_captcha()`. + - Added ``AUTO_INCREMENT`` support for Oracle 12.1+ to :doc:`Database Forge <database/forge>`. + - Added ``FULL [OUTER] JOIN`` support to :doc:`Query Builder <database/query_builder>`. + - Added support for detecting WebP image type to :doc:`File Uploading Library <libraries/file_uploading>`. + - Added method :doc:`Database Library <database/index>` method ``trans_active()`` to expose transaction state. + - Updated :doc:`Database Library <database/index>` 'pdo' driver to attempt to free resources in order to allow connections to be closed. + - Added ``SameSite=Strict`` attribute to the CSRF cookie sent by the :doc:`Security Class <libraries/security>`. + - Added ``$config['cookie_samesite']`` option and ``$samesite`` parameter to :doc:`Input Library <libraries/input>` method ``set_cookie()``. + - Added ``SameSite`` support through ``$config['sess_samesite']`` option to the :doc:`Session Library <libraries/sessions>`. + - Added a wrapper class around :doc:`Session <libraries/sessions>` drivers to deal with compatibility between PHP 8.1 and older versions. + - Updated a lot of code for PHP 8.0 and 8.1 compatibility. + +Bug fixes for 3.1.12 +==================== + +- Fixed a bug (#5834) - :doc:`Query Builder <database/query_builder>` method ``count_all_results()`` triggered an SQL error for queries with a ``HAVING`` clause. +- Fixed a bug (#5840) - :doc:`Cache Library <libraries/caching>` 'redis' driver triggered an ``E_DEPRECATED`` warning about ``sRemove()`` with phpRedis 5. +- Fixed a bug (#5857) - :doc:`Session <libraries/sessions>` data could be corrupted after a concurrent request write with the 'files' driver due to a filesize cache being incorrect. +- Fixed a bug (#5861) - :doc:`Cache Library <libraries/caching>` 'redis' driver would always use phpRedis 5 ``del()`` due to an incorrect version check. +- Fixed a bug (#5879) - :doc:`Profiler Library <general/profiling>` triggered an ``E_DEPRECATED`` warning on PHP 7.4+. +- Fixed a bug (#5901) - :doc:`Database Library <database/index>` methods ``list_fields()`` and ``field_data()`` ignored the configured table schema on PostgreSQL. +- Fixed a bug (#5906) - :doc:`Database Library <database/index>` 'postgre' driver couldn't use the failover feature without a ``$config['dsn']``. +- Fixed a bug (#5903) - :doc:`common function <general/common_functions>` :php:func:`set_status_header()` didn't recognize 'HTTP/2.0' as a valid ``$_SERVER['SERVER_PROTOCOL']``. +- Fixed a bug (#6013) - :doc:`Session <libraries/sessions>` flashdata didn't work on PHP 8. +- Fixed a bug (#6006) - ``is_callable()`` change in PHP 8 broke :doc:`Migrations <libraries/migration>`, a part of :doc:`XML-RPC <libraries/xmlrpc>` and an edge case in 404 detection logic. + +Version 3.1.11 +============== + +Release Date: Sep 19, 2019 + +- General Changes + + - Changed ``CI_Log`` to append ``PHP_EOL`` instead of ``\n`` at the end of log messages. + - Improved performance in :doc:`Cache Library <libraries/caching>` 'redis' driver with non-scalar variables. + - Altered the :doc:`Session Library <libraries/sessions>` 'files' driver to log error and trigger a session start failure instead of throwing an ``Exception`` in case of unusable ``$config['sess_save_path']``. + - Updated the :doc:`Session <libraries/sessions>` and :doc:`Cache <libraries/caching>` libraries' 'redis' driver to work with phpRedis 5. + +Bug fixes for 3.1.11 +-------------------- +- Fixed a bug (#5681) - :doc:`Database Forge <database/forge>` method ``modify_column()`` produced erroneous SQL for ``DEFAULT`` attribute changes under PostgreSQL, Firebird. +- Fixed a bug (#5692) - :doc:`Database Forge <database/forge>` didn't handle column nullability with the 'oci8', 'pdo/oci' drivers. +- Fixed a bug (#5701) - :doc:`Database <database/index>` driver 'pdo/pgsql' produced incorrect DSNs when constructing from a configuration array. +- Fixed a bug (#5708) - :doc:`Session Library <libraries/sessions>` 'redis' driver too often failed with locking-related errors that could've been avoided. +- Fixed a bug (#5703) - :doc:`Session Library <libraries/sessions>` triggered an ``E_WARNING`` message about changing ``session.save_path`` during an active session when it fails to obtain a lock. +- Fixed a bug where :doc:`Session Library <libraries/sessions>` 'database' driver didn't trigger a failure if it can't obtain a lock. +- Fixed a bug (#5755) - :doc:`Form Validation Library <libraries/form_validation>` rule **valid_url** accepted digit-only domains due to a PHP bug. +- Fixed a bug (#5753) - :doc:`Cache Library <libraries/caching>` 'redis' driver methods ``increment()``, ``decrement()`` ignored their ``$offset`` parameter. +- Fixed a bug (#5779) - :doc:`Session Library <libraries/sessions>` 'redis' only attempted to validate session IDs in case the connection to Redis failed. +- Fixed a bug (#5774) - :doc:`Database Results <database/results>` method ``custom_result_object()`` didn't properly handle empty result sets, triggering ``E_WARNING`` messages on PHP 7.2+. +- Fixed a bug (#5788) - :doc:`Database Results <database/results>` method ``field_data()`` triggered an ``E_NOTICE`` error with PDO when a field type is not recognized by PHP. +- Fixed a bug (#5796) - :doc:`Query Builder <database/query_builder>` method ``list_tables()`` triggered an SQL syntax error under MySQL when the database schema is a numeric string. +- Fixed a bug where :doc:`Security Class <libraries/security>` would trigger an ``E_WARNING`` if CSRF inputs are arrays instead of strings. Version 3.1.10 ============== diff --git a/user_guide_src/source/database/db_driver_reference.rst b/user_guide_src/source/database/db_driver_reference.rst index c240526e0..8a4f56784 100644 --- a/user_guide_src/source/database/db_driver_reference.rst +++ b/user_guide_src/source/database/db_driver_reference.rst @@ -156,11 +156,18 @@ This article is intended to be a reference for them. .. php:method:: trans_status() - :returns: TRUE if the transaction succeeded, FALSE if it failed + :returns: TRUE if the transaction succeeded, FALSE if it failed :rtype: bool Lets you retrieve the transaction status flag to determine if it has failed. + + .. php:method:: trans_active() + + :returns: TRUE if a transaction is active, FALSE if not + :rtype: bool + + Determines if a transaction is currently active. .. php:method:: compile_binds($sql, $binds) diff --git a/user_guide_src/source/database/forge.rst b/user_guide_src/source/database/forge.rst index 5af4f2248..c6cacb1b0 100644 --- a/user_guide_src/source/database/forge.rst +++ b/user_guide_src/source/database/forge.rst @@ -370,7 +370,7 @@ Class Reference .. php:method:: drop_column($table, $column_name) :param string $table: Table name - :param array $column_name: The column name to drop + :param string $column_name: The column name to drop :returns: TRUE on success, FALSE on failure :rtype: bool diff --git a/user_guide_src/source/database/query_builder.rst b/user_guide_src/source/database/query_builder.rst index a33c7073b..a085de293 100644 --- a/user_guide_src/source/database/query_builder.rst +++ b/user_guide_src/source/database/query_builder.rst @@ -199,7 +199,7 @@ query. If you need a specific type of JOIN you can specify it via the third parameter of the function. Options are: left, right, outer, inner, left -outer, and right outer. +outer, right outer and full outer. :: @@ -1281,7 +1281,7 @@ Class Reference Generates the WHERE portion of the query. Separates multiple calls with 'OR'. - .. php:method:: or_where_in([$key = NULL[, $values = NULL[, $escape = NULL]]]) + .. php:method:: or_where_in([$key[, array $values[, $escape = NULL]]]) :param string $key: The field to search :param array $values: The values searched on @@ -1292,7 +1292,7 @@ Class Reference Generates a WHERE field IN('item', 'item') SQL query, joined with 'OR' if appropriate. - .. php:method:: or_where_not_in([$key = NULL[, $values = NULL[, $escape = NULL]]]) + .. php:method:: or_where_not_in([$key[, array $values[, $escape = NULL]]]) :param string $key: The field to search :param array $values: The values searched on @@ -1303,7 +1303,7 @@ Class Reference Generates a WHERE field NOT IN('item', 'item') SQL query, joined with 'OR' if appropriate. - .. php:method:: where_in([$key = NULL[, $values = NULL[, $escape = NULL]]]) + .. php:method:: where_in([$key[, array $values[, $escape = NULL]]]) :param string $key: Name of field to examine :param array $values: Array of target values @@ -1314,7 +1314,7 @@ Class Reference Generates a WHERE field IN('item', 'item') SQL query, joined with 'AND' if appropriate. - .. php:method:: where_not_in([$key = NULL[, $values = NULL[, $escape = NULL]]]) + .. php:method:: where_not_in([$key[, array $values[, $escape = NULL]]]) :param string $key: Name of field to examine :param array $values: Array of target values @@ -1424,6 +1424,50 @@ Class Reference Adds a HAVING clause to a query, separating multiple calls with OR. + .. php:method:: or_having_in([$key[, array $values[, $escape = NULL]]]) + + :param string $key: The field to search + :param array $values: The values searched on + :param bool $escape: Whether to escape values and identifiers + :returns: DB_query_builder instance + :rtype: object + + Generates a HAVING field IN('item', 'item') SQL query, + joined with 'OR' if appropriate. + + .. php:method:: or_having_not_in([$key[, array $values[, $escape = NULL]]]) + + :param string $key: The field to search + :param array $values: The values searched on + :param bool $escape: Whether to escape values and identifiers + :returns: DB_query_builder instance + :rtype: object + + Generates a HAVING field NOT IN('item', 'item') SQL query, + joined with 'OR' if appropriate. + + .. php:method:: having_in([$key[, array $values[, $escape = NULL]]]) + + :param string $key: Name of field to examine + :param array $values: Array of target values + :param bool $escape: Whether to escape values and identifiers + :returns: DB_query_builder instance + :rtype: object + + Generates a HAVING field IN('item', 'item') SQL query, + joined with 'AND' if appropriate. + + .. php:method:: having_not_in([$key[, array $values[, $escape = NULL]]]) + + :param string $key: Name of field to examine + :param array $values: Array of target values + :param bool $escape: Whether to escape values and identifiers + :returns: DB_query_builder instance + :rtype: object + + Generates a HAVING field NOT IN('item', 'item') SQL query, + joined with 'AND' if appropriate. + .. php:method:: group_by($by[, $escape = NULL]) :param mixed $by: Field(s) to group by; string or array diff --git a/user_guide_src/source/general/views.rst b/user_guide_src/source/general/views.rst index 2fc0cb2ca..b84e85399 100644 --- a/user_guide_src/source/general/views.rst +++ b/user_guide_src/source/general/views.rst @@ -22,7 +22,7 @@ Creating a View Using your text editor, create a file called blogview.php, and put this in it:: - <html> + <html lang="en"> <head> <title>My Blog</title> </head> @@ -138,7 +138,7 @@ Let's try it with your controller file. Open it add this code:: Now open your view file and change the text to variables that correspond to the array keys in your data:: - <html> + <html lang="en"> <head> <title><?php echo $title;?></title> </head> @@ -176,7 +176,7 @@ Here's a simple example. Add this to your controller:: Now open your view file and create a loop:: - <html> + <html lang="en"> <head> <title><?php echo $title;?></title> </head> @@ -210,4 +210,4 @@ some way. If you set the parameter to TRUE (boolean) it will return data. The default behavior is false, which sends it to your browser. Remember to assign it to a variable if you want the data returned:: - $string = $this->load->view('myfile', '', TRUE);
\ No newline at end of file + $string = $this->load->view('myfile', '', TRUE); diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst index 43a20e18c..50cda2ed4 100644 --- a/user_guide_src/source/helpers/form_helper.rst +++ b/user_guide_src/source/helpers/form_helper.rst @@ -380,7 +380,7 @@ The following functions are available: <fieldset> <legend>Address Information</legend> - <p>form content here</p> + <p>fieldset content here</p> </fieldset> */ @@ -401,7 +401,7 @@ The following functions are available: <fieldset id="address_info" class="address_info"> <legend>Address Information</legend> - <p>form content here</p> + <p>fieldset content here</p> </fieldset> */ diff --git a/user_guide_src/source/installation/downloads.rst b/user_guide_src/source/installation/downloads.rst index 428ae3ab2..de9a22a58 100644 --- a/user_guide_src/source/installation/downloads.rst +++ b/user_guide_src/source/installation/downloads.rst @@ -3,7 +3,8 @@ Downloading CodeIgniter ####################### - `CodeIgniter v3.2.0-dev (Current version) <https://codeload.github.com/bcit-ci/CodeIgniter/zip/develop>`_ -- `CodeIgniter v3.1.11-dev <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1-stable>`_ +- `CodeIgniter v3.1.12-dev <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1-stable>`_ +- `CodeIgniter v3.1.11 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.11>`_ - `CodeIgniter v3.1.10 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.10>`_ - `CodeIgniter v3.1.9 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.9>`_ - `CodeIgniter v3.1.8 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.8>`_ diff --git a/user_guide_src/source/installation/upgrade_150.rst b/user_guide_src/source/installation/upgrade_150.rst index 50eb5eae5..527e4548d 100644 --- a/user_guide_src/source/installation/upgrade_150.rst +++ b/user_guide_src/source/installation/upgrade_150.rst @@ -49,8 +49,8 @@ Open your application/config/config.php file and ADD these new items:: | This item allows you to set the filename/classname prefix when extending | native libraries. For more information please see the user guide: | - | https://codeigniter.com/user_guide/general/core_classes.html - | https://codeigniter.com/user_guide/general/creating_libraries.html + | https://codeigniter.com/userguide3/general/core_classes.html + | https://codeigniter.com/userguide3/general/creating_libraries.html | */ $config['subclass_prefix'] = 'MY_'; diff --git a/user_guide_src/source/installation/upgrade_3111.rst b/user_guide_src/source/installation/upgrade_3111.rst index 5463e40c1..5dd02efdc 100644 --- a/user_guide_src/source/installation/upgrade_3111.rst +++ b/user_guide_src/source/installation/upgrade_3111.rst @@ -12,3 +12,9 @@ Replace all files and directories in your *system/* directory. .. note:: If you have any custom developed files in these directories, please make copies of them first. + +Step 2: Replace config/mimes.php +================================ + +This config file has received some updates. Please copy it to +*application/config/mimes.php*. diff --git a/user_guide_src/source/installation/upgrade_3112.rst b/user_guide_src/source/installation/upgrade_3112.rst new file mode 100644 index 000000000..93bcc43d3 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_3112.rst @@ -0,0 +1,26 @@ +############################### +Upgrading from 3.1.11 to 3.1.12 +############################### + +Before performing an update you should take your site offline by +replacing the index.php file with a static one. + +Step 1: Update your CodeIgniter files +===================================== + +Replace all files and directories in your *system/* directory. + +.. note:: If you have any custom developed files in these directories, + please make copies of them first. + +Step 2: Replace config/user_agents.php +================================ + +This config file has received some updates. Please copy it to +*application/config/user_agents.php*. + +Step 3: Replace config/mimes.php +================================ + +This config file has received some updates. Please copy it to +*application/config/mimes.php*. diff --git a/user_guide_src/source/installation/upgrade_320.rst b/user_guide_src/source/installation/upgrade_320.rst index 3eadd8caf..2616a2a47 100644 --- a/user_guide_src/source/installation/upgrade_320.rst +++ b/user_guide_src/source/installation/upgrade_320.rst @@ -257,3 +257,13 @@ so that if you're using the :doc:`Web Page Caching <../general/caching>` feature, you'll be left with some old, garbage cache files. That shouldn't be a problem, but you may want to clear them. + +Step 13: Remove usage of OCI8 get_cursor() and stored_procedure() methods +========================================================================= + +The OCI8 :doc:`Database <database/index>` driver no longer has these two +methods that were specific to it and not present in other database drivers. +The ``$curs_id`` property is also removed. + +If you were using those, you can create your own cursors via ``oci_new_cursor()`` +and the publicly accessible ``$conn_id()``. diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst index 98f49ecac..789c9b32e 100644 --- a/user_guide_src/source/installation/upgrading.rst +++ b/user_guide_src/source/installation/upgrading.rst @@ -9,6 +9,7 @@ upgrading from. :titlesonly: Upgrading from 3.1.10+ to 3.2.x <upgrade_320> + Upgrading from 3.1.11 to 3.1.12 <upgrade_3112> Upgrading from 3.1.10 to 3.1.11 <upgrade_3111> Upgrading from 3.1.9 to 3.1.10 <upgrade_3110> Upgrading from 3.1.8 to 3.1.9 <upgrade_319> diff --git a/user_guide_src/source/libraries/file_uploading.rst b/user_guide_src/source/libraries/file_uploading.rst index 1b7581670..ce3de5a8a 100644 --- a/user_guide_src/source/libraries/file_uploading.rst +++ b/user_guide_src/source/libraries/file_uploading.rst @@ -35,7 +35,7 @@ Creating the Upload Form Using a text editor, create a form called upload_form.php. In it, place this code and save it to your **application/views/** directory:: - <html> + <html lang="en"> <head> <title>Upload Form</title> </head> @@ -68,7 +68,7 @@ The Success Page Using a text editor, create a form called upload_success.php. In it, place this code and save it to your **application/views/** directory:: - <html> + <html lang="en"> <head> <title>Upload Form</title> </head> diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst index fd2f3af94..5f30817eb 100644 --- a/user_guide_src/source/libraries/form_validation.rst +++ b/user_guide_src/source/libraries/form_validation.rst @@ -45,7 +45,7 @@ and tedious to implement. Form Validation Tutorial ************************ -What follows is a "hands on" tutorial for implementing CodeIgniters Form +What follows is a "hands on" tutorial for implementing CodeIgniter's Form Validation. In order to implement form validation you'll need three things: @@ -65,7 +65,7 @@ The Form Using a text editor, create a form called myform.php. In it, place this code and save it to your application/views/ folder:: - <html> + <html lang="en"> <head> <title>My Form</title> </head> @@ -100,7 +100,7 @@ The Success Page Using a text editor, create a form called formsuccess.php. In it, place this code and save it to your application/views/ folder:: - <html> + <html lang="en"> <head> <title>My Form</title> </head> @@ -359,7 +359,7 @@ function calls!** :: - <html> + <html lang="en"> <head> <title>My Form</title> </head> diff --git a/user_guide_src/source/libraries/input.rst b/user_guide_src/source/libraries/input.rst index 730b3a9b0..e0f3d8417 100644 --- a/user_guide_src/source/libraries/input.rst +++ b/user_guide_src/source/libraries/input.rst @@ -242,7 +242,7 @@ Class Reference This method is identical to ``get()``, ``post()`` and ``cookie()``, only it fetches the *php://input* stream data. - .. php:method:: set_cookie($name = ''[, $value = ''[, $expire = 0[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = NULL[, $httponly = NULL]]]]]]]) + .. php:method:: set_cookie($name = ''[, $value = ''[, $expire = 0[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = NULL[, $httponly = NULL[, $samesite = NULL]]]]]]]]) :param mixed $name: Cookie name or an array of parameters :param string $value: Cookie value @@ -252,6 +252,7 @@ Class Reference :param string $prefix: Cookie name prefix :param bool $secure: Whether to only transfer the cookie through HTTPS :param bool $httponly: Whether to only make the cookie accessible for HTTP requests (no JavaScript) + :param string $samesite: SameSite attribute ('Lax', 'Strict', 'None') :rtype: void @@ -265,13 +266,14 @@ Class Reference parameter:: $cookie = array( - 'name' => 'The Cookie Name', - 'value' => 'The Value', - 'expire' => 86500, - 'domain' => '.some-domain.com', - 'path' => '/', - 'prefix' => 'myprefix_', - 'secure' => TRUE + 'name' => 'The Cookie Name', + 'value' => 'The Value', + 'expire' => 86500, + 'domain' => '.some-domain.com', + 'path' => '/', + 'prefix' => 'myprefix_', + 'secure' => TRUE, + 'samesite' => 'Strict' ); $this->input->set_cookie($cookie); @@ -297,13 +299,14 @@ Class Reference The *httponly* and *secure* flags, when omitted, will default to your ``$config['cookie_httponly']`` and ``$config['cookie_secure']`` settings. + The *samesite* parameter can be ``'Lax'``, ``'Strict'`` or ``'None'``. If not set, the same-site cookie attribute will default to ``'Lax'``. **Discrete Parameters** If you prefer, you can set the cookie by passing data using individual parameters:: - $this->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure); + $this->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $samesite); .. php:method:: ip_address() diff --git a/user_guide_src/source/libraries/parser.rst b/user_guide_src/source/libraries/parser.rst index 6c9d28959..43ef5ee56 100644 --- a/user_guide_src/source/libraries/parser.rst +++ b/user_guide_src/source/libraries/parser.rst @@ -9,7 +9,7 @@ It can parse simple variables or variable tag pairs. If you've never used a template engine, pseudo-variable names are enclosed in braces, like this:: - <html> + <html lang="en"> <head> <title>{blog_title}</title> </head> @@ -95,7 +95,7 @@ you would like an entire block of variables to be repeated, with each iteration containing new values? Consider the template example we showed at the top of the page:: - <html> + <html lang="en"> <head> <title>{blog_title}</title> </head> @@ -290,7 +290,7 @@ Class Reference .. php:method:: parse_string($template, $data[, $return = FALSE]) - :param string $template: Path to view file + :param string $template: Content to parse :param array $data: Variable data :param bool $return: Whether to only return the parsed template :returns: Parsed template string @@ -306,4 +306,4 @@ Class Reference :rtype: void Sets the delimiters (opening and closing) for a - pseudo-variable "tag" in a template.
\ No newline at end of file + pseudo-variable "tag" in a template. diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index f2236c633..b87508aba 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -438,6 +438,8 @@ Preference Default Options ============================ =============== ======================================== ============================================================================================ **sess_driver** files files/database/redis/memcached/*custom* The session storage driver to use. **sess_cookie_name** ci_session [A-Za-z\_-] characters only The name used for the session cookie. +**sess_samesite** ci_session 'Lax', 'Strict' or 'None' SameSite attribute value for session cookies. + Defaults to ``session.cookie_samesite`` on PHP 7.3+ or 'Lax' if not present at all. **sess_expiration** 7200 (2 hours) Time in seconds (integer) The number of seconds you would like the session to last. If you would like a non-expiring session (until browser is closed) set the value to zero: 0 **sess_save_path** NULL None Specifies the storage location, depends on the driver being used. diff --git a/user_guide_src/source/libraries/typography.rst b/user_guide_src/source/libraries/typography.rst index 9e1386835..321b064ba 100644 --- a/user_guide_src/source/libraries/typography.rst +++ b/user_guide_src/source/libraries/typography.rst @@ -47,7 +47,7 @@ Class Reference .. php:method:: auto_typography($str[, $reduce_linebreaks = FALSE]) :param string $str: Input string - :param bool $reduce_linebreaks: Whether to reduce consequitive linebreaks + :param bool $reduce_linebreaks: Whether to reduce consecutive linebreaks :returns: HTML typography-safe string :rtype: string diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index cde52fde8..b53ef2d68 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -25,7 +25,7 @@ the slug from our title in the model. Create the new view at <?php echo form_open('news/create'); ?> <label for="title">Title</label> - <input type="input" name="title" /><br /> + <input type="text" name="title" /><br /> <label for="text">Text</label> <textarea name="text"></textarea><br /> diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index 5daaa958f..8db105555 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -58,7 +58,7 @@ the following code: :: - <html> + <html lang="en"> <head> <title>CodeIgniter Tutorial</title> </head> @@ -162,7 +162,7 @@ arguments. More information about routing can be found in the URI Routing :doc:`documentation <../general/routing>`. -Here, the second rule in the ``$routes`` array matches **any** request +Here, the second rule in the ``$route`` array matches **any** request using the wildcard string ``(:any)``. and passes the parameter to the ``view()`` method of the ``Pages`` class. |