diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..257221d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,14 @@
+# editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..d3353e5
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,37 @@
+# Autodetect text files
+* text=auto
+
+# ...Unless the name matches the following overriding patterns
+
+# Definitively text files
+*.php text
+*.css text
+*.js text
+*.txt text
+*.md text
+*.xml text
+*.json text
+*.bat text
+*.sql text
+*.yml text
+
+# Ensure those won't be messed up with
+*.png binary
+*.jpg binary
+*.gif binary
+*.ttf binary
+
+# Ignore some meta files when creating an archive of this repository
+/.github export-ignore
+/.editorconfig export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+/.scrutinizer.yml export-ignore
+/phpunit.xml.dist export-ignore
+/tests export-ignore
+/docs export-ignore
+
+# Avoid merge conflicts in CHANGELOG
+# https://about.gitlab.com/2015/02/10/gitlab-reduced-merge-conflicts-by-90-percent-with-changelog-placeholders/
+/CHANGELOG.md merge=union
+
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..803e000
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,67 @@
+# Yii Contributor Code of Conduct
+
+## Our Pledge
+
+As contributors and maintainers of this project, and in order to keep Yii community open and welcoming, we ask to respect all community members.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Personal attacks
+* Trolling or insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing other's private information, such as physical or electronic
+ addresses, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in
+ a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in response
+to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments,
+commits, code, wiki edits, issues, and other contributions that are not aligned to this
+Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
+that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when
+an individual is representing the project or its community. Examples of representing
+a project or community include posting via an official social media account,
+within project GitHub, official forum or acting as an appointed representative at
+an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported
+by contacting core team members. All complaints will be reviewed and investigated
+and will result in a response that is deemed necessary and appropriate to the circumstances.
+The project team is obligated to maintain confidentiality with regard to the reporter of
+an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith
+may face temporary or permanent repercussions as determined by other members of
+the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 1.4.0, available at
+[http://contributor-covenant.org/version/1/4/][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..28737bd
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,23 @@
+# Prerequisites
+
+- [Yii goal and values](https://github.com/yiisoft/docs/blob/master/001-yii-values.md)
+- [Namespaces](https://github.com/yiisoft/docs/blob/master/004-namespaces.md)
+- [Git commit messages](https://github.com/yiisoft/docs/blob/master/006-git-commit-messages.md)
+- [Exceptions](https://github.com/yiisoft/docs/blob/master/007-exceptions.md)
+- [Interfaces](https://github.com/yiisoft/docs/blob/master/008-interfaces.md)
+
+# Getting started
+
+Since Yii 3 consists of many packages, we have a [special development tool](https://github.com/yiisoft/docs/blob/master/005-development-tool.md).
+
+1. [Clone the repository](https://github.com/yiisoft/yii-dev-tool).
+
+2. [Set up your own fork](https://github.com/yiisoft/yii-dev-tool#using-your-own-fork).
+
+3. Now you are ready. Fork any package listed in `packages.php` and do `./yii-dev install username/package`.
+
+If you don't have any particular package in mind to start with:
+
+- [Check roadmap](https://github.com/yiisoft/docs/blob/master/003-roadmap.md).
+- Check package issues at github. Usually there are some.
+- Ask @samdark.
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..f0dc531
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+open_collective: yiisoft
+github: [yiisoft]
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..b748c2d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,16 @@
+
+
+### What steps will reproduce the problem?
+
+### What is the expected result?
+
+### What do you get instead?
+
+
+### Additional info
+
+| Q | A
+| ---------------- | ---
+| Version | 1.0.?
+| PHP version |
+| Operating system |
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..4a3e8ac
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,6 @@
+| Q | A
+| ------------- | ---
+| Is bugfix? | ✔️/❌
+| New feature? | ✔️/❌
+| Breaks BC? | ✔️/❌
+| Fixed issues | comma-separated list of tickets # fixed by the PR, if any
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
new file mode 100644
index 0000000..ba09318
--- /dev/null
+++ b/.github/SECURITY.md
@@ -0,0 +1,6 @@
+# Security Policy
+
+Please use the [security issue form](https://www.yiiframework.com/security) to report to us any security issue you
+find in Yii. DO NOT use the issue tracker or discuss it in the public forum as it will cause more damage than help.
+
+Please note that as a non-commercial OpenSource project we are not able to pay bounties at the moment.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..8fc3ed2
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,94 @@
+on:
+ - pull_request
+ - push
+
+name: build
+
+jobs:
+ tests:
+ name: PHP ${{ matrix.php-version }}-${{ matrix.os }}
+ env:
+ extensions: curl, mbstring, dom, intl, json, libxml, xml, xmlwriter
+ key: cache-v1
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os:
+ - ubuntu-latest
+ - windows-latest
+
+ php-version:
+ - "7.4"
+ - "8.0"
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Setup cache environment
+ id: cache-env
+ uses: shivammathur/cache-extensions@v1
+ with:
+ php-version: ${{ matrix.php-version }}
+ extensions: ${{ env.extensions }}
+ key: ${{ env.key }}
+
+ - name: Cache extensions
+ uses: actions/cache@v1
+ with:
+ path: ${{ steps.cache-env.outputs.dir }}
+ key: ${{ steps.cache-env.outputs.key }}
+ restore-keys: ${{ steps.cache-env.outputs.key }}
+
+ - name: Install PHP with extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+ extensions: ${{ env.extensions }}
+ ini-values: date.timezone='UTC'
+ coverage: pcov
+ tools: composer:v2
+
+ - name: Determine composer cache directory on Linux
+ if: matrix.os == 'ubuntu-latest'
+ run: echo "::set-env name=COMPOSER_CACHE_DIR::$(composer config cache-dir)"
+
+ - name: Determine composer cache directory on Windows
+ if: matrix.os == 'windows-latest'
+ run: ECHO "::set-env name=COMPOSER_CACHE_DIR::~\AppData\Local\Composer"
+
+ - name: Cache dependencies installed with composer
+ uses: actions/cache@v2
+ with:
+ path: ${{ env.COMPOSER_CACHE_DIR }}
+ key: php${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }}
+ restore-keys: |
+ php${{ matrix.php-version }}-composer-
+
+ - name: Install dependencies with composer php 7.4
+ if: matrix.php-version == '7.4'
+ run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader
+
+ - name: Install dependencies with composer php 8.0
+ if: matrix.php-version == '8.0'
+ run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader
+
+ - name: Run tests with phpunit and coverage on Linux php 7.4
+ if: matrix.os == 'ubuntu-latest' && matrix.php-version == '7.4'
+ run: vendor/bin/phpunit --coverage-clover=coverage.clover
+
+ - name: Run tests with phpunit without coverage on Linux php 8.0
+ if: matrix.os == 'ubuntu-latest' && matrix.php-version == '8.0'
+ run: vendor/bin/phpunit
+
+ - name: Run tests with phpunit without coverage on Windows
+ if: matrix.os == 'windows-latest'
+ run: vendor/bin/phpunit
+
+ - name: Upload code coverage scrutinizer on Linux php 7.4
+ if: matrix.os == 'ubuntu-latest' && matrix.php-version == '7.4'
+ run: |
+ wget https://scrutinizer-ci.com/ocular.phar
+ php ocular.phar code-coverage:upload --format=php-clover coverage.clover
diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml
new file mode 100644
index 0000000..a78dea1
--- /dev/null
+++ b/.github/workflows/mutation.yml
@@ -0,0 +1,55 @@
+on:
+ pull_request:
+ push:
+ branches:
+ - "master"
+
+name: mutation test
+
+jobs:
+ mutation:
+ name: PHP ${{ matrix.php-version }}-${{ matrix.os }}
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os:
+ - ubuntu-latest
+
+ php-version:
+ - "7.4"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v2"
+
+ - name: "Install PHP"
+ uses: "shivammathur/setup-php@v2"
+ with:
+ php-version: "${{ matrix.php-version }}"
+ ini-values: memory_limit=-1
+ coverage: "pcov"
+ tools: composer:v2
+
+ - name: Determine composer cache directory
+ run: echo "::set-env name=COMPOSER_CACHE_DIR::$(composer config cache-dir)"
+
+ - name: Cache dependencies installed with composer
+ uses: actions/cache@v2
+ with:
+ path: ${{ env.COMPOSER_CACHE_DIR }}
+ key: php${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }}
+ restore-keys: |
+ php${{ matrix.php-version }}-composer-
+
+ - name: Install dependencies with composer
+ run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader
+
+ - name: Run test mutation infection with coverage
+ run: |
+ mkdir -p build/logs
+ vendor/bin/phpunit --coverage-xml=build/logs/coverage-xml --log-junit=build/logs/junit.xml
+ vendor/bin/infection --threads=2 --coverage=build/logs --show-mutations --no-progress --min-msi=10 --min-covered-msi=10
+ env:
+ STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
new file mode 100644
index 0000000..eaf11b9
--- /dev/null
+++ b/.github/workflows/static.yml
@@ -0,0 +1,50 @@
+on:
+ - pull_request
+ - push
+
+name: static analysis
+
+jobs:
+ mutation:
+ name: PHP ${{ matrix.php-version }}-${{ matrix.os }}
+ env:
+ extensions: ast
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os:
+ - ubuntu-latest
+
+ php-version:
+ - "7.4"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v2"
+
+ - name: "Install PHP"
+ uses: "shivammathur/setup-php@v2"
+ with:
+ php-version: "${{ matrix.php-version }}"
+ extensions: ${{ env.extensions }}
+ tools: composer:v2, cs2pr
+ coverage: none
+
+ - name: Determine composer cache directory
+ run: echo "::set-env name=COMPOSER_CACHE_DIR::$(composer config cache-dir)"
+
+ - name: Cache dependencies installed with composer
+ uses: actions/cache@v2
+ with:
+ path: ${{ env.COMPOSER_CACHE_DIR }}
+ key: php${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }}
+ restore-keys: |
+ php${{ matrix.php-version }}-composer-
+
+ - name: Install dependencies with composer
+ run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader
+
+ - name: Static analysis with phan
+ run: vendor/bin/phan --no-progress-bar --output-mode checkstyle | cs2pr --graceful-warnings --colorize
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..18a33d4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,35 @@
+# phpstorm project files
+.idea
+
+# netbeans project files
+nbproject
+
+# zend studio for eclipse project files
+.buildpath
+.project
+.settings
+
+# windows thumbnail cache
+Thumbs.db
+
+# composer vendor dir
+/vendor
+
+/composer.lock
+
+# composer itself is not needed
+composer.phar
+
+# Mac DS_Store Files
+.DS_Store
+
+# phpunit itself is not needed
+phpunit.phar
+# local phpunit config
+/phpunit.xml
+# phpunit cache
+.phpunit.result.cache
+
+# Phan
+analysis.txt
+
diff --git a/.phan/config.php b/.phan/config.php
new file mode 100644
index 0000000..4433509
--- /dev/null
+++ b/.phan/config.php
@@ -0,0 +1,374 @@
+=7.1.0"
+ 'target_php_version' => '7.4',
+
+ // If enabled, missing properties will be created when
+ // they are first seen. If false, we'll report an
+ // error message if there is an attempt to write
+ // to a class property that wasn't explicitly
+ // defined.
+ 'allow_missing_properties' => false,
+
+ // If enabled, null can be cast to any type and any
+ // type can be cast to null. Setting this to true
+ // will cut down on false positives.
+ 'null_casts_as_any_type' => false,
+
+ // If enabled, allow null to be cast as any array-like type.
+ //
+ // This is an incremental step in migrating away from `null_casts_as_any_type`.
+ // If `null_casts_as_any_type` is true, this has no effect.
+ 'null_casts_as_array' => false,
+
+ // If enabled, allow any array-like type to be cast to null.
+ // This is an incremental step in migrating away from `null_casts_as_any_type`.
+ // If `null_casts_as_any_type` is true, this has no effect.
+ 'array_casts_as_null' => false,
+
+ // If enabled, scalars (int, float, bool, string, null)
+ // are treated as if they can cast to each other.
+ // This does not affect checks of array keys. See `scalar_array_key_cast`.
+ 'scalar_implicit_cast' => false,
+
+ // If enabled, any scalar array keys (int, string)
+ // are treated as if they can cast to each other.
+ // E.g. `array` can cast to `array` and vice versa.
+ // Normally, a scalar type such as int could only cast to/from int and mixed.
+ 'scalar_array_key_cast' => false,
+
+ // If this has entries, scalars (int, float, bool, string, null)
+ // are allowed to perform the casts listed.
+ //
+ // E.g. `['int' => ['float', 'string'], 'float' => ['int'], 'string' => ['int'], 'null' => ['string']]`
+ // allows casting null to a string, but not vice versa.
+ // (subset of `scalar_implicit_cast`)
+ 'scalar_implicit_partial' => [],
+
+ // If enabled, Phan will warn if **any** type in a method invocation's object
+ // is definitely not an object,
+ // or if **any** type in an invoked expression is not a callable.
+ // Setting this to true will introduce numerous false positives
+ // (and reveal some bugs).
+ 'strict_method_checking' => true,
+
+ // If enabled, Phan will warn if **any** type of the object expression for a property access
+ // does not contain that property.
+ 'strict_object_checking' => true,
+
+ // If enabled, Phan will warn if **any** type in the argument's union type
+ // cannot be cast to a type in the parameter's expected union type.
+ // Setting this to true will introduce numerous false positives
+ // (and reveal some bugs).
+ 'strict_param_checking' => true,
+
+ // If enabled, Phan will warn if **any** type in a property assignment's union type
+ // cannot be cast to a type in the property's declared union type.
+ // Setting this to true will introduce numerous false positives
+ // (and reveal some bugs).
+ 'strict_property_checking' => true,
+
+ // If enabled, Phan will warn if **any** type in a returned value's union type
+ // cannot be cast to the declared return type.
+ // Setting this to true will introduce numerous false positives
+ // (and reveal some bugs).
+ 'strict_return_checking' => true,
+
+ // If true, seemingly undeclared variables in the global
+ // scope will be ignored.
+ //
+ // This is useful for projects with complicated cross-file
+ // globals that you have no hope of fixing.
+ 'ignore_undeclared_variables_in_global_scope' => false,
+
+ // Set this to false to emit `PhanUndeclaredFunction` issues for internal functions that Phan has signatures for,
+ // but aren't available in the codebase, or the internal functions used to run Phan
+ // (may lead to false positives if an extension isn't loaded)
+ //
+ // If this is true(default), then Phan will not warn.
+ 'ignore_undeclared_functions_with_known_signatures' => false,
+
+ // Backwards Compatibility Checking. This is slow
+ // and expensive, but you should consider running
+ // it before upgrading your version of PHP to a
+ // new version that has backward compatibility
+ // breaks.
+ //
+ // If you are migrating from PHP 5 to PHP 7,
+ // you should also look into using
+ // [php7cc (no longer maintained)](https://github.com/sstalle/php7cc)
+ // and [php7mar](https://github.com/Alexia/php7mar),
+ // which have different backwards compatibility checks.
+ 'backward_compatibility_checks' => false,
+
+ // If true, check to make sure the return type declared
+ // in the doc-block (if any) matches the return type
+ // declared in the method signature.
+ 'check_docblock_signature_return_type_match' => true,
+
+ // If true, make narrowed types from phpdoc params override
+ // the real types from the signature, when real types exist.
+ // (E.g. allows specifying desired lists of subclasses,
+ // or to indicate a preference for non-nullable types over nullable types)
+ //
+ // Affects analysis of the body of the method and the param types passed in by callers.
+ //
+ // (*Requires `check_docblock_signature_param_type_match` to be true*)
+ 'prefer_narrowed_phpdoc_param_type' => true,
+
+ // (*Requires `check_docblock_signature_return_type_match` to be true*)
+ //
+ // If true, make narrowed types from phpdoc returns override
+ // the real types from the signature, when real types exist.
+ //
+ // (E.g. allows specifying desired lists of subclasses,
+ // or to indicate a preference for non-nullable types over nullable types)
+ //
+ // This setting affects the analysis of return statements in the body of the method and the return types passed in by callers.
+ 'prefer_narrowed_phpdoc_return_type' => true,
+
+ // If enabled, check all methods that override a
+ // parent method to make sure its signature is
+ // compatible with the parent's.
+ //
+ // This check can add quite a bit of time to the analysis.
+ //
+ // This will also check if final methods are overridden, etc.
+ 'analyze_signature_compatibility' => true,
+
+ // This setting maps case-insensitive strings to union types.
+ //
+ // This is useful if a project uses phpdoc that differs from the phpdoc2 standard.
+ //
+ // If the corresponding value is the empty string,
+ // then Phan will ignore that union type (E.g. can ignore 'the' in `@return the value`)
+ //
+ // If the corresponding value is not empty,
+ // then Phan will act as though it saw the corresponding UnionTypes(s)
+ // when the keys show up in a UnionType of `@param`, `@return`, `@var`, `@property`, etc.
+ //
+ // This matches the **entire string**, not parts of the string.
+ // (E.g. `@return the|null` will still look for a class with the name `the`, but `@return the` will be ignored with the below setting)
+ //
+ // (These are not aliases, this setting is ignored outside of doc comments).
+ // (Phan does not check if classes with these names exist)
+ //
+ // Example setting: `['unknown' => '', 'number' => 'int|float', 'char' => 'string', 'long' => 'int', 'the' => '']`
+ 'phpdoc_type_mapping' => [],
+
+ // Set to true in order to attempt to detect dead
+ // (unreferenced) code. Keep in mind that the
+ // results will only be a guess given that classes,
+ // properties, constants and methods can be referenced
+ // as variables (like `$class->$property` or
+ // `$class->$method()`) in ways that we're unable
+ // to make sense of.
+ 'dead_code_detection' => false,
+
+ // Set to true in order to attempt to detect unused variables.
+ // `dead_code_detection` will also enable unused variable detection.
+ //
+ // This has a few known false positives, e.g. for loops or branches.
+ 'unused_variable_detection' => true,
+
+ // Set to true in order to attempt to detect redundant and impossible conditions.
+ //
+ // This has some false positives involving loops,
+ // variables set in branches of loops, and global variables.
+ 'redundant_condition_detection' => true,
+
+ // If enabled, Phan will act as though it's certain of real return types of a subset of internal functions,
+ // even if those return types aren't available in reflection (real types were taken from php 7.3 or 8.0-dev, depending on target_php_version).
+ //
+ // Note that with php 7 and earlier, php would return null or false for many internal functions if the argument types or counts were incorrect.
+ // As a result, enabling this setting with target_php_version 8.0 may result in false positives for `--redundant-condition-detection` when codebases also support php 7.x.
+ 'assume_real_types_for_internal_functions' => true,
+
+ // If true, this runs a quick version of checks that takes less
+ // time at the cost of not running as thorough
+ // of an analysis. You should consider setting this
+ // to true only when you wish you had more **undiagnosed** issues
+ // to fix in your code base.
+ //
+ // In quick-mode the scanner doesn't rescan a function
+ // or a method's code block every time a call is seen.
+ // This means that the problem here won't be detected:
+ //
+ // ```php
+ // false,
+
+ // Enable or disable support for generic templated
+ // class types.
+ 'generic_types_enabled' => true,
+
+ // Override to hardcode existence and types of (non-builtin) globals in the global scope.
+ // Class names should be prefixed with `\`.
+ //
+ // (E.g. `['_FOO' => '\FooClass', 'page' => '\PageClass', 'userId' => 'int']`)
+ 'globals_type_map' => [],
+
+ // The minimum severity level to report on. This can be
+ // set to `Issue::SEVERITY_LOW`, `Issue::SEVERITY_NORMAL` or
+ // `Issue::SEVERITY_CRITICAL`. Setting it to only
+ // critical issues is a good place to start on a big
+ // sloppy mature code base.
+ 'minimum_severity' => Issue::SEVERITY_LOW,
+
+ // Add any issue types (such as `'PhanUndeclaredMethod'`)
+ // to this black-list to inhibit them from being reported.
+ 'suppress_issue_types' => [],
+
+ // A regular expression to match files to be excluded
+ // from parsing and analysis and will not be read at all.
+ //
+ // This is useful for excluding groups of test or example
+ // directories/files, unanalyzable files, or files that
+ // can't be removed for whatever reason.
+ // (e.g. `'@Test\.php$@'`, or `'@vendor/.*/(tests|Tests)/@'`)
+ 'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?|vendor)/@',
+
+ // A file list that defines files that will be excluded
+ // from parsing and analysis and will not be read at all.
+ //
+ // This is useful for excluding hopelessly unanalyzable
+ // files that can't be removed for whatever reason.
+ 'exclude_file_list' => [],
+
+ // A directory list that defines files that will be excluded
+ // from static analysis, but whose class and method
+ // information should be included.
+ //
+ // Generally, you'll want to include the directories for
+ // third-party code (such as "vendor/") in this list.
+ //
+ // n.b.: If you'd like to parse but not analyze 3rd
+ // party code, directories containing that code
+ // should be added to the `directory_list` as well as
+ // to `exclude_analysis_directory_list`.
+ 'exclude_analysis_directory_list' => [
+ 'vendor/',
+ ],
+
+ // Enable this to enable checks of require/include statements referring to valid paths.
+ 'enable_include_path_checks' => true,
+
+ // The number of processes to fork off during the analysis
+ // phase.
+ 'processes' => 1,
+
+ // List of case-insensitive file extensions supported by Phan.
+ // (e.g. `['php', 'html', 'htm']`)
+ 'analyzed_file_extensions' => [
+ 'php',
+ ],
+
+ // You can put paths to stubs of internal extensions in this config option.
+ // If the corresponding extension is **not** loaded, then Phan will use the stubs instead.
+ // Phan will continue using its detailed type annotations,
+ // but load the constants, classes, functions, and classes (and their Reflection types)
+ // from these stub files (doubling as valid php files).
+ // Use a different extension from php to avoid accidentally loading these.
+ // The `tools/make_stubs` script can be used to generate your own stubs (compatible with php 7.0+ right now)
+ //
+ // (e.g. `['xdebug' => '.phan/internal_stubs/xdebug.phan_php']`)
+ 'autoload_internal_extension_signatures' => [],
+
+ // A list of plugin files to execute.
+ //
+ // Plugins which are bundled with Phan can be added here by providing their name (e.g. `'AlwaysReturnPlugin'`)
+ //
+ // Documentation about available bundled plugins can be found [here](https://github.com/phan/phan/tree/master/.phan/plugins).
+ //
+ // Alternately, you can pass in the full path to a PHP file with the plugin's implementation (e.g. `'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php'`)
+ 'plugins' => [
+ 'AlwaysReturnPlugin',
+ 'DollarDollarPlugin',
+ 'DuplicateArrayKeyPlugin',
+ 'DuplicateExpressionPlugin',
+ 'PregRegexCheckerPlugin',
+ 'PrintfCheckerPlugin',
+ 'SleepCheckerPlugin',
+ 'UnreachableCodePlugin',
+ 'UseReturnValuePlugin',
+ 'EmptyStatementListPlugin',
+ 'StrictComparisonPlugin',
+ 'LoopVariableReusePlugin',
+ ],
+
+ // A list of directories that should be parsed for class and
+ // method information. After excluding the directories
+ // defined in `exclude_analysis_directory_list`, the remaining
+ // files will be statically analyzed for errors.
+ //
+ // Thus, both first-party and third-party code being used by
+ // your application should be included in this list.
+ 'directory_list' => [
+ 'src',
+ 'vendor'
+ ],
+
+ // A list of individual files to include in analysis
+ // with a path relative to the root directory of the
+ // project.
+ 'file_list' => [],
+];
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
new file mode 100644
index 0000000..c7b177a
--- /dev/null
+++ b/.scrutinizer.yml
@@ -0,0 +1,18 @@
+build:
+ environment:
+ php: "7.4"
+ nodes:
+ analysis:
+ tests:
+ override:
+ - php-scrutinizer-run
+filter:
+ paths:
+ - "src/*"
+checks:
+ php: true
+tools:
+ php_code_coverage:
+ enabled: true
+ external_code_coverage:
+ timeout: 600
diff --git a/.styleci.yml b/.styleci.yml
new file mode 100644
index 0000000..207ce0e
--- /dev/null
+++ b/.styleci.yml
@@ -0,0 +1,6 @@
+preset: psr12
+
+finder:
+ exclude:
+ - docs
+ - vendor
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..6a8fbfe
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# _____ Change Log
+
+## 1.0.0 under development
+
+- Initial release.
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..ee872b9
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,29 @@
+Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Yii Software LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b13cefb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,51 @@
+
+
+
+
+
Yii _____
+
+
+
+The package ...
+
+[![Latest Stable Version](https://poser.pugx.org/yiisoft/_____/v/stable.png)](https://packagist.org/packages/yiisoft/_____)
+[![Total Downloads](https://poser.pugx.org/yiisoft/_____/downloads.png)](https://packagist.org/packages/yiisoft/_____)
+[![Build status](https://github.com/yiisoft/_____/workflows/build/badge.svg)](https://github.com/yiisoft/_____/actions?query=workflow%3Abuild)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yiisoft/_____/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yiisoft/_____/?branch=master)
+[![Code Coverage](https://scrutinizer-ci.com/g/yiisoft/_____/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/yiisoft/_____/?branch=master)
+[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fyiisoft%2F_____%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/_____/master)
+[![static analysis](https://github.com/yiisoft/_____/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/_____/actions?query=workflow%3A%22static+analysis%22)
+
+## Installation
+
+The package could be installed with composer:
+
+```
+composer install yiisoft/_____
+```
+
+## General usage
+
+## Unit testing
+
+The package is tested with [PHPUnit](https://phpunit.de/). To run tests:
+
+```php
+./vendor/bin/phpunit
+```
+
+## Mutation testing
+
+The package tests are checked with [Infection](https://infection.github.io/) mutation framework. To run it:
+
+```php
+./vendor/bin/infection
+```
+
+## Static analysis
+
+The code is statically analyzed with [Phan](https://github.com/phan/phan/wiki). To run static analysis:
+
+```php
+./vendor/bin/phan
+```
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..f85fd1f
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,45 @@
+{
+ "name": "yiisoft/_____",
+ "type": "library",
+ "description": "_____",
+ "keywords": [
+ "_____"
+ ],
+ "homepage": "https://www.yiiframework.com/",
+ "license": "BSD-3-Clause",
+ "support": {
+ "issues": "https://github.com/yiisoft/_____/issues?state=open",
+ "forum": "https://www.yiiframework.com/forum/",
+ "wiki": "https://www.yiiframework.com/wiki/",
+ "irc": "irc://irc.freenode.net/yii",
+ "source": "https://github.com/yiisoft/_____"
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "require": {
+ "php": "^7.4|^8.0"
+ },
+ "require-dev": {
+ "infection/infection": "^0.16.3",
+ "phan/phan": "^3.0",
+ "phpunit/phpunit": "^9.3"
+ },
+ "autoload": {
+ "psr-4": {
+ "Yiisoft\\_____\\": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Yiisoft\\_____\\Tests\\": "tests"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ }
+}
diff --git a/infection.json.dist b/infection.json.dist
new file mode 100644
index 0000000..d319ab1
--- /dev/null
+++ b/infection.json.dist
@@ -0,0 +1,16 @@
+{
+ "source": {
+ "directories": [
+ "src"
+ ]
+ },
+ "logs": {
+ "text": "php:\/\/stderr",
+ "badge": {
+ "branch": "master"
+ }
+ },
+ "mutators": {
+ "@default": true
+ }
+}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..b1d7346
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+ ./tests
+
+
+
+
+
+ ./src
+
+
+
diff --git a/src/.gitkeep b/src/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/.gitkeep b/tests/.gitkeep
new file mode 100644
index 0000000..e69de29