From 3df03b117fb1d31117fd808cc1fe96f26f30e301 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 18 Apr 2022 22:39:00 +0200 Subject: [PATCH 01/89] ical update --- ICAL.txt | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 ICAL.txt diff --git a/ICAL.txt b/ICAL.txt new file mode 100644 index 0000000..019045f --- /dev/null +++ b/ICAL.txt @@ -0,0 +1,49 @@ +# Individual Contributor License Agreement ("CLA") 1.0 + +Thank you for your interest in Karaka-Management (the "Company"). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Company must provide a Contributor License Agreement ("CLA") on file that has been made available to each Contributor. This license is for your protection as a Contributor as well as the protection of the Company and its users; it does not change your rights to use your own Contributions for any other purpose. + +By contributing to the Company You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Company. In return, the Company shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its bylaws in effect at the time of the Contribution. Except for the license granted herein to the Company and recipients of software distributed by the Company, You reserve all right, title, and interest in and to Your Contributions. + +## Definitions + +**"You" (or "Your")** + +"You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with the Company. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +**"Contribution"** + +"Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to the Company for inclusion in, or documentation of, any of the products owned or managed by the Company (the "Work"). This includes but is not limited to technical material, techniques, articles, sketches, drawings, images, models, inventions, know-how, processes, apparatus, equipment, algorithms, software programs, software source documents, and formula related to the current, future and proposed products and services regarding the Company". For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Company or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Company for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." + +## Grant of Copyright License + +Subject to the terms and conditions of this Agreement, You hereby grant to the Company and to recipients of software distributed by the Company a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sub license, and distribute Your Contributions and such derivative works. + +## Grant of Patent License + +Subject to the terms and conditions of this Agreement, You hereby grant to the Company and to recipients of software distributed by the Company a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. + +## Authorization + +You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to the Company, or that your employer has executed a separate Corporate CLA with the Company. + +You represent that each of Your Contributions is Your original creation (see "Third-party Contribution" for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions. + +## Support + +You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + +## Third-party Contribution + +Should You wish to submit work that is not Your original creation, You may submit it to the Company separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]". + +## Survival + +This Agreement shall govern all communications between the parties. You understand that this Agreement stays active even if the connection with You gets terminated unless the project the Company gets officially canceled by the project manager "Dennis Eichhorn". + +## Governing Law and Jurisdiction + +This Agreement shall be governed exclusively by German law. The courts of Hessen, Germany shall have exclusive jurisdiction. + +## Entire Agreement + +This agreement constitutes the entire agreement and supersedes all prior or contemporaneous oral or written agreements concerning such Contribution. This agreement may only be changed by mutual agreement of authorized representatives of the parties in writing. You agree to notify the Company of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect. \ No newline at end of file From b2f0df175a85f9582122503e63e2c7f236587964 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 9 Nov 2022 22:56:18 +0100 Subject: [PATCH 02/89] permission changes & minor bug fixes --- ICAL.txt | 0 README.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 ICAL.txt mode change 100644 => 100755 README.md diff --git a/ICAL.txt b/ICAL.txt old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 From 48394ac603732ef6edf60ea2603fbc0276e94dda Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Thu, 26 Jan 2023 21:54:13 +0100 Subject: [PATCH 03/89] org -> unit change, some new functionality --- .github/dev_bug_report.md | 35 + .github/dev_feature_request.md | 18 + .github/user_bug_report.md | 34 + .github/user_feature_request.md | 18 + .github/workflows/greetings.yml | 13 + .github/workflows/image.yml | 24 + .github/workflows/main.yml | 281 ++ .gitignore | 1 + Admin/Install/Media.install.json | 9 + Admin/Install/Media.php | 43 + Admin/Install/Navigation.install.json | 110 + Admin/Install/Navigation.php | 43 + Admin/Install/db.json | 405 ++ Admin/Installer.php | 50 + Admin/Routes/Web/Backend.php | 76 + Admin/Status.php | 36 + Admin/Uninstaller.php | 36 + Admin/Updater.php | 29 + Controller.js | 0 Controller/ApiController.php | 28 + Controller/BackendController.php | 29 + Controller/Controller.php | 76 + Docs/Dev/en/SUMMARY.md | 3 + Docs/Dev/en/structure.md | 5 + Docs/Dev/img/er.png | Bin 0 -> 312054 bytes Models/PermissionCategory.php | 30 + Theme/Backend/Lang/Navigation.ar.lang.php | 19 + Theme/Backend/Lang/Navigation.cs.lang.php | 19 + Theme/Backend/Lang/Navigation.da.lang.php | 19 + Theme/Backend/Lang/Navigation.de.lang.php | 19 + Theme/Backend/Lang/Navigation.el.lang.php | 19 + Theme/Backend/Lang/Navigation.en.lang.php | 19 + Theme/Backend/Lang/Navigation.es.lang.php | 19 + Theme/Backend/Lang/Navigation.fi.lang.php | 19 + Theme/Backend/Lang/Navigation.fr.lang.php | 19 + Theme/Backend/Lang/Navigation.hu.lang.php | 19 + Theme/Backend/Lang/Navigation.it.lang.php | 19 + Theme/Backend/Lang/Navigation.ja.lang.php | 19 + Theme/Backend/Lang/Navigation.ko.lang.php | 19 + Theme/Backend/Lang/Navigation.no.lang.php | 19 + Theme/Backend/Lang/Navigation.pl.lang.php | 19 + Theme/Backend/Lang/Navigation.pt.lang.php | 19 + Theme/Backend/Lang/Navigation.ru.lang.php | 19 + Theme/Backend/Lang/Navigation.sv.lang.php | 19 + Theme/Backend/Lang/Navigation.th.lang.php | 19 + Theme/Backend/Lang/Navigation.tr.lang.php | 19 + Theme/Backend/Lang/Navigation.uk.lang.php | 19 + Theme/Backend/Lang/Navigation.zh.lang.php | 19 + Theme/Backend/Lang/ar.lang.php | 126 + Theme/Backend/Lang/cs.lang.php | 126 + Theme/Backend/Lang/da.lang.php | 126 + Theme/Backend/Lang/de.lang.php | 126 + Theme/Backend/Lang/el.lang.php | 126 + Theme/Backend/Lang/en.lang.php | 127 + Theme/Backend/Lang/es.lang.php | 126 + Theme/Backend/Lang/fi.lang.php | 126 + Theme/Backend/Lang/fr.lang.php | 126 + Theme/Backend/Lang/hu.lang.php | 126 + Theme/Backend/Lang/it.lang.php | 126 + Theme/Backend/Lang/ja.lang.php | 126 + Theme/Backend/Lang/ko.lang.php | 126 + Theme/Backend/Lang/no.lang.php | 126 + Theme/Backend/Lang/pl.lang.php | 126 + Theme/Backend/Lang/pt.lang.php | 126 + Theme/Backend/Lang/ru.lang.php | 126 + Theme/Backend/Lang/sv.lang.php | 126 + Theme/Backend/Lang/th.lang.php | 126 + Theme/Backend/Lang/tr.lang.php | 126 + Theme/Backend/Lang/uk.lang.php | 126 + Theme/Backend/Lang/zh.lang.php | 126 + Theme/Backend/vehicle-create.tpl.php | 289 ++ Theme/Backend/vehicle-list.tpl.php | 128 + Theme/Backend/vehicle-profile.tpl.php | 618 +++ composer.json | 20 + composer.lock | 4802 +++++++++++++++++++++ info.json | 49 + tests/Admin/AdminTest.php | 27 + tests/Autoloader.php | 94 + tests/Bootstrap.php | 415 ++ tests/Controller/ApiControllerTest.php | 88 + tests/Models/Vehicle.php | 20 + tests/phpunit_default.xml | 57 + 82 files changed, 11230 insertions(+) create mode 100755 .github/dev_bug_report.md create mode 100755 .github/dev_feature_request.md create mode 100755 .github/user_bug_report.md create mode 100755 .github/user_feature_request.md create mode 100755 .github/workflows/greetings.yml create mode 100755 .github/workflows/image.yml create mode 100755 .github/workflows/main.yml create mode 100755 .gitignore create mode 100755 Admin/Install/Media.install.json create mode 100755 Admin/Install/Media.php create mode 100755 Admin/Install/Navigation.install.json create mode 100755 Admin/Install/Navigation.php create mode 100755 Admin/Install/db.json create mode 100755 Admin/Installer.php create mode 100755 Admin/Routes/Web/Backend.php create mode 100755 Admin/Status.php create mode 100755 Admin/Uninstaller.php create mode 100755 Admin/Updater.php create mode 100755 Controller.js create mode 100755 Controller/ApiController.php create mode 100755 Controller/BackendController.php create mode 100755 Controller/Controller.php create mode 100755 Docs/Dev/en/SUMMARY.md create mode 100755 Docs/Dev/en/structure.md create mode 100755 Docs/Dev/img/er.png create mode 100755 Models/PermissionCategory.php create mode 100755 Theme/Backend/Lang/Navigation.ar.lang.php create mode 100755 Theme/Backend/Lang/Navigation.cs.lang.php create mode 100755 Theme/Backend/Lang/Navigation.da.lang.php create mode 100755 Theme/Backend/Lang/Navigation.de.lang.php create mode 100755 Theme/Backend/Lang/Navigation.el.lang.php create mode 100755 Theme/Backend/Lang/Navigation.en.lang.php create mode 100755 Theme/Backend/Lang/Navigation.es.lang.php create mode 100755 Theme/Backend/Lang/Navigation.fi.lang.php create mode 100755 Theme/Backend/Lang/Navigation.fr.lang.php create mode 100755 Theme/Backend/Lang/Navigation.hu.lang.php create mode 100755 Theme/Backend/Lang/Navigation.it.lang.php create mode 100755 Theme/Backend/Lang/Navigation.ja.lang.php create mode 100755 Theme/Backend/Lang/Navigation.ko.lang.php create mode 100755 Theme/Backend/Lang/Navigation.no.lang.php create mode 100755 Theme/Backend/Lang/Navigation.pl.lang.php create mode 100755 Theme/Backend/Lang/Navigation.pt.lang.php create mode 100755 Theme/Backend/Lang/Navigation.ru.lang.php create mode 100755 Theme/Backend/Lang/Navigation.sv.lang.php create mode 100755 Theme/Backend/Lang/Navigation.th.lang.php create mode 100755 Theme/Backend/Lang/Navigation.tr.lang.php create mode 100755 Theme/Backend/Lang/Navigation.uk.lang.php create mode 100755 Theme/Backend/Lang/Navigation.zh.lang.php create mode 100755 Theme/Backend/Lang/ar.lang.php create mode 100755 Theme/Backend/Lang/cs.lang.php create mode 100755 Theme/Backend/Lang/da.lang.php create mode 100755 Theme/Backend/Lang/de.lang.php create mode 100755 Theme/Backend/Lang/el.lang.php create mode 100755 Theme/Backend/Lang/en.lang.php create mode 100755 Theme/Backend/Lang/es.lang.php create mode 100755 Theme/Backend/Lang/fi.lang.php create mode 100755 Theme/Backend/Lang/fr.lang.php create mode 100755 Theme/Backend/Lang/hu.lang.php create mode 100755 Theme/Backend/Lang/it.lang.php create mode 100755 Theme/Backend/Lang/ja.lang.php create mode 100755 Theme/Backend/Lang/ko.lang.php create mode 100755 Theme/Backend/Lang/no.lang.php create mode 100755 Theme/Backend/Lang/pl.lang.php create mode 100755 Theme/Backend/Lang/pt.lang.php create mode 100755 Theme/Backend/Lang/ru.lang.php create mode 100755 Theme/Backend/Lang/sv.lang.php create mode 100755 Theme/Backend/Lang/th.lang.php create mode 100755 Theme/Backend/Lang/tr.lang.php create mode 100755 Theme/Backend/Lang/uk.lang.php create mode 100755 Theme/Backend/Lang/zh.lang.php create mode 100755 Theme/Backend/vehicle-create.tpl.php create mode 100755 Theme/Backend/vehicle-list.tpl.php create mode 100755 Theme/Backend/vehicle-profile.tpl.php create mode 100755 composer.json create mode 100755 composer.lock create mode 100755 info.json create mode 100755 tests/Admin/AdminTest.php create mode 100755 tests/Autoloader.php create mode 100755 tests/Bootstrap.php create mode 100755 tests/Controller/ApiControllerTest.php create mode 100644 tests/Models/Vehicle.php create mode 100755 tests/phpunit_default.xml diff --git a/.github/dev_bug_report.md b/.github/dev_bug_report.md new file mode 100755 index 0000000..ef93e56 --- /dev/null +++ b/.github/dev_bug_report.md @@ -0,0 +1,35 @@ +--- +name: Dev Bug Report +about: Create a report to help us improve +title: '' +labels: stat_backlog, type_bug +assignees: '' + +--- + +# Bug Description +A clear and concise description of what the bug is. + +# How to Reproduce + +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +## Minimal Code Example + +``` +// your code ... +``` + +# Expected Behavior +A clear and concise description of what you expected to happen. + +# Screenshots +If applicable, add screenshots to help explain your problem. + +# Additional Information +Add any other context about the problem here. diff --git a/.github/dev_feature_request.md b/.github/dev_feature_request.md new file mode 100755 index 0000000..9573c35 --- /dev/null +++ b/.github/dev_feature_request.md @@ -0,0 +1,18 @@ +--- +name: Dev Feature Request +about: Suggest an idea for this project +title: '' +labels: stat_backlog, type_feature +assignees: '' + +--- + +# What is the feature you request +* A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +* A clear and concise description of what you want to happen. + +# Alternatives +A clear and concise description of any alternative solutions or features you've considered. + +# Additional Information +Add any other context or screenshots about the feature request here. diff --git a/.github/user_bug_report.md b/.github/user_bug_report.md new file mode 100755 index 0000000..9e5f2a5 --- /dev/null +++ b/.github/user_bug_report.md @@ -0,0 +1,34 @@ +--- +name: User Bug Report +about: Create a report to help us improve +title: '' +labels: stat_backlog, type_bug +assignees: '' + +--- + +# Bug Description +A clear and concise description of what the bug is. + +# How to Reproduce +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +# Expected Behavior +A clear and concise description of what you expected to happen. + +# Screenshots +If applicable, add screenshots to help explain your problem. + +# System Information + - System: [e.g. PC or iPhone11, ...] + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - KarakaVersion [e.g. 22] + +# Additional Information +Add any other context about the problem here. diff --git a/.github/user_feature_request.md b/.github/user_feature_request.md new file mode 100755 index 0000000..6eb8ddc --- /dev/null +++ b/.github/user_feature_request.md @@ -0,0 +1,18 @@ +--- +name: User Feature Request +about: Suggest an idea for this project +title: '' +labels: stat_backlog, type_feature +assignees: '' + +--- + +# What is the feature you request +* A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +* A clear and concise description of what you want to happen. + +# Alternatives +A clear and concise description of any alternative solutions or features you've considered. + +# Additional Information +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100755 index 0000000..adb8716 --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,13 @@ +name: Greetings + +on: [pull_request, issues] + +jobs: + greeting: + runs-on: ubuntu-latest + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: 'Thank you for createing this issue. We will check it as soon as possible.' + pr-message: 'Thank you for your pull request. We will check it as soon as possible.' diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml new file mode 100755 index 0000000..d079329 --- /dev/null +++ b/.github/workflows/image.yml @@ -0,0 +1,24 @@ +name: Compress images +on: + push: + paths: + - '**.jpg' + - '**.png' + - '**.webp' + pull_request: + paths: + - '**.jpg' + - '**.png' + - '**.webp' +jobs: + build: + name: calibreapp/image-actions + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@main + + - name: Compress Images + uses: calibreapp/image-actions@main + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100755 index 0000000..6dcd721 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,281 @@ +name: CI + +on: [push, pull_request] + +jobs: + autoformat: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'NO_CI')" + strategy: + fail-fast: false + max-parallel: 3 + steps: + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + - name: Get Composer Cache Directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + - name: Setup Composer + run: composer install + - name: Autoformat + run: 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes' + - name: Check for modified files + id: git-check + run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) + - name: Push changes + if: steps.git-check.outputs.modified == 'true' + run: | + git config --global user.name 'Formatter Bot' + git config --global user.email 'formatter.bot@karaka.app' + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} + git commit -am "Automated formatting changes" + git push + code-tests: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'NO_CI')" + services: + mysql: + image: mysql:5.7 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: false + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: oms + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + postgres: + image: postgres:10.8 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: root + POSTGRES_DB: oms + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 + redis: + image: redis + ports: + - 6379:6379 + options: --entrypoint redis-server + memcached: + image: memcached + ports: + - 11211:11211 + strategy: + fail-fast: false + max-parallel: 3 + matrix: + php-versions: ['8.1'] + steps: + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + - name: Checkout Build Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/Build + path: Build + - name: Checkout Resource Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/Resources + path: Resources + - name: Checkout phpOMS Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/phpOMS + path: phpOMS + token: ${{ secrets.GH_PAT }} + - name: Checkout Karaka Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/Karaka + path: Karaka + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached + ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 + coverage: pcov + - name: Get Composer Cache Directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + - name: Setup Composer + run: composer install + - name: phpunit + run: vendor/bin/phpunit --coverage-clover tests/coverage.xml --configuration tests/phpunit_default.xml + static-tests: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'NO_CI')" + strategy: + fail-fast: false + max-parallel: 3 + matrix: + php-versions: ['8.1'] + steps: + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + submodules: recursive + token: ${{ secrets.GH_PAT }} + - name: Checkout Build Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/Build + path: Build + - name: Checkout phpOMS Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/phpOMS + path: phpOMS + token: ${{ secrets.GH_PAT }} + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached + ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 + - name: Get Composer Cache Directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + - name: Setup Composer + run: composer install + - name: phpstan + run: vendor/bin/phpstan analyse -a phpOMS/Autoloader.php --no-progress -l 9 -c Build/Config/phpstan.neon ./ + codestyle-tests: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'NO_CI')" + strategy: + fail-fast: false + max-parallel: 3 + matrix: + php-versions: ['8.1'] + steps: + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + submodules: recursive + token: ${{ secrets.GH_PAT }} + - name: Checkout Build Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/Build + path: Build + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached + ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 + - name: Get Composer Cache Directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + - name: Setup Composer + run: composer install + - name: phpcs + run: vendor/bin/phpcs --severity=1 ./ --standard="Build/Config/phpcs.xml" -s --report=full + - name: Install NPM + uses: actions/setup-node@v3 + with: + node-version: '14' + cache: 'npm' + - run: npm install + - name: eslint + run: npx eslint ./ -c Build/Config/.eslintrc.json +# linting: +# runs-on: ubuntu-latest +# if: "!contains(github.event.head_commit.message, 'NO_CI')" +# strategy: +# fail-fast: false +# max-parallel: 3 +# steps: +# - name: Checkout Repository +# uses: actions/checkout@main +# with: +# fetch-depth: 0 +# submodules: recursive +# token: ${{ secrets.GH_TOKEN }} +# - name: Lint Code Base +# uses: github/super-linter/slim@v4 +# env: +# VALIDATE_ALL_CODEBASE: false +# VALIDATE_PHP: true +# VALIDATE_PHP_BUILTIN: true +# DEFAULT_BRANCH: develop +# GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + custom: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'NO_CI')" + strategy: + fail-fast: false + max-parallel: 3 + matrix: + php-versions: ['8.1'] + steps: + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + - name: Checkout Build Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/Build + path: Build + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, bcmath, redis, memcached + ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 + - name: PHP linting + run: | + find ./ -type f \ + -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v "No syntax errors detected" ) + - name: Php strict + run: if [[ $(grep -r -L "declare(strict_types=1);" --include=*.php --exclude={*.tpl.php,*Hooks.php,*Routes.php,*SearchCommands.php} ./) -ne "" ]]; then exit 1; fi diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..22d0d82 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/Admin/Install/Media.install.json b/Admin/Install/Media.install.json new file mode 100755 index 0000000..672b5b8 --- /dev/null +++ b/Admin/Install/Media.install.json @@ -0,0 +1,9 @@ +[ + { + "type": "collection", + "create_directory": true, + "name": "FleetManagement", + "virtualPath": "/Modules", + "user": 1 + } +] \ No newline at end of file diff --git a/Admin/Install/Media.php b/Admin/Install/Media.php new file mode 100755 index 0000000..ee82fd1 --- /dev/null +++ b/Admin/Install/Media.php @@ -0,0 +1,43 @@ + __DIR__ . '/Media.install.json']); + } +} diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json new file mode 100755 index 0000000..7e031ca --- /dev/null +++ b/Admin/Install/Navigation.install.json @@ -0,0 +1,110 @@ +[ + { + "id": 1003501001, + "pid": "/", + "type": 2, + "subtype": 0, + "name": "FleetManagement", + "uri": null, + "target": "self", + "icon": "fa fa-car", + "order": 80, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 0, + "children": [ + { + "id": 1003502001, + "pid": "/", + "type": 2, + "subtype": 1, + "name": "Vehicles", + "uri": "{/lang}/{/app}/fleet/client/list", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003501001, + "children": [ + { + "id": 1003502101, + "pid": "/fleet/vehicle", + "type": 3, + "subtype": 1, + "name": "List", + "uri": "{/lang}/{/app}/fleet/vehicle/list", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003502001, + "children": [] + }, + { + "id": 1003502201, + "pid": "/fleet/vehicle", + "type": 3, + "subtype": 1, + "name": "Create", + "uri": "{/lang}/{/app}/fleet/vehicle/create?{?}", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 4, "category": null, "element": null }, + "parent": 1003502001, + "children": [] + } + ] + }, + { + "id": 1003503001, + "pid": "/", + "type": 2, + "subtype": 1, + "name": "Attributes", + "uri": "{/lang}/{/app}/fleet/vehicle/attribute/type/list?{?}", + "target": "self", + "icon": null, + "order": 5, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003501001, + "children": [ + { + "id": 1003503101, + "pid": "/sales", + "type": 3, + "subtype": 1, + "name": "Types", + "uri": "{/lang}/{/app}/fleet/vehicle/attribute/type/list?{?}", + "target": "self", + "icon": null, + "order": 15, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003503001, + "children": [] + }, + { + "id": 1003503201, + "pid": "/sales", + "type": 3, + "subtype": 1, + "name": "Values", + "uri": "{/lang}/{/app}/fleet/vehicle/attribute/value/list?{?}", + "target": "self", + "icon": null, + "order": 15, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003503001, + "children": [] + } + ] + } + ] + } +] diff --git a/Admin/Install/Navigation.php b/Admin/Install/Navigation.php new file mode 100755 index 0000000..bebc194 --- /dev/null +++ b/Admin/Install/Navigation.php @@ -0,0 +1,43 @@ + __DIR__ . '/Navigation.install.json']); + } +} diff --git a/Admin/Install/db.json b/Admin/Install/db.json new file mode 100755 index 0000000..651ca07 --- /dev/null +++ b/Admin/Install/db.json @@ -0,0 +1,405 @@ +{ + "fleetmgmt_vehicle": { + "name": "fleetmgmt_vehicle", + "fields": { + "fleetmgmt_vehicle_id": { + "name": "fleetmgmt_vehicle_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_status": { + "name": "fleetmgmt_vehicle_status", + "type": "TINYINT", + "null": false + }, + "fleetmgmt_vehicle_type": { + "name": "fleetmgmt_vehicle_type", + "type": "TINYINT", + "null": false + }, + "fleetmgmt_vehicle_info": { + "name": "fleetmgmt_vehicle_info", + "type": "TEXT", + "null": false + }, + "fleetmgmt_vehicle_created_at": { + "name": "fleetmgmt_vehicle_created_at", + "type": "DATETIME", + "null": false + }, + "fleetmgmt_vehicle_responsible": { + "name": "fleetmgmt_vehicle_responsible", + "type": "INT", + "null": false, + "foreignTable": "account", + "foreignKey": "account_id" + }, + "fleetmgmt_vehicle_unit": { + "name": "fleetmgmt_vehicle_unit", + "type": "INT", + "default": null, + "null": true, + "foreignTable": "unit", + "foreignKey": "unit_id" + } + } + }, + "fleetmgmt_vehicle_responsible": { + "name": "fleetmgmt_vehicle_responsible", + "fields": { + "fleetmgmt_vehicle_responsible_id": { + "name": "fleetmgmt_vehicle_responsible_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_responsible_description": { + "name": "fleetmgmt_vehicle_responsible_description", + "type": "TEXT", + "null": false + }, + "fleetmgmt_vehicle_responsible_account": { + "name": "fleetmgmt_vehicle_responsible_account", + "type": "INT", + "null": false, + "foreignTable": "account", + "foreignKey": "account_id" + }, + "fleetmgmt_vehicle_responsible_start": { + "name": "fleetmgmt_vehicle_responsible_start", + "type": "DATETIME", + "null": false + }, + "fleetmgmt_vehicle_responsible_end": { + "name": "fleetmgmt_vehicle_responsible_end", + "type": "DATETIME", + "null": true, + "default": null + } + } + }, + "fleetmgmt_vehicle_usage": { + "name": "fleetmgmt_vehicle_usage", + "fields": { + "fleetmgmt_vehicle_usage_id": { + "name": "fleetmgmt_vehicle_usage_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_usage_type": { + "name": "fleetmgmt_vehicle_usage_type", + "type": "INT", + "null": false + }, + "fleetmgmt_vehicle_usage_account": { + "name": "fleetmgmt_vehicle_usage_account", + "type": "INT", + "null": false, + "foreignTable": "account", + "foreignKey": "account_id" + }, + "fleetmgmt_vehicle_usage_start": { + "name": "fleetmgmt_vehicle_usage_start", + "type": "DATETIME", + "null": false + }, + "fleetmgmt_vehicle_usage_end": { + "name": "fleetmgmt_vehicle_usage_end", + "type": "DATETIME", + "null": true, + "default": null + }, + "fleetmgmt_vehicle_usage_distance": { + "name": "fleetmgmt_vehicle_usage_distance", + "type": "INT", + "null": false + } + } + }, + "fleetmgmt_attr_type": { + "name": "fleetmgmt_attr_type", + "fields": { + "fleetmgmt_attr_type_id": { + "name": "fleetmgmt_attr_type_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_attr_type_name": { + "name": "fleetmgmt_attr_type_name", + "type": "VARCHAR(255)", + "null": false, + "unique": true + }, + "fleetmgmt_attr_type_datatype": { + "name": "fleetmgmt_attr_type_datatype", + "type": "INT(11)", + "null": false + }, + "fleetmgmt_attr_type_fields": { + "name": "fleetmgmt_attr_type_fields", + "type": "INT(11)", + "null": false + }, + "fleetmgmt_attr_type_custom": { + "name": "fleetmgmt_attr_type_custom", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_attr_type_required": { + "description": "Every item must have this attribute type if set to true.", + "name": "fleetmgmt_attr_type_required", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_attr_type_pattern": { + "description": "This is a regex validation pattern.", + "name": "fleetmgmt_attr_type_pattern", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "fleetmgmt_attr_type_l11n": { + "name": "fleetmgmt_attr_type_l11n", + "fields": { + "fleetmgmt_attr_type_l11n_id": { + "name": "fleetmgmt_attr_type_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_attr_type_l11n_title": { + "name": "fleetmgmt_attr_type_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_attr_type_l11n_type": { + "name": "fleetmgmt_attr_type_l11n_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_type", + "foreignKey": "fleetmgmt_attr_type_id" + }, + "fleetmgmt_attr_type_l11n_lang": { + "name": "fleetmgmt_attr_type_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, + "fleetmgmt_attr_value": { + "name": "fleetmgmt_attr_value", + "fields": { + "fleetmgmt_attr_value_id": { + "name": "fleetmgmt_attr_value_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_attr_value_default": { + "name": "fleetmgmt_attr_value_default", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_attr_value_valueStr": { + "name": "fleetmgmt_attr_value_valueStr", + "type": "VARCHAR(255)", + "null": true, + "default": null + }, + "fleetmgmt_attr_value_valueInt": { + "name": "fleetmgmt_attr_value_valueInt", + "type": "INT(11)", + "null": true, + "default": null + }, + "fleetmgmt_attr_value_valueDec": { + "name": "fleetmgmt_attr_value_valueDec", + "type": "DECIMAL(19,5)", + "null": true, + "default": null + }, + "fleetmgmt_attr_value_valueDat": { + "name": "fleetmgmt_attr_value_valueDat", + "type": "DATETIME", + "null": true, + "default": null + }, + "fleetmgmt_attr_value_unit": { + "name": "fleetmgmt_attr_value_unit", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_attr_value_deptype": { + "name": "fleetmgmt_attr_value_deptype", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "fleetmgmt_attr_type", + "foreignKey": "fleetmgmt_attr_type_id" + }, + "fleetmgmt_attr_value_depvalue": { + "name": "fleetmgmt_attr_value_depvalue", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "fleetmgmt_attr_value", + "foreignKey": "fleetmgmt_attr_value_id" + } + } + }, + "fleetmgmt_attr_value_l11n": { + "name": "fleetmgmt_attr_value_l11n", + "fields": { + "fleetmgmt_attr_value_l11n_id": { + "name": "fleetmgmt_attr_value_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_attr_value_l11n_title": { + "name": "fleetmgmt_attr_value_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_attr_value_l11n_value": { + "name": "fleetmgmt_attr_value_l11n_value", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_value", + "foreignKey": "fleetmgmt_attr_value_id" + }, + "fleetmgmt_attr_value_l11n_lang": { + "name": "fleetmgmt_attr_value_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, + "fleetmgmt_vehicle_attr_default": { + "name": "fleetmgmt_vehicle_attr_default", + "fields": { + "fleetmgmt_vehicle_attr_default_id": { + "name": "fleetmgmt_vehicle_attr_default_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_attr_default_type": { + "name": "fleetmgmt_vehicle_attr_default_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_type", + "foreignKey": "fleetmgmt_attr_type_id" + }, + "fleetmgmt_vehicle_attr_default_value": { + "name": "fleetmgmt_vehicle_attr_default_value", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_value", + "foreignKey": "fleetmgmt_attr_value_id" + } + } + }, + "fleetmgmt_vehicle_attr": { + "name": "fleetmgmt_vehicle_attr", + "fields": { + "fleetmgmt_vehicle_attr_id": { + "name": "fleetmgmt_vehicle_attr_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_attr_vehicle": { + "name": "fleetmgmt_vehicle_attr_vehicle", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_vehicle", + "foreignKey": "fleetmgmt_vehicle_id" + }, + "fleetmgmt_vehicle_attr_type": { + "name": "fleetmgmt_vehicle_attr_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_type", + "foreignKey": "fleetmgmt_attr_type_id" + }, + "fleetmgmt_vehicle_attr_value": { + "name": "fleetmgmt_vehicle_attr_value", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "fleetmgmt_attr_value", + "foreignKey": "fleetmgmt_attr_value_id" + } + } + }, + "fleetmgmt_vehicle_media": { + "name": "fleetmgmt_vehicle_media", + "fields": { + "fleetmgmt_vehicle_media_id": { + "name": "fleetmgmt_vehicle_media_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_media_dst": { + "name": "fleetmgmt_vehicle_media_dst", + "type": "INT", + "null": false, + "foreignTable": "media", + "foreignKey": "media_id" + }, + "fleetmgmt_vehicle_media_src": { + "name": "fleetmgmt_vehicle_media_src", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_vehicle", + "foreignKey": "fleetmgmt_vehicle_id" + } + } + }, + "fleetmgmt_vehicle_note": { + "name": "fleetmgmt_vehicle_note", + "fields": { + "fleetmgmt_vehicle_note_id": { + "name": "fleetmgmt_vehicle_note_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_note_dst": { + "name": "fleetmgmt_vehicle_note_dst", + "type": "INT", + "null": false, + "foreignTable": "editor_doc", + "foreignKey": "editor_doc_id" + }, + "fleetmgmt_vehicle_note_src": { + "name": "fleetmgmt_vehicle_note_src", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_vehicle", + "foreignKey": "fleetmgmt_vehicle_id" + } + } + } +} \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php new file mode 100755 index 0000000..cc9ac9a --- /dev/null +++ b/Admin/Installer.php @@ -0,0 +1,50 @@ + [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementAttributeTypeList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/vehicle/attribute/type\?.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementAttributeType', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/vehicle/list.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/vehicle/create.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleCreate', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::CREATE, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/vehicle/profile.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleProfile', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], +]; diff --git a/Admin/Status.php b/Admin/Status.php new file mode 100755 index 0000000..7e387fa --- /dev/null +++ b/Admin/Status.php @@ -0,0 +1,36 @@ +1tv%;lbMZk@UgiohH8Bwp(G|$^XUarG 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

fvDEQrSysTM~UV@u)Wc)c^S+_-E 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 z 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 z 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

3rA0&0A9H@Yv8-N}M;vkO`cL3gYd!!wg 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 w{fqyer1$4@{ww_Z=l| [ + 'Client' => 'عميل', + 'Region' => 'منطقة', + 'SalesRep' => 'مندول المبيعات', +]]; diff --git a/Theme/Backend/Lang/Navigation.cs.lang.php b/Theme/Backend/Lang/Navigation.cs.lang.php new file mode 100755 index 0000000..b0dc3bd --- /dev/null +++ b/Theme/Backend/Lang/Navigation.cs.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Klienta', + 'Region' => 'Kraj', + 'SalesRep' => 'Obchodní zástupce', +]]; diff --git a/Theme/Backend/Lang/Navigation.da.lang.php b/Theme/Backend/Lang/Navigation.da.lang.php new file mode 100755 index 0000000..af6ee4c --- /dev/null +++ b/Theme/Backend/Lang/Navigation.da.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Klient', + 'Region' => 'Område', + 'SalesRep' => 'Salgsrepræsentant', +]]; diff --git a/Theme/Backend/Lang/Navigation.de.lang.php b/Theme/Backend/Lang/Navigation.de.lang.php new file mode 100755 index 0000000..532e4ca --- /dev/null +++ b/Theme/Backend/Lang/Navigation.de.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Klient', + 'Region' => 'Region', + 'SalesRep' => 'VerkäufeRep', +]]; diff --git a/Theme/Backend/Lang/Navigation.el.lang.php b/Theme/Backend/Lang/Navigation.el.lang.php new file mode 100755 index 0000000..816f3ab --- /dev/null +++ b/Theme/Backend/Lang/Navigation.el.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Πελάτης', + 'Region' => 'Περιοχή', + 'SalesRep' => 'Αντιπρόσωπος Πωλήσεων', +]]; diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php new file mode 100755 index 0000000..7e84efb --- /dev/null +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Client', + 'Region' => 'Region', + 'SalesRep' => 'SalesRep', +]]; diff --git a/Theme/Backend/Lang/Navigation.es.lang.php b/Theme/Backend/Lang/Navigation.es.lang.php new file mode 100755 index 0000000..50b9f95 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.es.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Cliente', + 'Region' => 'Región', + 'SalesRep' => 'Vendedores', +]]; diff --git a/Theme/Backend/Lang/Navigation.fi.lang.php b/Theme/Backend/Lang/Navigation.fi.lang.php new file mode 100755 index 0000000..1fdb589 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.fi.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Asiakas', + 'Region' => 'Alue', + 'SalesRep' => 'Myyntiedustaja', +]]; diff --git a/Theme/Backend/Lang/Navigation.fr.lang.php b/Theme/Backend/Lang/Navigation.fr.lang.php new file mode 100755 index 0000000..1674a29 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.fr.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Client', + 'Region' => 'Région', + 'SalesRep' => 'Représentant commercial', +]]; diff --git a/Theme/Backend/Lang/Navigation.hu.lang.php b/Theme/Backend/Lang/Navigation.hu.lang.php new file mode 100755 index 0000000..9f34a1b --- /dev/null +++ b/Theme/Backend/Lang/Navigation.hu.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Ügyfél', + 'Region' => 'Vidék', + 'SalesRep' => 'Értékesítés', +]]; diff --git a/Theme/Backend/Lang/Navigation.it.lang.php b/Theme/Backend/Lang/Navigation.it.lang.php new file mode 100755 index 0000000..898dfe1 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.it.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Cliente', + 'Region' => 'Regione', + 'SalesRep' => 'Rappresentante delle vendite', +]]; diff --git a/Theme/Backend/Lang/Navigation.ja.lang.php b/Theme/Backend/Lang/Navigation.ja.lang.php new file mode 100755 index 0000000..daf2208 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.ja.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'クライアント', + 'Region' => '領域', + 'SalesRep' => 'セールスレート', +]]; diff --git a/Theme/Backend/Lang/Navigation.ko.lang.php b/Theme/Backend/Lang/Navigation.ko.lang.php new file mode 100755 index 0000000..e12496b --- /dev/null +++ b/Theme/Backend/Lang/Navigation.ko.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => '고객', + 'Region' => '지역', + 'SalesRep' => '매출액', +]]; diff --git a/Theme/Backend/Lang/Navigation.no.lang.php b/Theme/Backend/Lang/Navigation.no.lang.php new file mode 100755 index 0000000..f40e6b1 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.no.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Klient', + 'Region' => 'Region', + 'SalesRep' => 'SalesRep.', +]]; diff --git a/Theme/Backend/Lang/Navigation.pl.lang.php b/Theme/Backend/Lang/Navigation.pl.lang.php new file mode 100755 index 0000000..0d2ee58 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.pl.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Klient', + 'Region' => 'Region', + 'SalesRep' => 'Przedstawiciel handlowy', +]]; diff --git a/Theme/Backend/Lang/Navigation.pt.lang.php b/Theme/Backend/Lang/Navigation.pt.lang.php new file mode 100755 index 0000000..5273a46 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.pt.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Cliente', + 'Region' => 'Região', + 'SalesRep' => 'Representante de vendas', +]]; diff --git a/Theme/Backend/Lang/Navigation.ru.lang.php b/Theme/Backend/Lang/Navigation.ru.lang.php new file mode 100755 index 0000000..7e3210c --- /dev/null +++ b/Theme/Backend/Lang/Navigation.ru.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Клиент', + 'Region' => 'Область', + 'SalesRep' => 'Торговый представитель', +]]; diff --git a/Theme/Backend/Lang/Navigation.sv.lang.php b/Theme/Backend/Lang/Navigation.sv.lang.php new file mode 100755 index 0000000..7227e7f --- /dev/null +++ b/Theme/Backend/Lang/Navigation.sv.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Klient', + 'Region' => 'Område', + 'SalesRep' => 'Säljare', +]]; diff --git a/Theme/Backend/Lang/Navigation.th.lang.php b/Theme/Backend/Lang/Navigation.th.lang.php new file mode 100755 index 0000000..b10f311 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.th.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'ลูกค้า', + 'Region' => 'ภูมิภาค', + 'SalesRep' => 'ตัวแทนฝ่ายขาย', +]]; diff --git a/Theme/Backend/Lang/Navigation.tr.lang.php b/Theme/Backend/Lang/Navigation.tr.lang.php new file mode 100755 index 0000000..9098354 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.tr.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Müşteri', + 'Region' => 'Bölge', + 'SalesRep' => 'Satıcı', +]]; diff --git a/Theme/Backend/Lang/Navigation.uk.lang.php b/Theme/Backend/Lang/Navigation.uk.lang.php new file mode 100755 index 0000000..cad1789 --- /dev/null +++ b/Theme/Backend/Lang/Navigation.uk.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => 'Клієнт', + 'Region' => 'Регіон', + 'SalesRep' => 'Торговий представник', +]]; diff --git a/Theme/Backend/Lang/Navigation.zh.lang.php b/Theme/Backend/Lang/Navigation.zh.lang.php new file mode 100755 index 0000000..25f25df --- /dev/null +++ b/Theme/Backend/Lang/Navigation.zh.lang.php @@ -0,0 +1,19 @@ + [ + 'Client' => '客户', + 'Region' => '地区', + 'SalesRep' => '销售代表', +]]; diff --git a/Theme/Backend/Lang/ar.lang.php b/Theme/Backend/Lang/ar.lang.php new file mode 100755 index 0000000..1b73d15 --- /dev/null +++ b/Theme/Backend/Lang/ar.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'محاسبة', + 'Addition' => 'إضافة', + 'Address' => 'تبوك', + 'Addresses' => 'عناوين', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'مدير المنطقة', + 'Articlegroup' => 'articlegroup.', + 'Articles' => 'مقالات', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'الرصيد', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'علاوة', + 'Business' => 'اعمال', + 'CIS' => '#VALUE!', + 'CLV' => 'قذيفة', + 'Calendar' => 'تقويم', + 'City' => 'مدينة', + 'Client' => 'عميل', + 'ClientID' => '#VALUE!', + 'Clients' => 'عملاء', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'اتصل', + 'Country' => 'دولة', + 'Created' => 'خلقت', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'التصنيف الائتماني', + 'Creditcard' => 'بطاقة إئتمان', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO.', + 'Date' => 'تاريخ', + 'Default' => 'تقصير', + 'Delivery' => 'توصيل', + 'Discount' => 'خصم', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'خصم ٪', + 'Documents' => 'وثائق', + 'Due' => 'بسبب', + 'Email' => 'بريد الالكتروني', + 'Europe' => '#VALUE!', + 'Fax' => 'فاكس', + 'Files' => 'الملفات', + 'Filter' => 'منقي', + 'Freightage' => 'شحن', + 'Group' => 'مجموعة', + 'ID' => 'بطاقة تعريف', + 'Info' => 'معلومات', + 'Invoice' => 'فاتورة', + 'Invoices' => 'الفواتير', + 'IsDefault' => 'افتراضي؟', + 'Items' => '#VALUE!', + 'LastContact' => 'آخر اتصال', + 'LastOrder' => 'آخر طلب', + 'Log' => 'سجل', + 'Logs' => 'السجلات', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'مرر', + 'MTDSales' => 'مبيعات MTD', + 'Margin' => 'هامش', + 'Messages' => 'رسائل', + 'Modified' => 'تم التعديل', + 'Modules' => 'وحدات', + 'Name' => 'اسم', + 'Name1' => 'اسم 1.', + 'Name2' => 'اسم 2.', + 'Name3' => 'اسم 3.', + 'Net' => 'شبكة', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'ملحوظات', + 'Number' => 'عدد', + 'Office' => 'مكتب. مقر. مركز', + 'Other' => '#VALUE!', + 'Payment' => 'دفع', + 'PaymentTerm' => 'مصطلح الدفع', + 'Permission' => 'إذن', + 'Phone' => 'هاتف', + 'Postal' => 'بريدي', + 'Price' => 'السعر', + 'Prices' => 'الأسعار.', + 'Private' => 'نشر', + 'Productgroup' => 'productgroup.', + 'Profile' => 'الملف الشخصي', + 'Profit' => '#VALUE!', + 'Purchase' => 'شراء', + 'Quantity' => 'كمية', + 'RecentInvoices' => 'الفواتير الأخيرة', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'مبيعات', + 'Segment' => 'قطعة', + 'Segments' => 'شرائح', + 'Subtype' => 'النوع الفرعي', + 'Support' => 'يدعم', + 'Tags' => 'كذا', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'نوع', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'موقع إلكتروني', + 'Wire' => 'الأسلاك', + 'YTDSales' => 'مبيعات YTD', + 'Zip' => 'أزيز', +]]; diff --git a/Theme/Backend/Lang/cs.lang.php b/Theme/Backend/Lang/cs.lang.php new file mode 100755 index 0000000..710f7a5 --- /dev/null +++ b/Theme/Backend/Lang/cs.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Účetnictví', + 'Addition' => 'Přidání', + 'Address' => 'Adresa', + 'Addresses' => 'Adresy', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Oblastní manažer', + 'Articlegroup' => 'Článek', + 'Articles' => 'Články', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Zůstatek', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus', + 'Business' => 'Business.', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv.', + 'Calendar' => 'Kalendář', + 'City' => 'Město', + 'Client' => 'Klienta', + 'ClientID' => '#VALUE!', + 'Clients' => 'Klienti', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Kontakt', + 'Country' => 'Země', + 'Created' => 'Vytvořený', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Úvěrový rating', + 'Creditcard' => 'Kreditní karta', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO.', + 'Date' => 'datum', + 'Default' => 'Výchozí hodnota', + 'Delivery' => 'dodávka', + 'Discount' => 'Sleva', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Sleva%', + 'Documents' => 'Dokumenty', + 'Due' => 'Způsoben', + 'Email' => 'E-mailem', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'Soubory', + 'Filter' => 'Filtr', + 'Freightage' => 'Dopravné', + 'Group' => 'Skupina', + 'ID' => 'ID.', + 'Info' => 'Info.', + 'Invoice' => 'Faktura', + 'Invoices' => 'Faktury', + 'IsDefault' => 'Je výchozí?', + 'Items' => '#VALUE!', + 'LastContact' => 'Poslední kontakt', + 'LastOrder' => 'Poslední objednávka', + 'Log' => 'Log', + 'Logs' => 'Protokoly', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr.', + 'MTDSales' => 'Prodej MTD.', + 'Margin' => 'Okraj', + 'Messages' => 'Zprávy', + 'Modified' => 'Upravený', + 'Modules' => 'Moduly', + 'Name' => 'název', + 'Name1' => 'Jméno1.', + 'Name2' => 'Jméno2.', + 'Name3' => 'Jméno3.', + 'Net' => 'Síť', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Poznámky', + 'Number' => 'Číslo', + 'Office' => 'Kancelář', + 'Other' => '#VALUE!', + 'Payment' => 'Způsob platby', + 'PaymentTerm' => 'Platební termín', + 'Permission' => 'Povolení', + 'Phone' => 'Telefon', + 'Postal' => 'Poštovní', + 'Price' => 'Cena', + 'Prices' => 'Ceny', + 'Private' => 'Soukromý', + 'Productgroup' => 'ProductSgroup.', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Nákup', + 'Quantity' => 'Množství', + 'RecentInvoices' => 'Nedávné faktury', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Odbyt', + 'Segment' => 'Segment', + 'Segments' => 'Segmenty', + 'Subtype' => 'Podtyp', + 'Support' => 'Podpěra, podpora', + 'Tags' => 'Tagy', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Typ', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'webová stránka', + 'Wire' => 'Drát', + 'YTDSales' => 'Prodej YTD.', + 'Zip' => 'Zip', +]]; diff --git a/Theme/Backend/Lang/da.lang.php b/Theme/Backend/Lang/da.lang.php new file mode 100755 index 0000000..f0ecc5e --- /dev/null +++ b/Theme/Backend/Lang/da.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Regnskab', + 'Addition' => 'Tilsætning', + 'Address' => 'Adresse', + 'Addresses' => 'Adresser', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Områdechef', + 'Articlegroup' => 'ArticleGroup.', + 'Articles' => 'Artikler', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Balance', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus', + 'Business' => 'Forretning', + 'CIS' => '#VALUE!', + 'CLV' => 'CLV.', + 'Calendar' => 'Kalender', + 'City' => 'City.', + 'Client' => 'Klient', + 'ClientID' => '#VALUE!', + 'Clients' => 'Klienter.', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Kontakt', + 'Country' => 'Land', + 'Created' => 'Oprettet', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Kreditvurdering', + 'Creditcard' => 'Kreditkort', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO.', + 'Date' => 'Dato', + 'Default' => 'Standard', + 'Delivery' => 'Levering', + 'Discount' => 'Rabat', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Rabat%', + 'Documents' => 'Dokumenter', + 'Due' => 'På grund', + 'Email' => 'Email.', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'Filer.', + 'Filter' => 'Filter', + 'Freightage' => 'Gods', + 'Group' => 'Gruppe', + 'ID' => 'ID.', + 'Info' => 'Info.', + 'Invoice' => 'Faktura', + 'Invoices' => 'Fakturaer.', + 'IsDefault' => 'Er standard?', + 'Items' => '#VALUE!', + 'LastContact' => 'Sidste kontakt', + 'LastOrder' => 'Sidste ordre', + 'Log' => 'Log', + 'Logs' => 'Logs.', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR.', + 'MTDSales' => 'MTD Sales.', + 'Margin' => 'Margin.', + 'Messages' => 'Beskeder', + 'Modified' => 'Modificeret', + 'Modules' => 'Moduler.', + 'Name' => 'Navn', + 'Name1' => 'NAME1.', + 'Name2' => 'NAME2.', + 'Name3' => 'NAME3.', + 'Net' => 'Net', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Noter.', + 'Number' => 'Nummer', + 'Office' => 'Kontor', + 'Other' => '#VALUE!', + 'Payment' => 'Betaling', + 'PaymentTerm' => 'Betalingsbetingelser', + 'Permission' => 'Tilladelse', + 'Phone' => 'telefon', + 'Postal' => 'Postal.', + 'Price' => 'Pris', + 'Prices' => 'Priser.', + 'Private' => 'Privat', + 'Productgroup' => 'Produktgruppe', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Køb', + 'Quantity' => 'Antal', + 'RecentInvoices' => 'Nylige fakturaer.', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'SALG', + 'Segment' => 'Segment', + 'Segments' => 'Segmenter.', + 'Subtype' => 'Subtype.', + 'Support' => 'Support', + 'Tags' => 'Tags.', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Type', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Internet side', + 'Wire' => 'Tråd', + 'YTDSales' => 'YTD SALG', + 'Zip' => 'Zip.', +]]; diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php new file mode 100755 index 0000000..40b81f6 --- /dev/null +++ b/Theme/Backend/Lang/de.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Buchhaltung', + 'Addition' => 'Zusatz', + 'Address' => 'Adresse', + 'Addresses' => 'Adressen', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Bereichsleiter', + 'Articlegroup' => 'ArtikelGroup.', + 'Articles' => 'Artikel', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Gleichgewicht', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus', + 'Business' => 'Geschäft', + 'CIS' => '#VALUE!', + 'CLV' => 'CLV', + 'Calendar' => 'Kalender', + 'City' => 'Stadt', + 'Client' => 'Klient', + 'ClientID' => '#VALUE!', + 'Clients' => 'Kunden', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Kontakt', + 'Country' => 'Land', + 'Created' => 'Erstellt', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Kreditbeurteilung', + 'Creditcard' => 'Kreditkarte', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO.', + 'Date' => 'Datum', + 'Default' => 'Standard', + 'Delivery' => 'Die Zustellung', + 'Discount' => 'Rabatt', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Rabatt %', + 'Documents' => 'Unterlagen', + 'Due' => 'Fällig', + 'Email' => 'Email', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'Dateien', + 'Filter' => 'Filter', + 'Freightage' => 'Fracht', + 'Group' => 'Gruppe', + 'ID' => 'ICH WÜRDE', + 'Info' => 'Die Info', + 'Invoice' => 'Rechnung', + 'Invoices' => 'Rechnungen', + 'IsDefault' => 'Ist standardmäßig?', + 'Items' => '#VALUE!', + 'LastContact' => 'Letzter Kontakt', + 'LastOrder' => 'Letzte Bestellung', + 'Log' => 'Protokoll', + 'Logs' => 'Protokoll', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr.', + 'MTDSales' => 'MTD-Verkäufe.', + 'Margin' => 'Rand', + 'Messages' => 'Mitteilungen', + 'Modified' => 'Geändert', + 'Modules' => 'Module', + 'Name' => 'Name', + 'Name1' => 'Name1.', + 'Name2' => 'Name2.', + 'Name3' => 'Name3.', + 'Net' => 'Netz', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Anmerkungen', + 'Number' => 'Nummer', + 'Office' => 'Sekretariat', + 'Other' => '#VALUE!', + 'Payment' => 'Zahlung', + 'PaymentTerm' => 'Zahlungsbezeichnung', + 'Permission' => 'Erlaubnis', + 'Phone' => 'Telefon', + 'Postal' => 'Post', + 'Price' => 'Preis', + 'Prices' => 'Preise', + 'Private' => 'Privatgelände', + 'Productgroup' => 'Produktgruppe', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Kaufen', + 'Quantity' => 'Menge', + 'RecentInvoices' => 'Jüngste Rechnungen', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Der Umsatz', + 'Segment' => 'Segment', + 'Segments' => 'Segmente', + 'Subtype' => 'Untertyp', + 'Support' => 'Unterstützung', + 'Tags' => 'Stichworte', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Typ', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Webseite', + 'Wire' => 'Kabel', + 'YTDSales' => 'Ytd Sales.', + 'Zip' => 'Reißverschluss', +]]; diff --git a/Theme/Backend/Lang/el.lang.php b/Theme/Backend/Lang/el.lang.php new file mode 100755 index 0000000..b6ad900 --- /dev/null +++ b/Theme/Backend/Lang/el.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Λογιστική', + 'Addition' => 'Πρόσθεση', + 'Address' => 'Διεύθυνση', + 'Addresses' => 'Διευθύνσεις', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Διευθυντής περιοχής', + 'Articlegroup' => 'Ομιλία', + 'Articles' => 'Είδη', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Ισορροπία', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Δώρο', + 'Business' => 'Επιχείρηση', + 'CIS' => '#VALUE!', + 'CLV' => 'Σολλίζω', + 'Calendar' => 'Ημερολόγιο', + 'City' => 'Πόλη', + 'Client' => 'Πελάτης', + 'ClientID' => '#VALUE!', + 'Clients' => 'Πελάτες', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Επικοινωνία', + 'Country' => 'Χώρα', + 'Created' => 'Δημιουργήθηκε', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Αξιολόγησης της πιστοληπτικής ικανότητας', + 'Creditcard' => 'Πιστωτική κάρτα', + 'Customers' => '#VALUE!', + 'DSO' => 'ΔΣΟ', + 'Date' => 'Ημερομηνία', + 'Default' => 'Προκαθορισμένο', + 'Delivery' => 'Διανομή', + 'Discount' => 'Εκπτωση', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Έκπτωση%', + 'Documents' => 'Εγγραφα', + 'Due' => 'Λόγω', + 'Email' => 'ΗΛΕΚΤΡΟΝΙΚΗ ΔΙΕΥΘΥΝΣΗ', + 'Europe' => '#VALUE!', + 'Fax' => 'Φαξ', + 'Files' => 'Αρχεία', + 'Filter' => 'Φίλτρο', + 'Freightage' => 'Ναύλος', + 'Group' => 'Ομάδα', + 'ID' => 'ταυτότητα', + 'Info' => 'Πληροφορία', + 'Invoice' => 'Τιμολόγιο', + 'Invoices' => 'Τιμολόγια', + 'IsDefault' => 'Είναι προεπιλογή;', + 'Items' => '#VALUE!', + 'LastContact' => 'Τελευταία επαφή', + 'LastOrder' => 'Τελευταία παραγγελία', + 'Log' => 'Κούτσουρο', + 'Logs' => 'Κούτσουρα', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR', + 'MTDSales' => 'Πωλήσεις MTD', + 'Margin' => 'Περιθώριο', + 'Messages' => 'Μηνύματα', + 'Modified' => 'Τροποποιημένος', + 'Modules' => 'Ενότητες', + 'Name' => 'Ονομα', + 'Name1' => 'Όνομα1', + 'Name2' => 'Όνομα2', + 'Name3' => 'Όνομα', + 'Net' => 'Καθαρά', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Σημειώνει', + 'Number' => 'Αριθμός', + 'Office' => 'Γραφείο', + 'Other' => '#VALUE!', + 'Payment' => 'Πληρωμή', + 'PaymentTerm' => 'Ορος πληρωμής', + 'Permission' => 'Αδεια', + 'Phone' => 'Τηλέφωνο', + 'Postal' => 'Ταχυδρομικός', + 'Price' => 'Τιμή', + 'Prices' => 'Τιμές', + 'Private' => 'Ιδιωτικός', + 'Productgroup' => 'Ομοιόμορφη ομάδα', + 'Profile' => 'Προφίλ', + 'Profit' => '#VALUE!', + 'Purchase' => 'Αγορά', + 'Quantity' => 'Ποσότητα', + 'RecentInvoices' => 'Πρόσφατα τιμολόγια', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Εκπτώσεις', + 'Segment' => 'Τμήμα', + 'Segments' => 'Τμήματα', + 'Subtype' => 'Υποτύπωμα', + 'Support' => 'Υποστήριξη', + 'Tags' => 'Ετικέτες', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Τύπος', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Δικτυακός τόπος', + 'Wire' => 'Σύρμα', + 'YTDSales' => 'Ytd πωλήσεις', + 'Zip' => 'Φερμουάρ', +]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php new file mode 100755 index 0000000..f77cd26 --- /dev/null +++ b/Theme/Backend/Lang/en.lang.php @@ -0,0 +1,127 @@ + [ + 'Accounting' => 'Accounting', + 'Addition' => 'Addition', + 'Address' => 'Address', + 'Addresses' => 'Addresses', + 'Africa' => 'Africa', + 'AllCustomers' => 'All Customers', + 'America' => 'America', + 'Analyse' => 'Analyse', + 'AreaManager' => 'Area Manager', + 'Articlegroup' => 'Articlegroup', + 'Articles' => 'Articles', + 'Asia' => 'Asia', + 'Attribute' => 'Attribute', + 'Attributes' => 'Attributes', + 'Balance' => 'Balance', + 'BaseTime' => 'Base time', + 'Bills' => 'Bills', + 'Bonus' => 'Bonus', + 'Business' => 'Business', + 'CIS' => 'CIS', + 'CLV' => 'CLV', + 'Calendar' => 'Calendar', + 'City' => 'City', + 'Client' => 'Client', + 'ClientID' => 'Client Id', + 'Clients' => 'Clients', + 'ComparisonTime' => 'Comparison time', + 'Contact' => 'Contact', + 'Country' => 'Country', + 'Created' => 'Created', + 'CreatedAt' => 'Created at', + 'CreditRating' => 'Credit Rating', + 'Creditcard' => 'Creditcard', + 'Customers' => 'Customers', + 'DSO' => 'DSO', + 'Date' => 'Date', + 'Default' => 'Default', + 'Delivery' => 'Delivery', + 'Discount' => 'Discount', + 'DiscountBonus' => 'Discount bonus', + 'DiscountP' => 'Discount %', + 'Documents' => 'Documents', + 'Due' => 'Due', + 'Email' => 'Email', + 'Europe' => 'Europe', + 'Fax' => 'Fax', + 'Files' => 'Files', + 'Filter' => 'Filter', + 'Freightage' => 'Freightage', + 'Group' => 'Group', + 'ID' => 'ID', + 'Info' => 'Info', + 'Invoice' => 'Invoice', + 'Invoices' => 'Invoices', + 'IsDefault' => 'Is default?', + 'Items' => 'Items', + 'LastContact' => 'Last Contact', + 'LastOrder' => 'Last Order', + 'Log' => 'Log', + 'Logs' => 'Logs', + 'LostCustomers' => 'Lost customers', + 'MRR' => 'MRR', + 'MTDSales' => 'MTD Sales', + 'Margin' => 'Margin', + 'Messages' => 'Messages', + 'Modified' => 'Modified', + 'Modules' => 'Modules', + 'Name' => 'Name', + 'Name1' => 'Name1', + 'Name2' => 'Name2', + 'Name3' => 'Name3', + 'Net' => 'Net', + 'NewCustomers' => 'New customers', + 'Notes' => 'Notes', + 'Number' => 'Number', + 'Office' => 'Office', + 'Other' => 'Other', + 'Payment' => 'Payment', + 'PaymentTerm' => 'Payment Term', + 'Permission' => 'Permission', + 'Phone' => 'Phone', + 'Postal' => 'Postal', + 'Price' => 'Price', + 'Prices' => 'Prices', + 'Private' => 'Private', + 'Productgroup' => 'Productgroup', + 'Profile' => 'Profile', + 'Profit' => 'Profit', + 'Purchase' => 'Purchase', + 'Quantity' => 'Quantity', + 'RecentInvoices' => 'Recent Invoices', + 'Region' => 'Region', + 'Rep' => 'Rep', + 'Retention' => 'Retention', + 'Sales' => 'Sales', + 'Segment' => 'Segment', + 'Segments' => 'Segments', + 'Subtype' => 'Subtype', + 'Support' => 'Support', + 'Tags' => 'Tags', + 'Title' => 'Title', + 'Total' => 'Total', + 'TotalPrice' => 'Total price', + 'Type' => 'Type', + 'UnitPrice' => 'Unit price', + 'Value' => 'Value', + 'Website' => 'Website', + 'Wire' => 'Wire', + 'YTDSales' => 'YTD Sales', + 'Zip' => 'Zip', + 'IMG_alt_map' => 'Map', +]]; diff --git a/Theme/Backend/Lang/es.lang.php b/Theme/Backend/Lang/es.lang.php new file mode 100755 index 0000000..07f9a57 --- /dev/null +++ b/Theme/Backend/Lang/es.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Contabilidad', + 'Addition' => 'Adición', + 'Address' => 'Habla a', + 'Addresses' => 'Direcciones', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Gerente de área', + 'Articlegroup' => 'Grupo articulo', + 'Articles' => 'Artículos', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Equilibrio', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Prima', + 'Business' => 'Negocio', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv', + 'Calendar' => 'Calendario', + 'City' => 'Ciudad', + 'Client' => 'Cliente', + 'ClientID' => '#VALUE!', + 'Clients' => 'Clientela', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Contacto', + 'Country' => 'País', + 'Created' => 'Creado', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Calificación crediticia', + 'Creditcard' => 'Tarjeta de crédito', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO', + 'Date' => 'Fecha', + 'Default' => 'Defecto', + 'Delivery' => 'Entrega', + 'Discount' => 'Descuento', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Descuento%', + 'Documents' => 'Documentos', + 'Due' => 'Vencer', + 'Email' => 'Correo electrónico', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'Archivos', + 'Filter' => 'Filtrar', + 'Freightage' => 'Flete', + 'Group' => 'Grupo', + 'ID' => 'IDENTIFICACIÓN', + 'Info' => 'Información', + 'Invoice' => 'Factura', + 'Invoices' => 'Facturas', + 'IsDefault' => 'Es por defecto?', + 'Items' => '#VALUE!', + 'LastContact' => 'Último contacto', + 'LastOrder' => 'Último pedido', + 'Log' => 'Tronco', + 'Logs' => 'Registros', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr', + 'MTDSales' => 'Ventas MTD', + 'Margin' => 'Margen', + 'Messages' => 'Mensajes', + 'Modified' => 'Modificado', + 'Modules' => 'Módulos', + 'Name' => 'Nombre', + 'Name1' => 'Nombre1', + 'Name2' => 'Nombre2', + 'Name3' => 'Nombre3', + 'Net' => 'Red', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Notas', + 'Number' => 'Número', + 'Office' => 'Oficina', + 'Other' => '#VALUE!', + 'Payment' => 'Pago', + 'PaymentTerm' => 'Plazo de pago', + 'Permission' => 'Permiso', + 'Phone' => 'Teléfono', + 'Postal' => 'Postal', + 'Price' => 'Precio', + 'Prices' => 'Precios', + 'Private' => 'Privado', + 'Productgroup' => 'Grupo de productos', + 'Profile' => 'Perfil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Compra', + 'Quantity' => 'Cantidad', + 'RecentInvoices' => 'Facturas recientes', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Ventas', + 'Segment' => 'Segmento', + 'Segments' => 'Segmentos', + 'Subtype' => 'Subtipo', + 'Support' => 'Apoyo', + 'Tags' => 'Etiquetas', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Escribe', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Sitio web', + 'Wire' => 'Cable', + 'YTDSales' => 'Ytd ventas', + 'Zip' => 'Cremallera', +]]; diff --git a/Theme/Backend/Lang/fi.lang.php b/Theme/Backend/Lang/fi.lang.php new file mode 100755 index 0000000..e39fe21 --- /dev/null +++ b/Theme/Backend/Lang/fi.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Kirjanpito', + 'Addition' => 'Lisäys', + 'Address' => 'Osoite', + 'Addresses' => 'Osoitteet', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Aluejohtaja', + 'Articlegroup' => 'ArticleGroup', + 'Articles' => 'Artikkelit', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Saldo', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus', + 'Business' => 'Liiketoiminta', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv', + 'Calendar' => 'Kalenteri', + 'City' => 'Kaupunki', + 'Client' => 'Asiakas', + 'ClientID' => '#VALUE!', + 'Clients' => 'Asiakkaat', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Ottaa yhteyttä', + 'Country' => 'Maa', + 'Created' => 'Luotu', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Luottoluokitus', + 'Creditcard' => 'Luottokortti', + 'Customers' => '#VALUE!', + 'DSO' => 'Dso', + 'Date' => 'Päivämäärä', + 'Default' => 'Oletusarvo', + 'Delivery' => 'Toimitus', + 'Discount' => 'Alennus', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Alennus %', + 'Documents' => 'Asiakirjat', + 'Due' => 'Takia', + 'Email' => 'Sähköposti', + 'Europe' => '#VALUE!', + 'Fax' => 'Faksi', + 'Files' => 'Tiedostot', + 'Filter' => 'Suodattaa', + 'Freightage' => 'Rahti', + 'Group' => 'Ryhmä', + 'ID' => 'Id', + 'Info' => 'Tiedot', + 'Invoice' => 'Lasku', + 'Invoices' => 'Laskut', + 'IsDefault' => 'On oletusarvo?', + 'Items' => '#VALUE!', + 'LastContact' => 'Viimeinen yhteystieto', + 'LastOrder' => 'Viimeinen tilaus', + 'Log' => 'Hirsi', + 'Logs' => 'Lokit', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr', + 'MTDSales' => 'MTD-myynti', + 'Margin' => 'Marginaali', + 'Messages' => 'Viestit', + 'Modified' => 'Muokattu', + 'Modules' => 'Moduulit', + 'Name' => 'Nimi', + 'Name1' => 'Nimi1', + 'Name2' => 'Nimi2', + 'Name3' => 'Nimi33', + 'Net' => 'Netto', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Toteaa', + 'Number' => 'Määrä', + 'Office' => 'Toimisto', + 'Other' => '#VALUE!', + 'Payment' => 'Maksu', + 'PaymentTerm' => 'Maksuehto', + 'Permission' => 'Lupa', + 'Phone' => 'Puhelin', + 'Postal' => 'Posti-', + 'Price' => 'Hinta', + 'Prices' => 'Hinnat', + 'Private' => 'Yksityinen', + 'Productgroup' => 'Tuoteryhmä', + 'Profile' => 'Profiili', + 'Profit' => '#VALUE!', + 'Purchase' => 'Ostaa', + 'Quantity' => 'Määrä', + 'RecentInvoices' => 'Viimeaikaiset laskut', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Myynti', + 'Segment' => 'Segmentti', + 'Segments' => 'Segmentit', + 'Subtype' => 'Alatyyppi', + 'Support' => 'Tuki', + 'Tags' => 'Tunnisteet', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Tyyppi', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Verkkosivusto', + 'Wire' => 'Lanka', + 'YTDSales' => 'YTD-myynti', + 'Zip' => 'Postinumero', +]]; diff --git a/Theme/Backend/Lang/fr.lang.php b/Theme/Backend/Lang/fr.lang.php new file mode 100755 index 0000000..a254ee8 --- /dev/null +++ b/Theme/Backend/Lang/fr.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Comptabilité', + 'Addition' => 'Une addition', + 'Address' => 'Adresse', + 'Addresses' => 'Adresses', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Chef de secteur', + 'Articlegroup' => 'Articlegroup', + 'Articles' => 'Des articles', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Équilibre', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Prime', + 'Business' => 'Entreprise', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv', + 'Calendar' => 'Calendrier', + 'City' => 'Ville', + 'Client' => 'Client', + 'ClientID' => '#VALUE!', + 'Clients' => 'Clients', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Contact', + 'Country' => 'Pays', + 'Created' => 'Établi', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Cote de crédit', + 'Creditcard' => 'Carte de crédit', + 'Customers' => '#VALUE!', + 'DSO' => 'Dso', + 'Date' => 'Date', + 'Default' => 'Défaut', + 'Delivery' => 'Livraison', + 'Discount' => 'Remise', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Remise %', + 'Documents' => 'Documents', + 'Due' => 'Dû', + 'Email' => 'E-mail', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'Des dossiers', + 'Filter' => 'Filtre', + 'Freightage' => 'Fret', + 'Group' => 'Grouper', + 'ID' => 'identifiant', + 'Info' => 'Info', + 'Invoice' => 'Facture d\'achat', + 'Invoices' => 'Factures', + 'IsDefault' => 'Est par défaut?', + 'Items' => '#VALUE!', + 'LastContact' => 'Dernier contact', + 'LastOrder' => 'Dernière commande', + 'Log' => 'Enregistrer', + 'Logs' => 'Journaux', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr', + 'MTDSales' => 'Ventes MTD', + 'Margin' => 'Marge', + 'Messages' => 'messages', + 'Modified' => 'Modifié', + 'Modules' => 'Modules', + 'Name' => 'Nom', + 'Name1' => 'Nom1', + 'Name2' => 'Nom2', + 'Name3' => 'Nom3', + 'Net' => 'Rapporter', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Remarques', + 'Number' => 'Nombre', + 'Office' => 'Bureau', + 'Other' => '#VALUE!', + 'Payment' => 'Paiement', + 'PaymentTerm' => 'Terme de paiement', + 'Permission' => 'Autorisation', + 'Phone' => 'Téléphoner', + 'Postal' => 'Postal', + 'Price' => 'Prix', + 'Prices' => 'Des prix', + 'Private' => 'Privé', + 'Productgroup' => 'Groupe de produits', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Acheter', + 'Quantity' => 'Quantité', + 'RecentInvoices' => 'Factures récentes', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Ventes', + 'Segment' => 'Segment', + 'Segments' => 'Segments', + 'Subtype' => 'Sous-type', + 'Support' => 'Soutien', + 'Tags' => 'Mots clés', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Taper', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Site Internet', + 'Wire' => 'Fil', + 'YTDSales' => 'Ventes YTD', + 'Zip' => 'Zipper', +]]; diff --git a/Theme/Backend/Lang/hu.lang.php b/Theme/Backend/Lang/hu.lang.php new file mode 100755 index 0000000..b170796 --- /dev/null +++ b/Theme/Backend/Lang/hu.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Könyvelés', + 'Addition' => 'Kiegészítés', + 'Address' => 'Cím', + 'Addresses' => 'Címek', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Területi menedzser', + 'Articlegroup' => 'Gyerekcsoport', + 'Articles' => 'Árucikkek', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Egyensúly', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bónusz', + 'Business' => 'Üzleti', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv', + 'Calendar' => 'Naptár', + 'City' => 'Város', + 'Client' => 'Ügyfél', + 'ClientID' => '#VALUE!', + 'Clients' => 'Kliensek', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Kapcsolatba lépni', + 'Country' => 'Ország', + 'Created' => 'Létrehozott', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Hitelminősítő', + 'Creditcard' => 'Hitelkártya', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO', + 'Date' => 'Dátum', + 'Default' => 'Alapértelmezett', + 'Delivery' => 'Szállítás', + 'Discount' => 'Kedvezmény', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Árengedmény%', + 'Documents' => 'Dokumentumok', + 'Due' => 'Esedékes', + 'Email' => 'Email', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'Fájlok', + 'Filter' => 'Szűrő', + 'Freightage' => 'Fuvardíj', + 'Group' => 'Csoport', + 'ID' => 'Idézés', + 'Info' => 'Információ', + 'Invoice' => 'Számla', + 'Invoices' => 'Számlák', + 'IsDefault' => 'Alapértelmezett?', + 'Items' => '#VALUE!', + 'LastContact' => 'Utolsó kapcsolat', + 'LastOrder' => 'Utolsó rendelés', + 'Log' => 'Napló', + 'Logs' => 'Naplók', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr', + 'MTDSales' => 'MTD értékesítés', + 'Margin' => 'Árrés', + 'Messages' => 'üzenetek', + 'Modified' => 'Módosított', + 'Modules' => 'Modulok', + 'Name' => 'Név', + 'Name1' => 'Név1', + 'Name2' => 'NAME2', + 'Name3' => 'Név3', + 'Net' => 'Háló', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Jegyzetek', + 'Number' => 'Szám', + 'Office' => 'Hivatal', + 'Other' => '#VALUE!', + 'Payment' => 'Fizetés', + 'PaymentTerm' => 'Fizetési határidő', + 'Permission' => 'Engedély', + 'Phone' => 'Telefon', + 'Postal' => 'Postai', + 'Price' => 'Ár', + 'Prices' => 'Árak', + 'Private' => 'Magán', + 'Productgroup' => 'Termékcsoport', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Vásárlás', + 'Quantity' => 'Mennyiség', + 'RecentInvoices' => 'Legutóbbi számlák', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Értékesítés', + 'Segment' => 'Szegmens', + 'Segments' => 'Szegmensek', + 'Subtype' => 'Altípus', + 'Support' => 'Támogatás', + 'Tags' => 'Címkék', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'típus', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Weboldal', + 'Wire' => 'Huzal', + 'YTDSales' => 'YTD értékesítés', + 'Zip' => 'Postai irányítószám', +]]; diff --git a/Theme/Backend/Lang/it.lang.php b/Theme/Backend/Lang/it.lang.php new file mode 100755 index 0000000..0af5b07 --- /dev/null +++ b/Theme/Backend/Lang/it.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Contabilità', + 'Addition' => 'Aggiunta', + 'Address' => 'Indirizzo', + 'Addresses' => 'Indirizzi', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Area Manager', + 'Articlegroup' => 'Art.group.', + 'Articles' => 'Artificio', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Bilancia', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus.', + 'Business' => 'Affare', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv.', + 'Calendar' => 'Calendario', + 'City' => 'Città', + 'Client' => 'Cliente', + 'ClientID' => '#VALUE!', + 'Clients' => 'Clienti', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Contatto', + 'Country' => 'Nazione', + 'Created' => 'Creato', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Rating del credito', + 'Creditcard' => 'Carta di credito', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO.', + 'Date' => 'Data', + 'Default' => 'Predefinito', + 'Delivery' => 'Consegna', + 'Discount' => 'Sconto', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Sconto%', + 'Documents' => 'Documenti', + 'Due' => 'Dovuto', + 'Email' => 'E-mail', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'File', + 'Filter' => 'Filtro', + 'Freightage' => 'Liberare', + 'Group' => 'Gruppo', + 'ID' => 'ID', + 'Info' => 'Informazioni', + 'Invoice' => 'Fattura', + 'Invoices' => 'Fatture', + 'IsDefault' => 'È predefinito?', + 'Items' => '#VALUE!', + 'LastContact' => 'Ultimo contatto', + 'LastOrder' => 'Ultimo ordine', + 'Log' => 'Tronco d\'albero', + 'Logs' => 'Logs.', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr.', + 'MTDSales' => 'Vendite di mtd.', + 'Margin' => 'Margine', + 'Messages' => 'Messaggi', + 'Modified' => 'Modificati', + 'Modules' => 'Moduli', + 'Name' => 'Nome', + 'Name1' => 'Nome1.', + 'Name2' => 'Nome2.', + 'Name3' => 'Nome3.', + 'Net' => 'Rete', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Appunti', + 'Number' => 'Numero', + 'Office' => 'Ufficio', + 'Other' => '#VALUE!', + 'Payment' => 'Pagamento', + 'PaymentTerm' => 'Termine di pagamento', + 'Permission' => 'Autorizzazione', + 'Phone' => 'Telefono', + 'Postal' => 'postale', + 'Price' => 'Prezzo', + 'Prices' => 'Prezzi', + 'Private' => 'Privato', + 'Productgroup' => 'Gruppo di prodotti', + 'Profile' => 'Profilo', + 'Profit' => '#VALUE!', + 'Purchase' => 'Acquistare', + 'Quantity' => 'Quantità', + 'RecentInvoices' => 'Recenti fatture', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Saldi', + 'Segment' => 'Segmento', + 'Segments' => 'Segmenti', + 'Subtype' => 'Sottotipo', + 'Support' => 'Supporto', + 'Tags' => 'Tags.', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Tipo', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Sito web', + 'Wire' => 'Filo', + 'YTDSales' => 'Vendite di ytd.', + 'Zip' => 'Cerniera lampo', +]]; diff --git a/Theme/Backend/Lang/ja.lang.php b/Theme/Backend/Lang/ja.lang.php new file mode 100755 index 0000000..c4775f3 --- /dev/null +++ b/Theme/Backend/Lang/ja.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => '会計', + 'Addition' => '添加', + 'Address' => '住所', + 'Addresses' => 'アドレス', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'エリアマネージャー', + 'Articlegroup' => '記事グループ', + 'Articles' => 'articles', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'バランス', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'ボーナス', + 'Business' => '仕事', + 'CIS' => '#VALUE!', + 'CLV' => 'cl cl', + 'Calendar' => 'カレンダー', + 'City' => '市', + 'Client' => 'クライアント', + 'ClientID' => '#VALUE!', + 'Clients' => 'クライアント', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'コンタクト', + 'Country' => '国', + 'Created' => '作成した', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => '信用格付け', + 'Creditcard' => 'クレジットカード', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO', + 'Date' => '日にち', + 'Default' => 'ディフォルト', + 'Delivery' => '配達', + 'Discount' => '割引', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => '割引 %', + 'Documents' => '文書', + 'Due' => '期限', + 'Email' => 'Eメール', + 'Europe' => '#VALUE!', + 'Fax' => 'ファックス', + 'Files' => 'ファイル', + 'Filter' => 'フィルター', + 'Freightage' => 'fre fre', + 'Group' => 'グループ', + 'ID' => 'id', + 'Info' => '情報', + 'Invoice' => '請求書', + 'Invoices' => '請求書', + 'IsDefault' => 'デフォルトですか?', + 'Items' => '#VALUE!', + 'LastContact' => '最後の連絡先', + 'LastOrder' => '最後の順序', + 'Log' => 'ログ', + 'Logs' => 'ログ', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR.', + 'MTDSales' => 'MTDセールス', + 'Margin' => 'マージン', + 'Messages' => 'メッセージ', + 'Modified' => '修正された', + 'Modules' => 'モジュール', + 'Name' => '名前', + 'Name1' => '名前1', + 'Name2' => '名前2', + 'Name3' => '名前3', + 'Net' => 'ネット', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'ノート', + 'Number' => '番号', + 'Office' => 'オフィス', + 'Other' => '#VALUE!', + 'Payment' => '支払い', + 'PaymentTerm' => '支払条件', + 'Permission' => '許可', + 'Phone' => '電話', + 'Postal' => '郵便', + 'Price' => '価格', + 'Prices' => '価格', + 'Private' => '民間', + 'Productgroup' => '製品グループ', + 'Profile' => 'プロフィール', + 'Profit' => '#VALUE!', + 'Purchase' => '購入', + 'Quantity' => '量', + 'RecentInvoices' => '最近の請求書', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => '売り返り', + 'Segment' => 'セグメント', + 'Segments' => 'セグメント', + 'Subtype' => 'サブタイプ', + 'Support' => 'サポート', + 'Tags' => 'タグ', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'タイプ', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Webサイト', + 'Wire' => 'ワイヤー', + 'YTDSales' => 'ytd売上高', + 'Zip' => 'ジップ', +]]; diff --git a/Theme/Backend/Lang/ko.lang.php b/Theme/Backend/Lang/ko.lang.php new file mode 100755 index 0000000..91e7f57 --- /dev/null +++ b/Theme/Backend/Lang/ko.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => '회계', + 'Addition' => '덧셈', + 'Address' => '주소', + 'Addresses' => '구애', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => '구역 책임자', + 'Articlegroup' => '기사 그룹', + 'Articles' => '조항', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => '균형', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => '보너스', + 'Business' => '사업', + 'CIS' => '#VALUE!', + 'CLV' => 'CLV.', + 'Calendar' => '달력', + 'City' => '도시', + 'Client' => '고객', + 'ClientID' => '#VALUE!', + 'Clients' => '클라이언트', + 'ComparisonTime' => '#VALUE!', + 'Contact' => '연락하다', + 'Country' => '국가', + 'Created' => '만들어진', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => '신용 등급', + 'Creditcard' => '신용 카드', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO.', + 'Date' => '날짜', + 'Default' => '기본', + 'Delivery' => '배달', + 'Discount' => '할인', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => '할인 %', + 'Documents' => '서류', + 'Due' => '로 인한', + 'Email' => '이메일', + 'Europe' => '#VALUE!', + 'Fax' => '팩스', + 'Files' => '파일', + 'Filter' => '필터', + 'Freightage' => '화물', + 'Group' => '그룹', + 'ID' => 'ID', + 'Info' => '정보', + 'Invoice' => '송장', + 'Invoices' => '송장', + 'IsDefault' => '기본값은 무엇입니까?', + 'Items' => '#VALUE!', + 'LastContact' => '마지막 연락처', + 'LastOrder' => '마지막 주문', + 'Log' => '통나무', + 'Logs' => '로그인', + 'LostCustomers' => '#VALUE!', + 'MRR' => '부서', + 'MTDSales' => 'MTD 판매', + 'Margin' => '여유', + 'Messages' => '메시지', + 'Modified' => '수정', + 'Modules' => '모듈', + 'Name' => '이름', + 'Name1' => 'name1.', + 'Name2' => 'name2.', + 'Name3' => 'Name3.', + 'Net' => '그물', + 'NewCustomers' => '#VALUE!', + 'Notes' => '노트', + 'Number' => '숫자', + 'Office' => '사무실', + 'Other' => '#VALUE!', + 'Payment' => '지불', + 'PaymentTerm' => '지불 기간', + 'Permission' => '허가', + 'Phone' => '핸드폰', + 'Postal' => '우편 엽서', + 'Price' => '가격', + 'Prices' => '물가', + 'Private' => '사적인', + 'Productgroup' => '제품 그룹', + 'Profile' => '프로필', + 'Profit' => '#VALUE!', + 'Purchase' => '구입', + 'Quantity' => '수량', + 'RecentInvoices' => '최근 송장', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => '매상', + 'Segment' => '분절', + 'Segments' => '세그먼트', + 'Subtype' => '하위 유형', + 'Support' => '지원하다', + 'Tags' => '태그', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => '유형', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => '웹 사이트', + 'Wire' => '철사', + 'YTDSales' => 'YTD 판매', + 'Zip' => '지퍼', +]]; diff --git a/Theme/Backend/Lang/no.lang.php b/Theme/Backend/Lang/no.lang.php new file mode 100755 index 0000000..b007f56 --- /dev/null +++ b/Theme/Backend/Lang/no.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Regnskap', + 'Addition' => 'Addisjon', + 'Address' => 'Adresse', + 'Addresses' => 'Adresser', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Områdeansvarlig', + 'Articlegroup' => 'Articregroup.', + 'Articles' => 'Artikler', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Balansere', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus', + 'Business' => 'Virksomhet', + 'CIS' => '#VALUE!', + 'CLV' => 'CLV.', + 'Calendar' => 'Kalender', + 'City' => 'By', + 'Client' => 'Klient', + 'ClientID' => '#VALUE!', + 'Clients' => 'Klienter', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Kontakt', + 'Country' => 'Land', + 'Created' => 'Opprettet', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Kredittvurdering', + 'Creditcard' => 'Kredittkort', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO', + 'Date' => 'Dato', + 'Default' => 'Misligholde', + 'Delivery' => 'Leveranse', + 'Discount' => 'Rabatt', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Rabatt%', + 'Documents' => 'Dokumenter', + 'Due' => 'På grunn av det', + 'Email' => 'E-post', + 'Europe' => '#VALUE!', + 'Fax' => 'Faks', + 'Files' => 'Filer', + 'Filter' => 'Filter', + 'Freightage' => 'Frakt', + 'Group' => 'Gruppe', + 'ID' => 'Id.', + 'Info' => 'Info.', + 'Invoice' => 'Faktura', + 'Invoices' => 'Fakturaer', + 'IsDefault' => 'Er standard?', + 'Items' => '#VALUE!', + 'LastContact' => 'Siste kontakt', + 'LastOrder' => 'Siste bestilling', + 'Log' => 'Logg', + 'Logs' => 'Tømmerstokker', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR.', + 'MTDSales' => 'MTD-salg', + 'Margin' => 'Margin', + 'Messages' => 'Meldinger', + 'Modified' => 'Endret', + 'Modules' => 'Moduler', + 'Name' => 'Navn', + 'Name1' => 'Navn1.', + 'Name2' => 'NAME2.', + 'Name3' => 'Navn3.', + 'Net' => 'Nett', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Notater', + 'Number' => 'Nummer', + 'Office' => 'Kontor', + 'Other' => '#VALUE!', + 'Payment' => 'innbetaling', + 'PaymentTerm' => 'Betalingsperiode', + 'Permission' => 'Tillatelse', + 'Phone' => 'Telefonen', + 'Postal' => 'Postal.', + 'Price' => 'Pris', + 'Prices' => 'Prisene', + 'Private' => 'Privat', + 'Productgroup' => 'Produktgruppe', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Kjøp', + 'Quantity' => 'Mengde', + 'RecentInvoices' => 'Nylige fakturaer', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Salg', + 'Segment' => 'Segmentet', + 'Segments' => 'Segmenter', + 'Subtype' => 'Subtype.', + 'Support' => 'Brukerstøtte', + 'Tags' => 'Tags.', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Type', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Nettside', + 'Wire' => 'Metalltråd', + 'YTDSales' => 'YTD-salg', + 'Zip' => 'Glidelås', +]]; diff --git a/Theme/Backend/Lang/pl.lang.php b/Theme/Backend/Lang/pl.lang.php new file mode 100755 index 0000000..9baf170 --- /dev/null +++ b/Theme/Backend/Lang/pl.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Rachunkowość', + 'Addition' => 'Dodatek', + 'Address' => 'Adres', + 'Addresses' => 'Adresy', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Dyrektor Regionalny', + 'Articlegroup' => 'Artykuł', + 'Articles' => 'Artykuły', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Balansować', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Premia', + 'Business' => 'Biznes', + 'CIS' => '#VALUE!', + 'CLV' => 'CLV.', + 'Calendar' => 'Kalendarz', + 'City' => 'Miasto', + 'Client' => 'Klient', + 'ClientID' => '#VALUE!', + 'Clients' => 'Klienci.', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Kontakt', + 'Country' => 'Kraj', + 'Created' => 'Utworzony', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Rating kredytowy', + 'Creditcard' => 'Karta kredytowa', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO.', + 'Date' => 'Data', + 'Default' => 'Domyślna', + 'Delivery' => 'Dostawa', + 'Discount' => 'Zniżka', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Zniżka %', + 'Documents' => 'Dokumenty', + 'Due' => 'Z powodu', + 'Email' => 'E-mail', + 'Europe' => '#VALUE!', + 'Fax' => 'Faks', + 'Files' => 'Pliki', + 'Filter' => 'Filtr', + 'Freightage' => 'Frachtowanie', + 'Group' => 'Grupa', + 'ID' => 'ID', + 'Info' => 'Info', + 'Invoice' => 'Faktura', + 'Invoices' => 'Faktury', + 'IsDefault' => 'Jest domyślnie?', + 'Items' => '#VALUE!', + 'LastContact' => 'Ostatni kontakt', + 'LastOrder' => 'Ostatnie zamówienie', + 'Log' => 'Dziennik', + 'Logs' => 'Kłody', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR.', + 'MTDSales' => 'Sprzedaż MTD.', + 'Margin' => 'Margines', + 'Messages' => 'Wiadomości', + 'Modified' => 'Modyfikowany', + 'Modules' => 'Moduły', + 'Name' => 'Nazwa', + 'Name1' => 'Nazwa1.', + 'Name2' => 'Nazwa2.', + 'Name3' => 'Nazwa3.', + 'Net' => 'Internet', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Notatki', + 'Number' => 'Numer', + 'Office' => 'Gabinet', + 'Other' => '#VALUE!', + 'Payment' => 'Zapłata', + 'PaymentTerm' => 'Termin płatności', + 'Permission' => 'Pozwolenie', + 'Phone' => 'Telefon', + 'Postal' => 'Pocztowy', + 'Price' => 'Cena £', + 'Prices' => 'Ceny', + 'Private' => 'Prywatny', + 'Productgroup' => 'Grupa produktów', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Zakup', + 'Quantity' => 'Ilość', + 'RecentInvoices' => 'Ostatnie faktury.', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Obroty', + 'Segment' => 'Człon', + 'Segments' => 'Segmenty', + 'Subtype' => 'Podtyp', + 'Support' => 'Wsparcie', + 'Tags' => 'Tagi.', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Rodzaj', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Stronie internetowej', + 'Wire' => 'Drut', + 'YTDSales' => 'Sprzedaż Ytd.', + 'Zip' => 'Zamek błyskawiczny', +]]; diff --git a/Theme/Backend/Lang/pt.lang.php b/Theme/Backend/Lang/pt.lang.php new file mode 100755 index 0000000..04f60e0 --- /dev/null +++ b/Theme/Backend/Lang/pt.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Contabilidade', + 'Addition' => 'Adição', + 'Address' => 'Endereço', + 'Addresses' => 'Endereços', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Gerente da área', + 'Articlegroup' => 'ArticleGroup', + 'Articles' => 'Artigos', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Equilíbrio', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bônus', + 'Business' => 'O negócio', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv.', + 'Calendar' => 'Calendário', + 'City' => 'Cidade', + 'Client' => 'Cliente', + 'ClientID' => '#VALUE!', + 'Clients' => 'Clientes', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Contato', + 'Country' => 'País', + 'Created' => 'Criado', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Rating de crédito', + 'Creditcard' => 'Cartão de crédito', + 'Customers' => '#VALUE!', + 'DSO' => 'Dso.', + 'Date' => 'Encontro', + 'Default' => 'Padrão', + 'Delivery' => 'Entrega', + 'Discount' => 'Desconto', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Desconto%', + 'Documents' => 'Documentos', + 'Due' => 'Vencimento', + 'Email' => 'E-mail', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'arquivos', + 'Filter' => 'Filtro', + 'Freightage' => 'Freightage', + 'Group' => 'Grupo', + 'ID' => 'identificação', + 'Info' => 'Info', + 'Invoice' => 'Fatura', + 'Invoices' => 'Faturas', + 'IsDefault' => 'É padrão?', + 'Items' => '#VALUE!', + 'LastContact' => 'Último contato.', + 'LastOrder' => 'Último pedido', + 'Log' => 'Registro', + 'Logs' => 'Histórico', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR.', + 'MTDSales' => 'Sales Mtd.', + 'Margin' => 'Margem', + 'Messages' => 'Mensagens', + 'Modified' => 'Modificado', + 'Modules' => 'Módulos.', + 'Name' => 'Nome', + 'Name1' => 'Nome1.', + 'Name2' => 'Nome2.', + 'Name3' => 'Nome3.', + 'Net' => 'Internet', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Notas', + 'Number' => 'Número', + 'Office' => 'Escritório', + 'Other' => '#VALUE!', + 'Payment' => 'Pagamento', + 'PaymentTerm' => 'Termo de pagamento', + 'Permission' => 'Permissão', + 'Phone' => 'Telefone', + 'Postal' => 'Postal', + 'Price' => 'Preço', + 'Prices' => 'Preços', + 'Private' => 'Privado', + 'Productgroup' => 'Grupo de produtos', + 'Profile' => 'Perfil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Comprar', + 'Quantity' => 'Quantidade', + 'RecentInvoices' => 'Faturas recentes', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Vendas', + 'Segment' => 'Segmento', + 'Segments' => 'Segmentos', + 'Subtype' => 'Subtipo', + 'Support' => 'Apoio, suporte', + 'Tags' => 'Tag', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Modelo', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Local na rede Internet', + 'Wire' => 'Fio', + 'YTDSales' => 'Vendas do ano', + 'Zip' => 'Fecho eclair', +]]; diff --git a/Theme/Backend/Lang/ru.lang.php b/Theme/Backend/Lang/ru.lang.php new file mode 100755 index 0000000..8110627 --- /dev/null +++ b/Theme/Backend/Lang/ru.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Учет', + 'Addition' => 'Добавление', + 'Address' => 'Адрес', + 'Addresses' => 'Адреса', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Региональный менеджер', + 'Articlegroup' => 'Staregroup.', + 'Articles' => 'Статьи', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Остаток средств', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Бонус', + 'Business' => 'Бизнес', + 'CIS' => '#VALUE!', + 'CLV' => 'Каблук', + 'Calendar' => 'Календарь', + 'City' => 'Город', + 'Client' => 'Клиент', + 'ClientID' => '#VALUE!', + 'Clients' => 'Клиенты', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Контакт', + 'Country' => 'Страна', + 'Created' => 'Созданный', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Кредитный рейтинг', + 'Creditcard' => 'Кредитная карта', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO', + 'Date' => 'Дата', + 'Default' => 'Дефолт', + 'Delivery' => 'Доставка', + 'Discount' => 'Скидка', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Скидка %', + 'Documents' => 'Документы', + 'Due' => 'Должное', + 'Email' => 'Электронное письмо', + 'Europe' => '#VALUE!', + 'Fax' => 'Факс', + 'Files' => 'Файлы', + 'Filter' => 'Фильтр', + 'Freightage' => 'Фрахты', + 'Group' => 'Группа', + 'ID' => 'Я БЫ', + 'Info' => 'Информация', + 'Invoice' => 'Счет', + 'Invoices' => 'Счета', + 'IsDefault' => 'По умолчанию?', + 'Items' => '#VALUE!', + 'LastContact' => 'Последний контакт', + 'LastOrder' => 'Последний заказ', + 'Log' => 'Бревно', + 'Logs' => 'Журналы', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR', + 'MTDSales' => 'MTD Sales.', + 'Margin' => 'Допуск', + 'Messages' => 'Сообщения', + 'Modified' => 'Модифицированный', + 'Modules' => 'Модули', + 'Name' => 'Имя', + 'Name1' => 'Имя1.', + 'Name2' => 'Имя2.', + 'Name3' => 'Имя3.', + 'Net' => 'Сеть', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Примечания', + 'Number' => 'Число', + 'Office' => 'Офис', + 'Other' => '#VALUE!', + 'Payment' => 'Оплата', + 'PaymentTerm' => 'Условия оплаты', + 'Permission' => 'Разрешение', + 'Phone' => 'Телефон', + 'Postal' => 'Почтовый', + 'Price' => 'Цена', + 'Prices' => 'Цены', + 'Private' => 'Частный', + 'Productgroup' => 'Группа товаров', + 'Profile' => 'Профиль', + 'Profit' => '#VALUE!', + 'Purchase' => 'Покупка', + 'Quantity' => 'Количество', + 'RecentInvoices' => 'Недавние счета', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Продажи', + 'Segment' => 'Сегмент', + 'Segments' => 'Сегменты', + 'Subtype' => 'Подтип', + 'Support' => 'Служба поддержки', + 'Tags' => 'Теги', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Тип', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Веб-сайт', + 'Wire' => 'Проволока', + 'YTDSales' => 'YTD Sales.', + 'Zip' => 'Zip.', +]]; diff --git a/Theme/Backend/Lang/sv.lang.php b/Theme/Backend/Lang/sv.lang.php new file mode 100755 index 0000000..63e172f --- /dev/null +++ b/Theme/Backend/Lang/sv.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Bokföring', + 'Addition' => 'Tillägg', + 'Address' => 'Adress', + 'Addresses' => 'Adresser', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Områdeschef', + 'Articlegroup' => 'Artikelgrupp', + 'Articles' => 'Artiklar', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Balans', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus', + 'Business' => 'Företag', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv', + 'Calendar' => 'Kalender', + 'City' => 'Stad', + 'Client' => 'Klient', + 'ClientID' => '#VALUE!', + 'Clients' => 'Klienter', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Kontakt', + 'Country' => 'Land', + 'Created' => 'Skapad', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Kreditvärdighet', + 'Creditcard' => 'Kreditkort', + 'Customers' => '#VALUE!', + 'DSO' => 'Do', + 'Date' => 'Datum', + 'Default' => 'Standard', + 'Delivery' => 'Leverans', + 'Discount' => 'Rabatt', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Rabatt%', + 'Documents' => 'Dokument', + 'Due' => 'På grund av', + 'Email' => 'E-post', + 'Europe' => '#VALUE!', + 'Fax' => 'Fax', + 'Files' => 'Filer', + 'Filter' => 'Filtrera', + 'Freightage' => 'Frakt', + 'Group' => 'Grupp', + 'ID' => 'Id', + 'Info' => 'Info', + 'Invoice' => 'Faktura', + 'Invoices' => 'Fakturor', + 'IsDefault' => 'Är standard?', + 'Items' => '#VALUE!', + 'LastContact' => 'Senaste kontakten', + 'LastOrder' => 'Sista beställningen', + 'Log' => 'Logga', + 'Logs' => 'Loggar', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr', + 'MTDSales' => 'MTD-försäljning', + 'Margin' => 'Marginal', + 'Messages' => 'Budskap', + 'Modified' => 'Ändrad', + 'Modules' => 'Moduler', + 'Name' => 'namn', + 'Name1' => 'Namn1', + 'Name2' => 'Namn2', + 'Name3' => 'Namn3', + 'Net' => 'Netto', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Anteckningar', + 'Number' => 'siffra', + 'Office' => 'Kontor', + 'Other' => '#VALUE!', + 'Payment' => 'Betalning', + 'PaymentTerm' => 'Betalningsvillkor', + 'Permission' => 'Tillstånd', + 'Phone' => 'Telefon', + 'Postal' => 'Post', + 'Price' => 'Pris', + 'Prices' => 'Priser', + 'Private' => 'Privat', + 'Productgroup' => 'Produktgrupp', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Inköp', + 'Quantity' => 'Kvantitet', + 'RecentInvoices' => 'Nya fakturor', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Försäljning', + 'Segment' => 'Segmentet', + 'Segments' => 'Segment', + 'Subtype' => 'Subtyp', + 'Support' => 'Stöd', + 'Tags' => 'Tagg', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Typ', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Hemsida', + 'Wire' => 'Tråd', + 'YTDSales' => 'YTD-försäljning', + 'Zip' => 'Blixtlås', +]]; diff --git a/Theme/Backend/Lang/th.lang.php b/Theme/Backend/Lang/th.lang.php new file mode 100755 index 0000000..37fc31c --- /dev/null +++ b/Theme/Backend/Lang/th.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'การบัญชี', + 'Addition' => 'ส่วนที่เพิ่มเข้าไป', + 'Address' => 'ที่อยู่', + 'Addresses' => 'ที่อยู่', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'ผู้จัดการพื้นที่', + 'Articlegroup' => 'ArticleGroup', + 'Articles' => 'บทความ', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'สมดุล', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'โบนัส', + 'Business' => 'ธุรกิจ', + 'CIS' => '#VALUE!', + 'CLV' => 'clv', + 'Calendar' => 'ปฏิทิน', + 'City' => 'เมือง', + 'Client' => 'ลูกค้า', + 'ClientID' => '#VALUE!', + 'Clients' => 'ลูกค้า', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'ติดต่อ', + 'Country' => 'ประเทศ', + 'Created' => 'สร้าง', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'การจัดอันดับเครดิต', + 'Creditcard' => 'บัตรเครดิต', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO', + 'Date' => 'วันที่', + 'Default' => 'ค่าเริ่มต้น', + 'Delivery' => 'จัดส่ง', + 'Discount' => 'การลดราคา', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'การลดราคา %', + 'Documents' => 'เอกสาร', + 'Due' => 'เนื่องจาก', + 'Email' => 'อีเมล', + 'Europe' => '#VALUE!', + 'Fax' => 'แฟกซ์', + 'Files' => 'ไฟล์', + 'Filter' => 'กรอง', + 'Freightage' => 'การขนส่งสินค้า', + 'Group' => 'กลุ่ม', + 'ID' => 'id', + 'Info' => 'ข้อมูล', + 'Invoice' => 'ใบแจ้งหนี้', + 'Invoices' => 'ใบแจ้งหนี้', + 'IsDefault' => 'เป็นค่าเริ่มต้น?', + 'Items' => '#VALUE!', + 'LastContact' => 'ติดต่อล่าสุด', + 'LastOrder' => 'คำสั่งสุดท้าย', + 'Log' => 'บันทึก', + 'Logs' => 'การบันทึก', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR', + 'MTDSales' => 'ขาย MTD', + 'Margin' => 'ระยะขอบ', + 'Messages' => 'ข้อความ', + 'Modified' => 'ที่ได้รับการแก้ไข', + 'Modules' => 'โมดูล', + 'Name' => 'ชื่อ', + 'Name1' => 'ชื่อ 1', + 'Name2' => 'ชื่อ 2', + 'Name3' => 'ชื่อ 3', + 'Net' => 'สุทธิ', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'หมายเหตุ', + 'Number' => 'ตัวเลข', + 'Office' => 'สำนักงาน', + 'Other' => '#VALUE!', + 'Payment' => 'การชำระเงิน', + 'PaymentTerm' => 'เงื่อนไขการชำระเงิน', + 'Permission' => 'การอนุญาต', + 'Phone' => 'โทรศัพท์', + 'Postal' => 'เกี่ยวกับการไปรษณีย์', + 'Price' => 'ราคา', + 'Prices' => 'ราคา', + 'Private' => 'ส่วนตัว', + 'Productgroup' => 'กลุ่มผลิตภัณฑ์', + 'Profile' => 'ประวัติโดยย่อ', + 'Profit' => '#VALUE!', + 'Purchase' => 'ซื้อ', + 'Quantity' => 'ปริมาณ', + 'RecentInvoices' => 'ใบแจ้งหนี้ล่าสุด', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'ฝ่ายขาย', + 'Segment' => 'ส่วน', + 'Segments' => 'กลุ่ม', + 'Subtype' => 'ประเภทย่อย', + 'Support' => 'สนับสนุน', + 'Tags' => 'แท็ก', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'พิมพ์', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'เว็บไซต์', + 'Wire' => 'ลวด', + 'YTDSales' => 'ขาย YTD', + 'Zip' => 'ซิป', +]]; diff --git a/Theme/Backend/Lang/tr.lang.php b/Theme/Backend/Lang/tr.lang.php new file mode 100755 index 0000000..7234743 --- /dev/null +++ b/Theme/Backend/Lang/tr.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Muhasebe', + 'Addition' => 'İlave', + 'Address' => 'Adres', + 'Addresses' => 'Adresler', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Alan müdürü', + 'Articlegroup' => 'Makale grubu', + 'Articles' => 'Nesne', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Denge', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Bonus', + 'Business' => 'İşletme', + 'CIS' => '#VALUE!', + 'CLV' => 'Clv', + 'Calendar' => 'Takvim', + 'City' => 'Şehir', + 'Client' => 'Müşteri', + 'ClientID' => '#VALUE!', + 'Clients' => 'Müşteriler', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Temas', + 'Country' => 'Ülke', + 'Created' => 'Yaratılmış', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Kredi notu', + 'Creditcard' => 'Kredi kartı', + 'Customers' => '#VALUE!', + 'DSO' => 'Dso', + 'Date' => 'Tarih', + 'Default' => 'Varsayılan', + 'Delivery' => 'Teslimat', + 'Discount' => 'İndirim', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'İndirim %', + 'Documents' => 'Belgeler', + 'Due' => 'Vadesi dolmuş', + 'Email' => 'E-posta', + 'Europe' => '#VALUE!', + 'Fax' => 'Faks', + 'Files' => 'Dosyalar', + 'Filter' => 'Filtrelemek', + 'Freightage' => 'Yük', + 'Group' => 'Grup', + 'ID' => 'İD', + 'Info' => 'Bilgi', + 'Invoice' => 'Fatura', + 'Invoices' => 'Faturalar', + 'IsDefault' => 'Varsayılan mı?', + 'Items' => '#VALUE!', + 'LastContact' => 'Son iletişim', + 'LastOrder' => 'Son sipariş', + 'Log' => 'Kayıt', + 'Logs' => 'Kütükler', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Mrr', + 'MTDSales' => 'Mtd satışları', + 'Margin' => 'Marj', + 'Messages' => 'Mesaj', + 'Modified' => 'Değiştirilmiş', + 'Modules' => 'Modüller', + 'Name' => 'İsim', + 'Name1' => 'İsim1', + 'Name2' => 'İsim2', + 'Name3' => 'İsim3', + 'Net' => 'Ağ', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Notalar', + 'Number' => 'Numara', + 'Office' => 'Ofis', + 'Other' => '#VALUE!', + 'Payment' => 'Ödeme', + 'PaymentTerm' => 'Ödeme koşulu', + 'Permission' => 'İzin', + 'Phone' => 'Telefon', + 'Postal' => 'Posta', + 'Price' => 'Fiyat', + 'Prices' => 'Fiyat:% s', + 'Private' => 'Özel', + 'Productgroup' => 'Ürün grubu', + 'Profile' => 'Profil', + 'Profit' => '#VALUE!', + 'Purchase' => 'Satın alma', + 'Quantity' => 'Miktar', + 'RecentInvoices' => 'Son Faturalar', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Satış', + 'Segment' => 'Segment', + 'Segments' => 'Segmentler', + 'Subtype' => 'Alt tip', + 'Support' => 'Destek', + 'Tags' => 'Etiketler', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Tip', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'İnternet sitesi', + 'Wire' => 'Tel', + 'YTDSales' => 'YTD satışları', + 'Zip' => 'Zip', +]]; diff --git a/Theme/Backend/Lang/uk.lang.php b/Theme/Backend/Lang/uk.lang.php new file mode 100755 index 0000000..1987ecf --- /dev/null +++ b/Theme/Backend/Lang/uk.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => 'Бухгалтерський облік', + 'Addition' => 'Додавання', + 'Address' => 'Адреса', + 'Addresses' => 'Адреси', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => 'Менеджер області', + 'Articlegroup' => 'Статтюгрупи', + 'Articles' => 'Статті', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => 'Баланс', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => 'Бонус', + 'Business' => 'Бізнес', + 'CIS' => '#VALUE!', + 'CLV' => 'Клоп', + 'Calendar' => 'Календар', + 'City' => 'Місто', + 'Client' => 'Клієнт', + 'ClientID' => '#VALUE!', + 'Clients' => 'Клієнти', + 'ComparisonTime' => '#VALUE!', + 'Contact' => 'Контакт', + 'Country' => 'Країна', + 'Created' => 'Створений', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => 'Кредитний рейтинг', + 'Creditcard' => 'Кредитна карта', + 'Customers' => '#VALUE!', + 'DSO' => 'Дз', + 'Date' => 'Дата', + 'Default' => 'За замовчуванням', + 'Delivery' => 'Доставка', + 'Discount' => 'Знижка', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => 'Знижка%', + 'Documents' => 'Документи', + 'Due' => 'Заборгованість', + 'Email' => 'Електронна пошта', + 'Europe' => '#VALUE!', + 'Fax' => 'Факс', + 'Files' => 'Файли', + 'Filter' => 'Фільтрувати', + 'Freightage' => 'Фрахт', + 'Group' => 'Група', + 'ID' => 'Ідентифікатор', + 'Info' => 'Інформація', + 'Invoice' => 'Рахунок-фактура', + 'Invoices' => 'Рахунки-фактури', + 'IsDefault' => 'Чи є за замовчуванням?', + 'Items' => '#VALUE!', + 'LastContact' => 'Останній контакт', + 'LastOrder' => 'Остання замовлення', + 'Log' => 'Журнал', + 'Logs' => 'Журнали', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'Пан', + 'MTDSales' => 'Продажі MTD', + 'Margin' => 'Маржа', + 'Messages' => 'Повідомлень', + 'Modified' => 'Модифікований', + 'Modules' => 'Модулі', + 'Name' => 'Назва', + 'Name1' => 'Name1', + 'Name2' => 'Name2', + 'Name3' => 'Name3', + 'Net' => 'Сітка', + 'NewCustomers' => '#VALUE!', + 'Notes' => 'Ноти', + 'Number' => 'Число', + 'Office' => 'Офіс', + 'Other' => '#VALUE!', + 'Payment' => 'Платіж', + 'PaymentTerm' => 'Термін оплати', + 'Permission' => 'Дозвіл', + 'Phone' => 'Телефон', + 'Postal' => 'Поштовий', + 'Price' => 'Ціна', + 'Prices' => 'Ціни', + 'Private' => 'Приватний', + 'Productgroup' => 'Група продуктів', + 'Profile' => 'Профіль', + 'Profit' => '#VALUE!', + 'Purchase' => 'Придбання', + 'Quantity' => 'Кількість', + 'RecentInvoices' => 'Останні рахунки-фактури', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => 'Продаж', + 'Segment' => 'Сегмент', + 'Segments' => 'Сегменти', + 'Subtype' => 'Підтип', + 'Support' => 'Підтримка', + 'Tags' => 'Теги', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => 'Тип', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => 'Веб-сайт', + 'Wire' => 'Дріт', + 'YTDSales' => 'Ytd продажі', + 'Zip' => 'Блиск', +]]; diff --git a/Theme/Backend/Lang/zh.lang.php b/Theme/Backend/Lang/zh.lang.php new file mode 100755 index 0000000..063d656 --- /dev/null +++ b/Theme/Backend/Lang/zh.lang.php @@ -0,0 +1,126 @@ + [ + 'Accounting' => '会计', + 'Addition' => '添加', + 'Address' => '地址', + 'Addresses' => '地址', + 'Africa' => '#VALUE!', + 'AllCustomers' => '#VALUE!', + 'America' => '#VALUE!', + 'Analyse' => '#VALUE!', + 'AreaManager' => '区域经理', + 'Articlegroup' => '商品组', + 'Articles' => '文章', + 'Asia' => '#VALUE!', + 'Attribute' => '#VALUE!', + 'Attributes' => '#VALUE!', + 'Balance' => '平衡', + 'BaseTime' => '#VALUE!', + 'Bills' => '#VALUE!', + 'Bonus' => '奖金', + 'Business' => '商业', + 'CIS' => '#VALUE!', + 'CLV' => 'CLV.', + 'Calendar' => '日历', + 'City' => '城市', + 'Client' => '客户', + 'ClientID' => '#VALUE!', + 'Clients' => '客户', + 'ComparisonTime' => '#VALUE!', + 'Contact' => '接触', + 'Country' => '国家', + 'Created' => '创造了', + 'CreatedAt' => '#VALUE!', + 'CreditRating' => '信用评级', + 'Creditcard' => '信用卡', + 'Customers' => '#VALUE!', + 'DSO' => 'DSO', + 'Date' => '日期', + 'Default' => '默认', + 'Delivery' => '交货', + 'Discount' => '折扣', + 'DiscountBonus' => '#VALUE!', + 'DiscountP' => '折扣 %', + 'Documents' => '文件', + 'Due' => '到期的', + 'Email' => '电子邮件', + 'Europe' => '#VALUE!', + 'Fax' => '传真', + 'Files' => '文件', + 'Filter' => '筛选', + 'Freightage' => 'FRIGUTAGE.', + 'Group' => '团体', + 'ID' => 'ID', + 'Info' => '信息', + 'Invoice' => '发票', + 'Invoices' => '发票', + 'IsDefault' => '默认为默认情况下?', + 'Items' => '#VALUE!', + 'LastContact' => '最后联系人', + 'LastOrder' => '最后的订单', + 'Log' => '日志', + 'Logs' => '日志', + 'LostCustomers' => '#VALUE!', + 'MRR' => 'MRR.', + 'MTDSales' => 'MTD销售', + 'Margin' => '利润', + 'Messages' => '消息', + 'Modified' => '修改的', + 'Modules' => '模块', + 'Name' => '名称', + 'Name1' => '名称1', + 'Name2' => '名称2.', + 'Name3' => '名称3.', + 'Net' => '网', + 'NewCustomers' => '#VALUE!', + 'Notes' => '笔记', + 'Number' => '数字', + 'Office' => '办公室', + 'Other' => '#VALUE!', + 'Payment' => '支付', + 'PaymentTerm' => '付款期限', + 'Permission' => '允许', + 'Phone' => '电话', + 'Postal' => '邮政', + 'Price' => '价格', + 'Prices' => '价格', + 'Private' => '私人的', + 'Productgroup' => '产品组', + 'Profile' => '轮廓', + 'Profit' => '#VALUE!', + 'Purchase' => '购买', + 'Quantity' => '数量', + 'RecentInvoices' => '最近的发票', + 'Region' => '#VALUE!', + 'Rep' => '#VALUE!', + 'Retention' => '#VALUE!', + 'Sales' => '销售量', + 'Segment' => '分割', + 'Segments' => '段', + 'Subtype' => '亚型', + 'Support' => '支持', + 'Tags' => '标签', + 'Title' => '#VALUE!', + 'Total' => '#VALUE!', + 'TotalPrice' => '#VALUE!', + 'Type' => '类型', + 'UnitPrice' => '#VALUE!', + 'Value' => '#VALUE!', + 'Website' => '网站', + 'Wire' => '金属丝', + 'YTDSales' => 'ytd销售', + 'Zip' => '压缩', +]]; diff --git a/Theme/Backend/vehicle-create.tpl.php b/Theme/Backend/vehicle-create.tpl.php new file mode 100755 index 0000000..a49f942 --- /dev/null +++ b/Theme/Backend/vehicle-create.tpl.php @@ -0,0 +1,289 @@ +getData('nav')->render(); ?> + +

+
+ +
+
+ request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Client'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Contact'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Address'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('PaymentTerm'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Payment'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-6' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Price'); ?>

+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-7' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('AreaManager'); ?>

+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-8' ? ' checked' : ''; ?>> +
+
+ request->uri->fragment === 'c-tab-9' ? ' checked' : ''; ?>> +
+
+
+ l11nManager, $this->request, $this->response); + $footerView->setTemplate('/Web/Templates/Lists/Footer/PaginationBig'); + $footerView->setPages(20); + $footerView->setPage(1); + ?> +
+ + + + + + +
getHtml('Logs'); ?>
IP + getHtml('ID', '0', '0'); ?> + getHtml('Name'); ?> + getHtml('Log'); ?> + getHtml('Date'); ?> +
printHtml($this->request->getOrigin()); ?> + printHtml((string) $this->request->header->account); ?> + printHtml((string) $this->request->header->account); ?> + Creating customer + printHtml((new \DateTime('now'))->format('Y-m-d H:i:s')); ?> +
+
+
+
+
+
+
diff --git a/Theme/Backend/vehicle-list.tpl.php b/Theme/Backend/vehicle-list.tpl.php new file mode 100755 index 0000000..f2f8b46 --- /dev/null +++ b/Theme/Backend/vehicle-list.tpl.php @@ -0,0 +1,128 @@ +getData('client'); + +echo $this->getData('nav')->render(); ?> +
+
+
+
getHtml('Clients'); ?>
+
+ + + + + $value) : ++$count; + $url = UriFactory::build('{/lang}/{/app}/sales/client/profile?{?}&id=' . $value->getId()); + $image = $value->getFileByTypeName('client_profile_image'); + ?> + +
+ getHtml('ID', '0', '0'); ?> + + + + getHtml('Name'); ?> + + + + getHtml('City'); ?> + + + + getHtml('Zip'); ?> + + + + getHtml('Address'); ?> + + + + getHtml('Country'); ?> + + + +
<?= $this->getHtml('IMG_alt_client'); ?> + printHtml($value->number); ?> + printHtml($value->profile->account->name1); ?> printHtml($value->profile->account->name2); ?> + printHtml($value->mainAddress->city); ?> + printHtml($value->mainAddress->postal); ?> + printHtml($value->mainAddress->address); ?> + printHtml($value->mainAddress->getCountry()); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
+
diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php new file mode 100755 index 0000000..7356d4e --- /dev/null +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -0,0 +1,618 @@ +getData('client'); +$notes = $client->getNotes(); +$files = $client->getFiles(); + +$newestInvoices = $this->getData('newestInvoices') ?? []; +$monthlySalesCosts = $this->getData('monthlySalesCosts') ?? []; + +/** + * @var \phpOMS\Views\View $this + */ +echo $this->getData('nav')->render(); +?> +
+
+ +
+
+ request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>> +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+
+ getHtml('Address'); ?> + + + + + +
+
+ + mainAddress->addition)) : ?> +
+
+ +
+
+
+
+
+
+
+
+
+ mainAddress->getCountry()) . '.svg')) : ?> + <?= $this->getHtml('IMG_alt_map'); ?> + +
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+ +
getHtml('YTDSales'); ?>: + +
getHtml('MTDSales'); ?>: + +
getHtml('CLV'); ?>: + +
getHtml('MRR'); ?>: + +
+
+
+
+ +
+
+
+ +
getHtml('LastContact'); ?>: + +
getHtml('LastOrder'); ?>: + +
getHtml('Created'); ?>: + +
getHtml('Modified'); ?>: + +
+
+
+
+ +
+
+
+ +
getHtml('DSO'); ?>: + +
getHtml('Due'); ?>: + +
getHtml('Balance'); ?>: + +
getHtml('CreditRating'); ?>: + +
+
+
+
+
+ +
+
+
+
getHtml('Notes'); ?>
+
+ + + + + getId()); + ?> + +
getHtml('Title'); ?> + getHtml('CreatedAt'); ?> +
title; ?> + createdAt->format('Y-m-d'); ?> + +
+
+
+
+ +
+
+
getHtml('Documents'); ?>
+
+ + + + + getId()); + ?> + +
getHtml('Title'); ?> + + getHtml('CreatedAt'); ?> +
name; ?> + extension; ?> + createdAt->format('Y-m-d'); ?> + +
+
+
+
+
+ +
+
+
+
getHtml('RecentInvoices'); ?>
+ + + + + getId()); + ?> + +
getHtml('Number'); ?> + getHtml('Type'); ?> + getHtml('Name'); ?> + getHtml('Net'); ?> + getHtml('Date'); ?> +
getNumber(); ?> + type->getL11n(); ?> + billTo; ?> + netSales->getCurrency(); ?> + createdAt->format('Y-m-d'); ?> + +
+
+
+
+ +
+
+
+
getHtml('Segments'); ?>
+
+
+
+ +
+
+
getHtml('Sales'); ?>
+
+ + + ], + "datasets": [ + { + "label": "getHtml('Margin'); ?>", + "type": "line", + "data": [ + + + ], + "yAxisID": "axis-2", + "fill": false, + "borderColor": "rgb(255, 99, 132)", + "backgroundColor": "rgb(255, 99, 132)" + }, + { + "label": "getHtml('Sales'); ?>", + "type": "bar", + "data": [ + + + ], + "yAxisID": "axis-1", + "backgroundColor": "rgb(54, 162, 235)" + } + ] + }, + "options": { + "scales": { + "yAxes": [ + { + "id": "axis-1", + "display": true, + "position": "left" + }, + { + "id": "axis-2", + "display": true, + "position": "right", + "scaleLabel": { + "display": true, + "labelString": "getHtml('Margin'); ?> %" + }, + "gridLines": { + "display": false + }, + "beginAtZero": true, + "ticks": { + "min": 0, + "max": 100, + "stepSize": 10 + } + } + ] + } + } + }'> +
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Address'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+

getHtml('Contact'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Payment'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+

getHtml('PaymentTerm'); ?>

+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-6' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('Price'); ?>

+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-7' ? ' checked' : ''; ?>> +
+
+
+
+

getHtml('AreaManager'); ?>

+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-8' ? ' checked' : ''; ?>> +
+
+ request->uri->fragment === 'c-tab-9' ? ' checked' : ''; ?>> +
+ +
+ request->uri->fragment === 'c-tab-9' ? ' checked' : ''; ?>> +
+ +
+ request->uri->fragment === 'c-tab-10' ? ' checked' : ''; ?>> +
+
+
+ l11nManager, $this->request, $this->response); + $footerView->setTemplate('/Web/Templates/Lists/Footer/PaginationBig'); + $footerView->setPages(20); + $footerView->setPage(1); + ?> +
+ + + + + + + + +
getHtml('Logs'); ?>
IP + getHtml('ID', '0', '0'); ?> + getHtml('Name'); ?> + getHtml('Log'); ?> + getHtml('Date'); ?> +
+
printHtml($this->request->getOrigin()); ?> + printHtml((string) $this->request->header->account); ?> + printHtml((string) $this->request->header->account); ?> + Creating customer + printHtml((new \DateTime('now'))->format('Y-m-d H:i:s')); ?> +
+
+
+
+
+
+
diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..15e8d01 --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "karaka/module", + "description": "Module for Karaka.", + "authors": [ + { + "name": "Dennis Eichhorn", + "email": "spl1nes.com@googlemail.com" + } + ], + "require-dev": { + "phpunit/phpunit": ">=9.4", + "friendsofphp/php-cs-fixer": ">=3.8", + "squizlabs/php_codesniffer": ">=3.6", + "phpmd/phpmd": ">=2.9", + "phpstan/phpstan": ">=1.8.6", + "phan/phan": ">=3.2.6" + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/composer.lock b/composer.lock new file mode 100755 index 0000000..1885692 --- /dev/null +++ b/composer.lock @@ -0,0 +1,4802 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "83c956950eced6728b0e73b4374aacd7", + "packages": [], + "packages-dev": [ + { + "name": "composer/pcre", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T20:21:48+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.13.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "5b668aef16090008790395c02c893b1ba13f7e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", + "reference": "5b668aef16090008790395c02c893b1ba13f7e08", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^0.12.20", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", + "symfony/cache": "^4.4 || ^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.2" + }, + "time": "2021-08-05T19:00:23+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-02-28T11:07:21+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.8.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", + "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", + "shasum": "" + }, + "require": { + "composer/semver": "^3.2", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^1.13", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "php-cs-fixer/diff": "^2.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.23", + "symfony/polyfill-php80": "^1.25", + "symfony/polyfill-php81": "^1.25", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" + }, + "require-dev": { + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^1.5", + "mikey179/vfsstream": "^1.6.10", + "php-coveralls/php-coveralls": "^2.5.2", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.15", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.5", + "phpunitgoodpractices/traits": "^1.9.1", + "symfony/phpunit-bridge": "^6.0", + "symfony/yaml": "^5.4 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.8.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2022-03-18T17:20:59+00:00" + }, + { + "name": "microsoft/tolerant-php-parser", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/microsoft/tolerant-php-parser.git", + "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/6a965617cf484355048ac6d2d3de7b6ec93abb16", + "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.15" + }, + "type": "library", + "autoload": { + "psr-4": { + "Microsoft\\PhpParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Lourens", + "email": "roblou@microsoft.com" + } + ], + "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", + "support": { + "issues": "https://github.com/microsoft/tolerant-php-parser/issues", + "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.1" + }, + "time": "2021-07-16T21:28:12+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v4.0.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" + }, + "time": "2020-12-01T19:48:11+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.13.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + }, + "time": "2021-11-30T19:35:32+00:00" + }, + { + "name": "pdepend/pdepend", + "version": "2.10.3", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "da3166a06b4a89915920a42444f707122a1584c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/da3166a06b4a89915920a42444f707122a1584c9", + "reference": "da3166a06b4a89915920a42444f707122a1584c9", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3|^4|^5|^6.0", + "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0", + "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0|^1.2.3", + "gregwar/rst": "^1.0", + "phpunit/phpunit": "^4.8.36|^5.7.27", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/2.10.3" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", + "type": "tidelift" + } + ], + "time": "2022-02-23T07:53:09+00:00" + }, + { + "name": "phan/phan", + "version": "5.3.2", + "source": { + "type": "git", + "url": "https://github.com/phan/phan.git", + "reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phan/phan/zipball/b7697eb811e912c038f709f8e1c4911c7ada3edc", + "reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4|^2.0|^3.0", + "composer/xdebug-handler": "^2.0|^3.0", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.4", + "microsoft/tolerant-php-parser": "^0.1.0", + "netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0", + "php": "^7.2.0|^8.0.0", + "sabre/event": "^5.1.3", + "symfony/console": "^3.2|^4.0|^5.0|^6.0", + "symfony/polyfill-mbstring": "^1.11.0", + "symfony/polyfill-php80": "^1.20.0", + "tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.16+ is recommended.", + "ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable", + "ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions.", + "ext-var_representation": "Suggested for converting values to strings in issue messages" + }, + "bin": [ + "phan", + "phan_client", + "tocheckstyle" + ], + "type": "project", + "autoload": { + "psr-4": { + "Phan\\": "src/Phan" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + }, + { + "name": "Rasmus Lerdorf" + }, + { + "name": "Andrew S. Morrison" + } + ], + "description": "A static analyzer for PHP", + "keywords": [ + "analyzer", + "php", + "static" + ], + "support": { + "issues": "https://github.com/phan/phan/issues", + "source": "https://github.com/phan/phan/tree/5.3.2" + }, + "time": "2022-02-01T00:17:36+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-cs-fixer/diff", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/29dc0d507e838c4580d018bd8b5cb412474f7ec3", + "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "sebastian/diff v3 backport support for PHP 5.6+", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/diff/issues", + "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2" + }, + "time": "2020-10-14T08:32:19+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "77a32518733312af16a44300404e945338981de3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, + "time": "2022-03-15T21:29:03+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.12.0", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "c0b678ba71902f539c27c14332aa0ddcf14388ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/c0b678ba71902f539c27c14332aa0ddcf14388ec", + "reference": "c0b678ba71902f539c27c14332aa0ddcf14388ec", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", + "ext-xml": "*", + "pdepend/pdepend": "^2.10.3", + "php": ">=5.3.9" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.3.2", + "ext-json": "*", + "ext-simplexml": "*", + "gregwar/rst": "^1.0", + "mikey179/vfsstream": "^1.6.8", + "phpunit/phpunit": "^4.8.36 || ^5.7.27", + "squizlabs/php_codesniffer": "^2.0" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "https://phpmd.org/", + "keywords": [ + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.12.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2022-03-24T13:33:01+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.5.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "bbf68cae24f6dc023c607ea0f87da55dd9d55c2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bbf68cae24f6dc023c607ea0f87da55dd9d55c2b", + "reference": "bbf68cae24f6dc023c607ea0f87da55dd9d55c2b", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.5.4" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpstan", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-04-03T12:39:00+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.15", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.13.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-03-07T09:28:20+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.0", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-01T12:37:26+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "d7da22897125d34d7eddf7977758191c06a74497" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497", + "reference": "d7da22897125d34d7eddf7977758191c06a74497", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ], + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, + "time": "2021-11-04T06:51:17+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-11-11T14:18:36+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-03-15T09:54:48+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.6.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2021-12-12T21:44:58+00:00" + }, + { + "name": "symfony/config", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "22850bfdd2b6090568ad05dece6843c859d933b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/22850bfdd2b6090568ad05dece6843c859d933b7", + "reference": "22850bfdd2b6090568ad05dece6843c859d933b7", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/filesystem": "^5.4|^6.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php81": "^1.22" + }, + "conflict": { + "symfony/finder": "<4.4" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-22T16:12:04+00:00" + }, + { + "name": "symfony/console", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", + "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-31T17:18:25+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "3e8a405fcc2eaf4eadb25b5e259ad9bf90499848" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3e8a405fcc2eaf4eadb25b5e259ad9bf90499848", + "reference": "3e8a405fcc2eaf4eadb25b5e259ad9bf90499848", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php81": "^1.22", + "symfony/service-contracts": "^1.1.6|^2.0|^3.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<5.4", + "symfony/finder": "<5.4", + "symfony/proxy-manager-bridge": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-08T15:43:52+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934", + "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/event-dispatcher-contracts": "^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", + "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-04-01T12:54:51+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/8661b74dbabc23223f38c9b99d3f8ade71170430", + "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-26T17:23:29+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "51f7006670febe4cbcbae177cbffe93ff833250d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/51f7006670febe4cbcbae177cbffe93ff833250d", + "reference": "51f7006670febe4cbcbae177cbffe93ff833250d", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-20T20:35:02+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-23T21:10:46+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-30T18:21:41+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-04T08:16:47+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-13T13:58:11+00:00" + }, + { + "name": "symfony/process", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", + "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-18T16:21:55+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-13T20:10:05+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.0.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "f2c1780607ec6502f2121d9729fd8150a655d337" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f2c1780607ec6502f2121d9729fd8150a655d337", + "reference": "f2c1780607ec6502f2121d9729fd8150a655d337", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/service-contracts": "^1|^2|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v6.0.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-21T17:15:17+00:00" + }, + { + "name": "symfony/string", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "tysonandre/var_representation_polyfill", + "version": "0.1.1", + "source": { + "type": "git", + "url": "https://github.com/TysonAndre/var_representation_polyfill.git", + "reference": "0a942e74e18af5514749895507bc6ca7ab96399a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/0a942e74e18af5514749895507bc6ca7ab96399a", + "reference": "0a942e74e18af5514749895507bc6ca7ab96399a", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.2.0|^8.0.0" + }, + "require-dev": { + "phan/phan": "^4.0", + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-var_representation": "*" + }, + "type": "library", + "autoload": { + "files": [ + "src/var_representation.php" + ], + "psr-4": { + "VarRepresentation\\": "src/VarRepresentation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + } + ], + "description": "Polyfill for var_representation: convert a variable to a string in a way that fixes the shortcomings of var_export", + "keywords": [ + "var_export", + "var_representation" + ], + "support": { + "issues": "https://github.com/TysonAndre/var_representation_polyfill/issues", + "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.1" + }, + "time": "2021-08-16T00:12:50+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.0.0" +} diff --git a/info.json b/info.json new file mode 100755 index 0000000..7d98326 --- /dev/null +++ b/info.json @@ -0,0 +1,49 @@ +{ + "name": { + "id": 1003500000, + "internal": "FleetManagement", + "external": "Fleet Management" + }, + "category": "Fleet", + "version": "1.0.0", + "requirements": { + "phpOMS": "1.0.0", + "phpOMS-db": "1.0.0" + }, + "creator": { + "name": "Karaka", + "website": "jingga.app" + }, + "description": "The buisness module.", + "directory": "FleetManagement", + "dependencies": { + "Admin": "1.0.0", + "Profile": "1.0.0", + "Media": "1.0.0", + "Editor": "1.0.0" + }, + "providing": { + "Navigation": "*", + "Media": "*" + }, + "load": [ + { + "pid": [ + "/fleet" + ], + "type": 4, + "for": 0, + "from": "FleetManagement", + "file": "FleetManagement" + }, + { + "pid": [ + "/" + ], + "type": 5, + "from": "FleetManagement", + "for": "Navigation", + "file": "Navigation" + } + ] +} diff --git a/tests/Admin/AdminTest.php b/tests/Admin/AdminTest.php new file mode 100755 index 0000000..9e0ebb5 --- /dev/null +++ b/tests/Admin/AdminTest.php @@ -0,0 +1,27 @@ + [ + 'core' => [ + 'masters' => [ + 'admin' => [ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'insert' => [ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'select' => [ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'update' => [ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'delete' => [ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'schema' => [ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + ], + 'postgresql' => [ + 'admin' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'insert' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'select' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'update' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'delete' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'schema' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + ], + 'sqlite' => [ + 'admin' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'insert' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'select' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'update' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'delete' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'schema' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + ], + 'mssql' => [ + 'admin' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'R00troot', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'insert' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'R00troot', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'select' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'R00troot', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'update' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'R00troot', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'delete' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'R00troot', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + 'schema' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'R00troot', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + ], + ], + ], + ], + 'cache' => [ + 'redis' => [ + 'db' => 1, + 'host' => '127.0.0.1', + 'port' => 6379, + ], + 'memcached' => [ + 'host' => '127.0.0.1', + 'port' => 11211, + ], + ], + 'mail' => [ + 'imap' => [ + 'host' => '127.0.0.1', + 'port' => 143, + 'ssl' => false, + 'user' => 'test', + 'password' => '123456', + ], + 'pop3' => [ + 'host' => '127.0.0.1', + 'port' => 25, + 'ssl' => false, + 'user' => 'test', + 'password' => '123456', + ], + ], + 'log' => [ + 'file' => [ + 'path' => __DIR__ . '/Logs', + ], + ], + 'page' => [ + 'root' => '/', + 'https' => false, + ], + 'app' => [ + 'path' => __DIR__, + 'default' => [ + 'app' => 'Backend', + 'id' => 'backend', + 'lang' => 'en', + 'theme' => 'Backend', + 'org' => 1, + ], + 'domains' => [ + '127.0.0.1' => [ + 'app' => 'Backend', + 'id' => 'backend', + 'lang' => 'en', + 'theme' => 'Backend', + 'org' => 1, + ], + ], + ], + 'socket' => [ + 'master' => [ + 'host' => '127.0.0.1', + 'limit' => 300, + 'port' => 4310, + ], + ], + 'language' => [ + 'en', + ], + 'apis' => [ + ], +]; + +// Reset database +if (\defined('RESET') && RESET === '1') { + if (\extension_loaded('pdo_mysql')) { + try { + $db = new \PDO('mysql:host=' . + $CONFIG['db']['core']['masters']['admin']['host'], + $CONFIG['db']['core']['masters']['admin']['login'], + $CONFIG['db']['core']['masters']['admin']['password'] + ); + $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['masters']['admin']['database']); + $db->exec('CREATE DATABASE IF NOT EXISTS ' . $CONFIG['db']['core']['masters']['admin']['database']); + $db = null; + } catch (\Throwable $t) { + echo "\nCouldn't connect to MYSQL DB\n"; + } + } + + if (\extension_loaded('pdo_pgsql')) { + try { + $db = new \PDO('pgsql:host=' . + $CONFIG['db']['core']['postgresql']['admin']['host'], + $CONFIG['db']['core']['postgresql']['admin']['login'], + $CONFIG['db']['core']['postgresql']['admin']['password'] + ); + $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['postgresql']['admin']['database']); + $db->exec('CREATE DATABASE ' . $CONFIG['db']['core']['postgresql']['admin']['database']); + $db = null; + } catch (\Throwable $t) { + echo "\nCouldn't connect to POSTGRESQL DB\n"; + } + } + + if (\extension_loaded('pdo_sqlsrv')) { + try { + $db = new \PDO('sqlsrv:Server=' . + $CONFIG['db']['core']['mssql']['admin']['host'], + $CONFIG['db']['core']['mssql']['admin']['login'], + $CONFIG['db']['core']['mssql']['admin']['password'] + ); + $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['mssql']['admin']['database']); + $db->exec('CREATE DATABASE ' . $CONFIG['db']['core']['mssql']['admin']['database']); + $db = null; + } catch (\Throwable $t) { + echo "\nCouldn't connect to MSSQL DB\n"; + } + } +} + +$httpSession = new HttpSession(); +$GLOBALS['session'] = $httpSession; + +$GLOBALS['dbpool'] = new DatabasePool(); +$GLOBALS['dbpool']->create('admin', $CONFIG['db']['core']['masters']['admin']); +$GLOBALS['dbpool']->create('select', $CONFIG['db']['core']['masters']['select']); +$GLOBALS['dbpool']->create('update', $CONFIG['db']['core']['masters']['update']); +$GLOBALS['dbpool']->create('delete', $CONFIG['db']['core']['masters']['delete']); +$GLOBALS['dbpool']->create('insert', $CONFIG['db']['core']['masters']['insert']); +$GLOBALS['dbpool']->create('schema', $CONFIG['db']['core']['masters']['schema']); + +DataMapperFactory::db($GLOBALS['dbpool']->get()); + +$GLOBALS['frameworkpath'] = '/phpOMS/'; + +function phpServe() : void +{ + // OS detection + $isWindows = \stristr(\php_uname('s'), 'Windows') !== false; + + // Command that starts the built-in web server + if ($isWindows) { + $command = \sprintf( + 'wmic process call create "php -S %s:%d -t %s" | find "ProcessId"', + WEB_SERVER_HOST, + WEB_SERVER_PORT, + __DIR__ . '/../' . WEB_SERVER_DOCROOT + ); + + $killCommand = 'taskkill /f /pid '; + } else { + $command = \sprintf( + 'php -S %s:%d -t %s >/dev/null 2>&1 & echo $!', + WEB_SERVER_HOST, + WEB_SERVER_PORT, + WEB_SERVER_DOCROOT + ); + + $killCommand = 'kill '; + } + + // Execute the command and store the process ID + $output = []; + echo \sprintf('Starting server...') . \PHP_EOL; + echo \sprintf(' Current directory: %s', \getcwd()) . \PHP_EOL; + echo \sprintf(' %s', $command); + \exec($command, $output); + + // Get PID + if ($isWindows) { + $pid = \explode('=', $output[0]); + $pid = \str_replace(' ', '', $pid[1]); + $pid = \str_replace(';', '', $pid); + } else { + $pid = (int) $output[0]; + } + + // Log + echo \sprintf( + ' %s - Web server started on %s:%d with PID %d', + \date('r'), + WEB_SERVER_HOST, + WEB_SERVER_PORT, + $pid + ) . \PHP_EOL; + + // Kill the web server when the process ends + \register_shutdown_function(function() use ($killCommand, $pid) : void { + echo \PHP_EOL . \sprintf('Stopping server...') . \PHP_EOL; + echo \sprintf(' %s - Killing process with ID %d', \date('r'), $pid) . \PHP_EOL; + \exec($killCommand . $pid); + }); +} + +\phpServe(); diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php new file mode 100755 index 0000000..6781d04 --- /dev/null +++ b/tests/Controller/ApiControllerTest.php @@ -0,0 +1,88 @@ +app = new class() extends ApplicationAbstract + { + protected string $appName = 'Api'; + }; + + $this->app->dbPool = $GLOBALS['dbpool']; + $this->app->unitId = 1; + $this->app->accountManager = new AccountManager($GLOBALS['session']); + $this->app->appSettings = new CoreSettings(); + $this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../../Modules/'); + $this->app->dispatcher = new Dispatcher($this->app); + $this->app->eventManager = new EventManager($this->app->dispatcher); + $this->app->eventManager->importFromFile(__DIR__ . '/../../../../Web/Api/Hooks.php'); + $this->app->sessionManager = new HttpSession(36000); + + $account = new Account(); + TestUtils::setMember($account, 'id', 1); + + $permission = new AccountPermission(); + $permission->setUnit(1); + $permission->setApp('backend'); + $permission->setPermission( + PermissionType::READ + | PermissionType::CREATE + | PermissionType::MODIFY + | PermissionType::DELETE + | PermissionType::PERMISSION + ); + + $account->addPermission($permission); + + $this->app->accountManager->add($account); + $this->app->router = new WebRouter(); + + $this->module = $this->app->moduleManager->get('FleetManagement'); + + TestUtils::setMember($this->module, 'app', $this->app); + } +} diff --git a/tests/Models/Vehicle.php b/tests/Models/Vehicle.php new file mode 100644 index 0000000..238cce2 --- /dev/null +++ b/tests/Models/Vehicle.php @@ -0,0 +1,20 @@ + + + + + *vendor* + vendor + ../vendor + ../phpOMS + ../phpOMS* + ../phpOMS/* + ../tests* + ../*/tests* + ../**/tests* + */tests* + ../* + ../* + ../* + ../* + ../* + ../**/test* + ../**/Theme* + ../**/Admin/Routes* + ../**/Admin/Hooks* + ../**/Admin/Install* + ../Media/Files* + + + + + + + + + ../Karaka/Install/tests* + + + ../tests* + + + + + volume + maybe + + + + + + + + + + + + + + From 200e3152f48139a0518ced9f4d87e71ce1f861ed Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 27 Jan 2023 22:12:09 +0100 Subject: [PATCH 04/89] phpstan, phpcs, phpunit fixes --- Admin/Installer.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Admin/Installer.php b/Admin/Installer.php index cc9ac9a..2cf1894 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -14,13 +14,7 @@ declare(strict_types=1); namespace Modules\FleetManagement\Admin; -use phpOMS\Application\ApplicationAbstract; -use phpOMS\Config\SettingsInterface; -use phpOMS\Message\Http\HttpRequest; -use phpOMS\Message\Http\HttpResponse; use phpOMS\Module\InstallerAbstract; -use phpOMS\Module\ModuleInfo; -use phpOMS\Uri\HttpUri; /** * Installer class. @@ -39,12 +33,4 @@ final class Installer extends InstallerAbstract * @since 1.0.0 */ public const PATH = __DIR__; - - /** - * {@inheritdoc} - */ - public static function install(ApplicationAbstract $app, ModuleInfo $info, SettingsInterface $cfgHandler) : void - { - parent::install($app, $info, $cfgHandler); - } } From d63c33f4de264210ff1d5febc31a892bbb947a06 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 11 Mar 2023 23:38:18 +0100 Subject: [PATCH 05/89] too many changes --- composer.json | 2 +- info.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 15e8d01..6fc1e5d 100755 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "karaka/module", - "description": "Module for Karaka.", + "description": "Module for Jingga.", "authors": [ { "name": "Dennis Eichhorn", diff --git a/info.json b/info.json index 7d98326..a5aa7bb 100755 --- a/info.json +++ b/info.json @@ -11,7 +11,7 @@ "phpOMS-db": "1.0.0" }, "creator": { - "name": "Karaka", + "name": "Jingga", "website": "jingga.app" }, "description": "The buisness module.", From 6ad0c0c9394bc3dd1e2fe75e8903049db4b44b6f Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 24 Mar 2023 16:20:22 +0100 Subject: [PATCH 06/89] registration fixes --- Admin/Install/Media.php | 4 ++-- Admin/Install/Navigation.install.json | 12 ++++++------ Admin/Install/Navigation.php | 4 ++-- Admin/Installer.php | 4 ++-- Admin/Routes/Web/Backend.php | 2 +- Admin/Status.php | 4 ++-- Admin/Uninstaller.php | 4 ++-- Admin/Updater.php | 4 ++-- Controller/ApiController.php | 4 ++-- Controller/BackendController.php | 4 ++-- Controller/Controller.php | 4 ++-- Models/PermissionCategory.php | 4 ++-- Theme/Backend/Lang/Navigation.ar.lang.php | 2 +- Theme/Backend/Lang/Navigation.cs.lang.php | 2 +- Theme/Backend/Lang/Navigation.da.lang.php | 2 +- Theme/Backend/Lang/Navigation.de.lang.php | 2 +- Theme/Backend/Lang/Navigation.el.lang.php | 2 +- Theme/Backend/Lang/Navigation.en.lang.php | 2 +- Theme/Backend/Lang/Navigation.es.lang.php | 2 +- Theme/Backend/Lang/Navigation.fi.lang.php | 2 +- Theme/Backend/Lang/Navigation.fr.lang.php | 2 +- Theme/Backend/Lang/Navigation.hu.lang.php | 2 +- Theme/Backend/Lang/Navigation.it.lang.php | 2 +- Theme/Backend/Lang/Navigation.ja.lang.php | 2 +- Theme/Backend/Lang/Navigation.ko.lang.php | 2 +- Theme/Backend/Lang/Navigation.no.lang.php | 2 +- Theme/Backend/Lang/Navigation.pl.lang.php | 2 +- Theme/Backend/Lang/Navigation.pt.lang.php | 2 +- Theme/Backend/Lang/Navigation.ru.lang.php | 2 +- Theme/Backend/Lang/Navigation.sv.lang.php | 2 +- Theme/Backend/Lang/Navigation.th.lang.php | 2 +- Theme/Backend/Lang/Navigation.tr.lang.php | 2 +- Theme/Backend/Lang/Navigation.uk.lang.php | 2 +- Theme/Backend/Lang/Navigation.zh.lang.php | 2 +- Theme/Backend/Lang/ar.lang.php | 2 +- Theme/Backend/Lang/cs.lang.php | 2 +- Theme/Backend/Lang/da.lang.php | 2 +- Theme/Backend/Lang/de.lang.php | 2 +- Theme/Backend/Lang/el.lang.php | 2 +- Theme/Backend/Lang/en.lang.php | 2 +- Theme/Backend/Lang/es.lang.php | 2 +- Theme/Backend/Lang/fi.lang.php | 2 +- Theme/Backend/Lang/fr.lang.php | 2 +- Theme/Backend/Lang/hu.lang.php | 2 +- Theme/Backend/Lang/it.lang.php | 2 +- Theme/Backend/Lang/ja.lang.php | 2 +- Theme/Backend/Lang/ko.lang.php | 2 +- Theme/Backend/Lang/no.lang.php | 2 +- Theme/Backend/Lang/pl.lang.php | 2 +- Theme/Backend/Lang/pt.lang.php | 2 +- Theme/Backend/Lang/ru.lang.php | 2 +- Theme/Backend/Lang/sv.lang.php | 2 +- Theme/Backend/Lang/th.lang.php | 2 +- Theme/Backend/Lang/tr.lang.php | 2 +- Theme/Backend/Lang/uk.lang.php | 2 +- Theme/Backend/Lang/zh.lang.php | 2 +- Theme/Backend/vehicle-create.tpl.php | 2 +- Theme/Backend/vehicle-list.tpl.php | 6 +++--- Theme/Backend/vehicle-profile.tpl.php | 8 ++++---- tests/Admin/AdminTest.php | 2 +- tests/Autoloader.php | 4 ++-- tests/Controller/ApiControllerTest.php | 2 +- tests/Models/Vehicle.php | 2 +- 63 files changed, 84 insertions(+), 84 deletions(-) diff --git a/Admin/Install/Media.php b/Admin/Install/Media.php index ee82fd1..006b8a3 100755 --- a/Admin/Install/Media.php +++ b/Admin/Install/Media.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement\Admin\Install * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Application\ApplicationAbstract; * Media class. * * @package Modules\FleetManagement\Admin\Install - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 7e031ca..5842634 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -19,7 +19,7 @@ "type": 2, "subtype": 1, "name": "Vehicles", - "uri": "{/lang}/{/app}/fleet/client/list", + "uri": "{/base}/fleet/client/list", "target": "self", "icon": null, "order": 1, @@ -33,7 +33,7 @@ "type": 3, "subtype": 1, "name": "List", - "uri": "{/lang}/{/app}/fleet/vehicle/list", + "uri": "{/base}/fleet/vehicle/list", "target": "self", "icon": null, "order": 1, @@ -48,7 +48,7 @@ "type": 3, "subtype": 1, "name": "Create", - "uri": "{/lang}/{/app}/fleet/vehicle/create?{?}", + "uri": "{/base}/fleet/vehicle/create?{?}", "target": "self", "icon": null, "order": 1, @@ -65,7 +65,7 @@ "type": 2, "subtype": 1, "name": "Attributes", - "uri": "{/lang}/{/app}/fleet/vehicle/attribute/type/list?{?}", + "uri": "{/base}/fleet/vehicle/attribute/type/list?{?}", "target": "self", "icon": null, "order": 5, @@ -79,7 +79,7 @@ "type": 3, "subtype": 1, "name": "Types", - "uri": "{/lang}/{/app}/fleet/vehicle/attribute/type/list?{?}", + "uri": "{/base}/fleet/vehicle/attribute/type/list?{?}", "target": "self", "icon": null, "order": 15, @@ -94,7 +94,7 @@ "type": 3, "subtype": 1, "name": "Values", - "uri": "{/lang}/{/app}/fleet/vehicle/attribute/value/list?{?}", + "uri": "{/base}/fleet/vehicle/attribute/value/list?{?}", "target": "self", "icon": null, "order": 15, diff --git a/Admin/Install/Navigation.php b/Admin/Install/Navigation.php index bebc194..6886a56 100755 --- a/Admin/Install/Navigation.php +++ b/Admin/Install/Navigation.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement\Admin\Install * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Application\ApplicationAbstract; * Navigation class. * * @package Modules\FleetManagement\Admin\Install - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Admin/Installer.php b/Admin/Installer.php index 2cf1894..b539310 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement\Admin * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Module\InstallerAbstract; * Installer class. * * @package Modules\FleetManagement\Admin - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 71b7f91..dcaf6fb 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -6,7 +6,7 @@ * * @package Modules * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Admin/Status.php b/Admin/Status.php index 7e387fa..d550090 100755 --- a/Admin/Status.php +++ b/Admin/Status.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement\Admin * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Module\StatusAbstract; * Status class. * * @package Modules\FleetManagement\Admin - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Admin/Uninstaller.php b/Admin/Uninstaller.php index 7f377af..3276fba 100755 --- a/Admin/Uninstaller.php +++ b/Admin/Uninstaller.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement\Admin * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Module\UninstallerAbstract; * Uninstaller class. * * @package Modules\FleetManagement\Admin - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Admin/Updater.php b/Admin/Updater.php index ae44b67..e1f5929 100755 --- a/Admin/Updater.php +++ b/Admin/Updater.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement\Admin * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Module\UpdaterAbstract; * Updater class. * * @package Modules\FleetManagement\Admin - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 7c15ebd..a4c5c35 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -18,7 +18,7 @@ namespace Modules\FleetManagement\Controller; * FleetManagement class. * * @package Modules\FleetManagement - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 122903b..37ab768 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -18,7 +18,7 @@ namespace Modules\FleetManagement\Controller; * FleetManagement class. * * @package Modules\FleetManagement - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 * @codeCoverageIgnore diff --git a/Controller/Controller.php b/Controller/Controller.php index f132819..18c63e3 100755 --- a/Controller/Controller.php +++ b/Controller/Controller.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Module\ModuleAbstract; * FleetManagement class. * * @package Modules\FleetManagement - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Models/PermissionCategory.php b/Models/PermissionCategory.php index d26daf2..0dd83ba 100755 --- a/Models/PermissionCategory.php +++ b/Models/PermissionCategory.php @@ -6,7 +6,7 @@ * * @package Modules\FleetManagement\Models * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ use phpOMS\Stdlib\Base\Enum; * Permision state enum. * * @package Modules\FleetManagement\Models - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/Theme/Backend/Lang/Navigation.ar.lang.php b/Theme/Backend/Lang/Navigation.ar.lang.php index 22ea23a..021dcf7 100755 --- a/Theme/Backend/Lang/Navigation.ar.lang.php +++ b/Theme/Backend/Lang/Navigation.ar.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.cs.lang.php b/Theme/Backend/Lang/Navigation.cs.lang.php index b0dc3bd..b911a4b 100755 --- a/Theme/Backend/Lang/Navigation.cs.lang.php +++ b/Theme/Backend/Lang/Navigation.cs.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.da.lang.php b/Theme/Backend/Lang/Navigation.da.lang.php index af6ee4c..08ee7b3 100755 --- a/Theme/Backend/Lang/Navigation.da.lang.php +++ b/Theme/Backend/Lang/Navigation.da.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.de.lang.php b/Theme/Backend/Lang/Navigation.de.lang.php index 532e4ca..738cf54 100755 --- a/Theme/Backend/Lang/Navigation.de.lang.php +++ b/Theme/Backend/Lang/Navigation.de.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.el.lang.php b/Theme/Backend/Lang/Navigation.el.lang.php index 816f3ab..657e381 100755 --- a/Theme/Backend/Lang/Navigation.el.lang.php +++ b/Theme/Backend/Lang/Navigation.el.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index 7e84efb..89165a9 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.es.lang.php b/Theme/Backend/Lang/Navigation.es.lang.php index 50b9f95..e025eed 100755 --- a/Theme/Backend/Lang/Navigation.es.lang.php +++ b/Theme/Backend/Lang/Navigation.es.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.fi.lang.php b/Theme/Backend/Lang/Navigation.fi.lang.php index 1fdb589..96a361a 100755 --- a/Theme/Backend/Lang/Navigation.fi.lang.php +++ b/Theme/Backend/Lang/Navigation.fi.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.fr.lang.php b/Theme/Backend/Lang/Navigation.fr.lang.php index 1674a29..25ce811 100755 --- a/Theme/Backend/Lang/Navigation.fr.lang.php +++ b/Theme/Backend/Lang/Navigation.fr.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.hu.lang.php b/Theme/Backend/Lang/Navigation.hu.lang.php index 9f34a1b..23fc91e 100755 --- a/Theme/Backend/Lang/Navigation.hu.lang.php +++ b/Theme/Backend/Lang/Navigation.hu.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.it.lang.php b/Theme/Backend/Lang/Navigation.it.lang.php index 898dfe1..a021cd4 100755 --- a/Theme/Backend/Lang/Navigation.it.lang.php +++ b/Theme/Backend/Lang/Navigation.it.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.ja.lang.php b/Theme/Backend/Lang/Navigation.ja.lang.php index daf2208..3eef75e 100755 --- a/Theme/Backend/Lang/Navigation.ja.lang.php +++ b/Theme/Backend/Lang/Navigation.ja.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.ko.lang.php b/Theme/Backend/Lang/Navigation.ko.lang.php index e12496b..4873142 100755 --- a/Theme/Backend/Lang/Navigation.ko.lang.php +++ b/Theme/Backend/Lang/Navigation.ko.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.no.lang.php b/Theme/Backend/Lang/Navigation.no.lang.php index f40e6b1..6eed7b1 100755 --- a/Theme/Backend/Lang/Navigation.no.lang.php +++ b/Theme/Backend/Lang/Navigation.no.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.pl.lang.php b/Theme/Backend/Lang/Navigation.pl.lang.php index 0d2ee58..6d2d762 100755 --- a/Theme/Backend/Lang/Navigation.pl.lang.php +++ b/Theme/Backend/Lang/Navigation.pl.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.pt.lang.php b/Theme/Backend/Lang/Navigation.pt.lang.php index 5273a46..e4f1413 100755 --- a/Theme/Backend/Lang/Navigation.pt.lang.php +++ b/Theme/Backend/Lang/Navigation.pt.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.ru.lang.php b/Theme/Backend/Lang/Navigation.ru.lang.php index 7e3210c..e394fe9 100755 --- a/Theme/Backend/Lang/Navigation.ru.lang.php +++ b/Theme/Backend/Lang/Navigation.ru.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.sv.lang.php b/Theme/Backend/Lang/Navigation.sv.lang.php index 7227e7f..2548900 100755 --- a/Theme/Backend/Lang/Navigation.sv.lang.php +++ b/Theme/Backend/Lang/Navigation.sv.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.th.lang.php b/Theme/Backend/Lang/Navigation.th.lang.php index b10f311..326f25e 100755 --- a/Theme/Backend/Lang/Navigation.th.lang.php +++ b/Theme/Backend/Lang/Navigation.th.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.tr.lang.php b/Theme/Backend/Lang/Navigation.tr.lang.php index 9098354..f289b27 100755 --- a/Theme/Backend/Lang/Navigation.tr.lang.php +++ b/Theme/Backend/Lang/Navigation.tr.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.uk.lang.php b/Theme/Backend/Lang/Navigation.uk.lang.php index cad1789..22cc72a 100755 --- a/Theme/Backend/Lang/Navigation.uk.lang.php +++ b/Theme/Backend/Lang/Navigation.uk.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/Navigation.zh.lang.php b/Theme/Backend/Lang/Navigation.zh.lang.php index 25f25df..326a094 100755 --- a/Theme/Backend/Lang/Navigation.zh.lang.php +++ b/Theme/Backend/Lang/Navigation.zh.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/ar.lang.php b/Theme/Backend/Lang/ar.lang.php index 1b73d15..356210a 100755 --- a/Theme/Backend/Lang/ar.lang.php +++ b/Theme/Backend/Lang/ar.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/cs.lang.php b/Theme/Backend/Lang/cs.lang.php index 710f7a5..f5f9e36 100755 --- a/Theme/Backend/Lang/cs.lang.php +++ b/Theme/Backend/Lang/cs.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/da.lang.php b/Theme/Backend/Lang/da.lang.php index f0ecc5e..1029166 100755 --- a/Theme/Backend/Lang/da.lang.php +++ b/Theme/Backend/Lang/da.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php index 40b81f6..d4ca613 100755 --- a/Theme/Backend/Lang/de.lang.php +++ b/Theme/Backend/Lang/de.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/el.lang.php b/Theme/Backend/Lang/el.lang.php index b6ad900..8f651b4 100755 --- a/Theme/Backend/Lang/el.lang.php +++ b/Theme/Backend/Lang/el.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index f77cd26..99b60d7 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/es.lang.php b/Theme/Backend/Lang/es.lang.php index 07f9a57..2ff994d 100755 --- a/Theme/Backend/Lang/es.lang.php +++ b/Theme/Backend/Lang/es.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/fi.lang.php b/Theme/Backend/Lang/fi.lang.php index e39fe21..aeec5c8 100755 --- a/Theme/Backend/Lang/fi.lang.php +++ b/Theme/Backend/Lang/fi.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/fr.lang.php b/Theme/Backend/Lang/fr.lang.php index a254ee8..177f537 100755 --- a/Theme/Backend/Lang/fr.lang.php +++ b/Theme/Backend/Lang/fr.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/hu.lang.php b/Theme/Backend/Lang/hu.lang.php index b170796..820c038 100755 --- a/Theme/Backend/Lang/hu.lang.php +++ b/Theme/Backend/Lang/hu.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/it.lang.php b/Theme/Backend/Lang/it.lang.php index 0af5b07..c8320ee 100755 --- a/Theme/Backend/Lang/it.lang.php +++ b/Theme/Backend/Lang/it.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/ja.lang.php b/Theme/Backend/Lang/ja.lang.php index c4775f3..ea4e8cb 100755 --- a/Theme/Backend/Lang/ja.lang.php +++ b/Theme/Backend/Lang/ja.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/ko.lang.php b/Theme/Backend/Lang/ko.lang.php index 91e7f57..e4c50a9 100755 --- a/Theme/Backend/Lang/ko.lang.php +++ b/Theme/Backend/Lang/ko.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/no.lang.php b/Theme/Backend/Lang/no.lang.php index b007f56..ca6edfa 100755 --- a/Theme/Backend/Lang/no.lang.php +++ b/Theme/Backend/Lang/no.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/pl.lang.php b/Theme/Backend/Lang/pl.lang.php index 9baf170..cca0393 100755 --- a/Theme/Backend/Lang/pl.lang.php +++ b/Theme/Backend/Lang/pl.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/pt.lang.php b/Theme/Backend/Lang/pt.lang.php index 04f60e0..88c9776 100755 --- a/Theme/Backend/Lang/pt.lang.php +++ b/Theme/Backend/Lang/pt.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/ru.lang.php b/Theme/Backend/Lang/ru.lang.php index 8110627..d183f48 100755 --- a/Theme/Backend/Lang/ru.lang.php +++ b/Theme/Backend/Lang/ru.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/sv.lang.php b/Theme/Backend/Lang/sv.lang.php index 63e172f..24b3c59 100755 --- a/Theme/Backend/Lang/sv.lang.php +++ b/Theme/Backend/Lang/sv.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/th.lang.php b/Theme/Backend/Lang/th.lang.php index 37fc31c..71a4354 100755 --- a/Theme/Backend/Lang/th.lang.php +++ b/Theme/Backend/Lang/th.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/tr.lang.php b/Theme/Backend/Lang/tr.lang.php index 7234743..ab9b4ef 100755 --- a/Theme/Backend/Lang/tr.lang.php +++ b/Theme/Backend/Lang/tr.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/uk.lang.php b/Theme/Backend/Lang/uk.lang.php index 1987ecf..c6a3dd0 100755 --- a/Theme/Backend/Lang/uk.lang.php +++ b/Theme/Backend/Lang/uk.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/Lang/zh.lang.php b/Theme/Backend/Lang/zh.lang.php index 063d656..15a37b3 100755 --- a/Theme/Backend/Lang/zh.lang.php +++ b/Theme/Backend/Lang/zh.lang.php @@ -6,7 +6,7 @@ * * @package Modules\Localization * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/vehicle-create.tpl.php b/Theme/Backend/vehicle-create.tpl.php index a49f942..62d4c00 100755 --- a/Theme/Backend/vehicle-create.tpl.php +++ b/Theme/Backend/vehicle-create.tpl.php @@ -6,7 +6,7 @@ * * @package Modules\ClientManagement * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/Theme/Backend/vehicle-list.tpl.php b/Theme/Backend/vehicle-list.tpl.php index f2f8b46..f8205bc 100755 --- a/Theme/Backend/vehicle-list.tpl.php +++ b/Theme/Backend/vehicle-list.tpl.php @@ -7,7 +7,7 @@ * * @package Modules\ClientManagement * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -103,14 +103,14 @@ echo $this->getData('nav')->render(); ?> $value) : ++$count; - $url = UriFactory::build('{/lang}/{/app}/sales/client/profile?{?}&id=' . $value->getId()); + $url = UriFactory::build('{/base}/sales/client/profile?{?}&id=' . $value->getId()); $image = $value->getFileByTypeName('client_profile_image'); ?> <?= $this->getHtml('IMG_alt_client'); ?> + UriFactory::build('{/base}/' . $image->getPath()); ?>"> printHtml($value->number); ?> printHtml($value->profile->account->name1); ?> printHtml($value->profile->account->name2); ?> printHtml($value->mainAddress->city); ?> diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 7356d4e..9feb413 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -6,7 +6,7 @@ * * @package Modules\ClientManagement * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -217,7 +217,7 @@ echo $this->getData('nav')->render(); getHtml('CreatedAt'); ?> getId()); + $url = UriFactory::build('{/base}/editor/single?{?}&id=' . $note->getId()); ?> title; ?> @@ -240,7 +240,7 @@ echo $this->getData('nav')->render(); getHtml('CreatedAt'); ?> getId()); + $url = UriFactory::build('{/base}/media/single?{?}&id=' . $file->getId()); ?> name; ?> @@ -269,7 +269,7 @@ echo $this->getData('nav')->render(); getId()); + $url = UriFactory::build('{/base}/sales/bill?{?}&id=' . $invoice->getId()); ?> getNumber(); ?> diff --git a/tests/Admin/AdminTest.php b/tests/Admin/AdminTest.php index 9e0ebb5..8a2b8d1 100755 --- a/tests/Admin/AdminTest.php +++ b/tests/Admin/AdminTest.php @@ -6,7 +6,7 @@ * * @package tests * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/tests/Autoloader.php b/tests/Autoloader.php index d032623..d08f1b7 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -6,7 +6,7 @@ * * @package Modules/tests * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ @@ -20,7 +20,7 @@ namespace tests; * Autoloader class. * * @package tests - * @license OMS License 1.0 + * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 6781d04..3c9971d 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -6,7 +6,7 @@ * * @package tests * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ diff --git a/tests/Models/Vehicle.php b/tests/Models/Vehicle.php index 238cce2..a79c40f 100644 --- a/tests/Models/Vehicle.php +++ b/tests/Models/Vehicle.php @@ -6,7 +6,7 @@ * * @package Modules\ClientManagement\Models * @copyright Dennis Eichhorn - * @license OMS License 1.0 + * @license OMS License 2.0 * @version 1.0.0 * @link https://jingga.app */ From f9b1cdb31ac0cff87be3a586e22d31880d0007e2 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 25 Mar 2023 22:32:10 +0000 Subject: [PATCH 07/89] perm change --- tests/Models/Vehicle.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tests/Models/Vehicle.php diff --git a/tests/Models/Vehicle.php b/tests/Models/Vehicle.php old mode 100644 new mode 100755 From b615ed84447cf04e6be7a584b3316a41420ee48e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 8 Apr 2023 04:36:26 +0200 Subject: [PATCH 08/89] fix billing process --- .github/user_bug_report.md | 14 ++++++++++---- tests/Controller/ApiControllerTest.php | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/user_bug_report.md b/.github/user_bug_report.md index 9e5f2a5..4b92a8e 100755 --- a/.github/user_bug_report.md +++ b/.github/user_bug_report.md @@ -8,9 +8,11 @@ assignees: '' --- # Bug Description + A clear and concise description of what the bug is. # How to Reproduce + Steps to reproduce the behavior: 1. Go to '...' @@ -19,16 +21,20 @@ Steps to reproduce the behavior: 4. See error # Expected Behavior + A clear and concise description of what you expected to happen. # Screenshots + If applicable, add screenshots to help explain your problem. # System Information - - System: [e.g. PC or iPhone11, ...] - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - KarakaVersion [e.g. 22] + +- System: [e.g. PC or iPhone11, ...] +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- KarakaVersion [e.g. 22] # Additional Information + Add any other context about the problem here. diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 3c9971d..1565a24 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -67,7 +67,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase $permission = new AccountPermission(); $permission->setUnit(1); - $permission->setApp('backend'); + $permission->setApp(2); $permission->setPermission( PermissionType::READ | PermissionType::CREATE From 9f0f7d9228590c2f1f29d64f2078587545b7f4d6 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 11 Apr 2023 00:20:12 +0200 Subject: [PATCH 09/89] fix static analysis --- .github/user_feature_request.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/user_feature_request.md b/.github/user_feature_request.md index 6eb8ddc..c9595e8 100755 --- a/.github/user_feature_request.md +++ b/.github/user_feature_request.md @@ -8,11 +8,14 @@ assignees: '' --- # What is the feature you request + * A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] * A clear and concise description of what you want to happen. # Alternatives + A clear and concise description of any alternative solutions or features you've considered. # Additional Information + Add any other context or screenshots about the feature request here. From 2f0bd06e5095facb42ca9cf6e93bb5f2db1737e0 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 17 Apr 2023 19:44:57 +0200 Subject: [PATCH 10/89] test fixes --- tests/Controller/ApiControllerTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 1565a24..5054ad3 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -23,6 +23,7 @@ use phpOMS\Application\ApplicationAbstract; use phpOMS\DataStorage\Session\HttpSession; use phpOMS\Dispatcher\Dispatcher; use phpOMS\Event\EventManager; +use phpOMS\Localization\L11nManager; use phpOMS\Module\ModuleAbstract; use phpOMS\Module\ModuleManager; use phpOMS\Router\WebRouter; @@ -61,6 +62,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase $this->app->eventManager = new EventManager($this->app->dispatcher); $this->app->eventManager->importFromFile(__DIR__ . '/../../../../Web/Api/Hooks.php'); $this->app->sessionManager = new HttpSession(36000); + $this->app->l11nManager = new L11nManager(); $account = new Account(); TestUtils::setMember($account, 'id', 1); From 5505bc4c6c2cddbfdc163051571623116d666777 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 6 May 2023 11:42:05 +0000 Subject: [PATCH 11/89] make id public, organigram impl. media password/encryption, settings bug fix, Money->FloatInt change, ... --- Theme/Backend/vehicle-list.tpl.php | 8 ++++---- Theme/Backend/vehicle-profile.tpl.php | 6 +++--- tests/Models/Vehicle.php | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Theme/Backend/vehicle-list.tpl.php b/Theme/Backend/vehicle-list.tpl.php index f8205bc..2adf467 100755 --- a/Theme/Backend/vehicle-list.tpl.php +++ b/Theme/Backend/vehicle-list.tpl.php @@ -103,14 +103,14 @@ echo $this->getData('nav')->render(); ?> $value) : ++$count; - $url = UriFactory::build('{/base}/sales/client/profile?{?}&id=' . $value->getId()); + $url = UriFactory::build('{/base}/sales/client/profile?{?}&id=' . $value->id); $image = $value->getFileByTypeName('client_profile_image'); ?> <?= $this->getHtml('IMG_alt_client'); ?> + src="id === 0 ? + UriFactory::build('Web/Backend/img/user_default_' . \mt_rand(1, 6) .'.png') : + UriFactory::build('{/base}/' . $image->getPath()); ?>"> printHtml($value->number); ?> printHtml($value->profile->account->name1); ?> printHtml($value->profile->account->name2); ?> printHtml($value->mainAddress->city); ?> diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 9feb413..ab6a5c0 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -217,7 +217,7 @@ echo $this->getData('nav')->render(); getHtml('CreatedAt'); ?> getId()); + $url = UriFactory::build('{/base}/editor/single?{?}&id=' . $note->id); ?> title; ?> @@ -240,7 +240,7 @@ echo $this->getData('nav')->render(); getHtml('CreatedAt'); ?> getId()); + $url = UriFactory::build('{/base}/media/single?{?}&id=' . $file->id); ?> name; ?> @@ -269,7 +269,7 @@ echo $this->getData('nav')->render(); getId()); + $url = UriFactory::build('{/base}/sales/bill?{?}&id=' . $invoice->id); ?> getNumber(); ?> diff --git a/tests/Models/Vehicle.php b/tests/Models/Vehicle.php index a79c40f..73ac808 100755 --- a/tests/Models/Vehicle.php +++ b/tests/Models/Vehicle.php @@ -16,5 +16,5 @@ namespace Modules\FleetManagement\Models; class Vehicle { - protected int $id = 0; + public int $id = 0; } \ No newline at end of file From 32d786db4cbc274ea8901b7082fbd2df26a4e41e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 19 May 2023 02:37:35 +0000 Subject: [PATCH 12/89] test fixes + new test data --- Admin/Install/Media.install.json | 7 + Admin/Install/Navigation.install.json | 2 +- Admin/Install/attributes.json | 285 +++++ Admin/Install/db.json | 190 +++- Admin/Install/fueltype.json | 135 +++ Admin/Install/vehicletype.json | 135 +++ Admin/Installer.php | 306 ++++++ Admin/Updater.php | 7 + Controller/ApiController.php | 1153 ++++++++++++++++++++ Controller/BackendController.php | 47 + Models/Cost.php | 48 + Models/CostType.php | 48 + Models/FuelType.php | 121 ++ Models/FuelTypeL11nMapper.php | 69 ++ Models/FuelTypeMapper.php | 82 ++ Models/Inspection.php | 0 Models/InspectionMapper_.php | 0 Models/NullFuelType.php | 46 + Models/NullInspection.php | 0 Models/NullVehicle.php | 46 + Models/NullVehicleType.php | 46 + Models/Vehicle.php | 81 ++ Models/VehicleAttributeMapper.php | 86 ++ Models/VehicleAttributeTypeL11nMapper.php | 69 ++ Models/VehicleAttributeTypeMapper.php | 94 ++ Models/VehicleAttributeValueL11nMapper.php | 69 ++ Models/VehicleAttributeValueMapper.php | 89 ++ Models/VehicleMapper.php | 110 ++ Models/VehicleStatus.php | 36 + Models/VehicleType.php | 121 ++ Models/VehicleTypeL11nMapper.php | 69 ++ Models/VehicleTypeMapper.php | 82 ++ Theme/Backend/Lang/Navigation.en.lang.php | 5 +- Theme/Backend/Lang/en.lang.php | 114 +- Theme/Backend/vehicle-list.tpl.php | 42 +- Theme/Backend/vehicle-profile.tpl.php | 624 ++--------- 36 files changed, 3694 insertions(+), 770 deletions(-) create mode 100644 Admin/Install/attributes.json create mode 100644 Admin/Install/fueltype.json create mode 100644 Admin/Install/vehicletype.json create mode 100644 Models/Cost.php create mode 100644 Models/CostType.php create mode 100644 Models/FuelType.php create mode 100644 Models/FuelTypeL11nMapper.php create mode 100644 Models/FuelTypeMapper.php create mode 100644 Models/Inspection.php create mode 100644 Models/InspectionMapper_.php create mode 100644 Models/NullFuelType.php create mode 100644 Models/NullInspection.php create mode 100644 Models/NullVehicle.php create mode 100644 Models/NullVehicleType.php create mode 100644 Models/Vehicle.php create mode 100644 Models/VehicleAttributeMapper.php create mode 100644 Models/VehicleAttributeTypeL11nMapper.php create mode 100644 Models/VehicleAttributeTypeMapper.php create mode 100644 Models/VehicleAttributeValueL11nMapper.php create mode 100644 Models/VehicleAttributeValueMapper.php create mode 100644 Models/VehicleMapper.php create mode 100644 Models/VehicleStatus.php create mode 100644 Models/VehicleType.php create mode 100644 Models/VehicleTypeL11nMapper.php create mode 100644 Models/VehicleTypeMapper.php diff --git a/Admin/Install/Media.install.json b/Admin/Install/Media.install.json index 672b5b8..58397fa 100755 --- a/Admin/Install/Media.install.json +++ b/Admin/Install/Media.install.json @@ -5,5 +5,12 @@ "name": "FleetManagement", "virtualPath": "/Modules", "user": 1 + }, + { + "type": "collection", + "create_directory": true, + "name": "Vehicle", + "virtualPath": "/Modules/FleetManagement", + "user": 1 } ] \ No newline at end of file diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 5842634..b41258b 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -19,7 +19,7 @@ "type": 2, "subtype": 1, "name": "Vehicles", - "uri": "{/base}/fleet/client/list", + "uri": "{/base}/fleet/vehicle/list", "target": "self", "icon": null, "order": 1, diff --git a/Admin/Install/attributes.json b/Admin/Install/attributes.json new file mode 100644 index 0000000..dec23c1 --- /dev/null +++ b/Admin/Install/attributes.json @@ -0,0 +1,285 @@ +[ + { + "name": "license_plate", + "l11n": { + "en": "License plate", + "de": "Kennzeichen" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "insurance_provider", + "l11n": { + "en": "Insurance provider", + "de": "Versicherung" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "insurance_number", + "l11n": { + "en": "Insurance number", + "de": "Versicherungsnummer" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "leasing_provider", + "l11n": { + "en": "Leasing provider", + "de": "Leasingsnummer" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "leasing_number", + "l11n": { + "en": "Leasing number", + "de": "Leasingsnummer" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "leasing_end", + "l11n": { + "en": "Leasing end", + "de": "Leasingende" + }, + "value_type": 4, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "leasing_milage", + "l11n": { + "en": "Leasing milage", + "de": "Laufleistung" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "insurance_milage", + "l11n": { + "en": "Insurance milage", + "de": "Versicherungslaufleistung" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "engine_size", + "l11n": { + "en": "Engine size", + "de": "Hubraum" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "vin", + "l11n": { + "en": "VIN", + "de": "Fahrgestellnummer" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "make", + "l11n": { + "en": "Make", + "de": "Marke" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "model", + "l11n": { + "en": "Model", + "de": "Modell" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "color", + "l11n": { + "en": "Color", + "de": "Farbe" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "build", + "l11n": { + "en": "Build year", + "de": "Baujahr" + }, + "value_type": 4, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "ownership_start", + "l11n": { + "en": "Ownership start", + "de": "Besitzbeginn" + }, + "value_type": 4, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "ownership_end", + "l11n": { + "en": "Ownership end", + "de": "Besitzende" + }, + "value_type": 4, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "fuel_type", + "l11n": { + "en": "Fuel type", + "de": "Kraftstoffart" + }, + "value_type": 1, + "is_custom_allowed": false, + "validation_pattern": "", + "is_required": true, + "default_value": "", + "values": [ + { + "value": 1, + "l11n": { + "en": "None", + "de": "Kein" + } + }, + { + "value": 2, + "l11n": { + "en": "Gas", + "de": "Benzin" + } + }, + { + "value": 3, + "l11n": { + "en": "Diesel", + "de": "Diesel" + } + }, + { + "value": 4, + "l11n": { + "en": "Electric", + "de": "Elektro" + } + }, + { + "value": 5, + "l11n": { + "en": "Hydrogen", + "de": "Wasserstoff" + } + } + ] + }, + { + "name": "purchase_price", + "l11n": { + "en": "Purchase price", + "de": "Kaufpreis" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "leasing_residual_value", + "l11n": { + "en": "Leasing residual value", + "de": "Leasing Restwert" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + } +] \ No newline at end of file diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 651ca07..ddda20c 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -1,4 +1,100 @@ { + "fleetmgmt_fuel_type": { + "name": "fleetmgmt_fuel_type", + "fields": { + "fleetmgmt_fuel_type_id": { + "name": "fleetmgmt_fuel_type_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_fuel_type_name": { + "name": "fleetmgmt_fuel_type_name", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "fleetmgmt_fuel_type_l11n": { + "name": "fleetmgmt_fuel_type_l11n", + "fields": { + "fleetmgmt_fuel_type_l11n_id": { + "name": "fleetmgmt_fuel_type_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_fuel_type_l11n_title": { + "name": "fleetmgmt_fuel_type_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_fuel_type_l11n_type": { + "name": "fleetmgmt_fuel_type_l11n_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_fuel_type", + "foreignKey": "fleetmgmt_fuel_type_id" + }, + "fleetmgmt_fuel_type_l11n_lang": { + "name": "fleetmgmt_fuel_type_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, + "fleetmgmt_vehicle_type": { + "name": "fleetmgmt_vehicle_type", + "fields": { + "fleetmgmt_vehicle_type_id": { + "name": "fleetmgmt_vehicle_type_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_type_name": { + "name": "fleetmgmt_vehicle_type_name", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "fleetmgmt_vehicle_type_l11n": { + "name": "fleetmgmt_vehicle_type_l11n", + "fields": { + "fleetmgmt_vehicle_type_l11n_id": { + "name": "fleetmgmt_vehicle_type_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_type_l11n_title": { + "name": "fleetmgmt_vehicle_type_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_vehicle_type_l11n_type": { + "name": "fleetmgmt_vehicle_type_l11n_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_vehicle_type", + "foreignKey": "fleetmgmt_vehicle_type_id" + }, + "fleetmgmt_vehicle_type_l11n_lang": { + "name": "fleetmgmt_vehicle_type_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, "fleetmgmt_vehicle": { "name": "fleetmgmt_vehicle", "fields": { @@ -9,6 +105,11 @@ "primary": true, "autoincrement": true }, + "fleetmgmt_vehicle_name": { + "name": "fleetmgmt_vehicle_name", + "type": "VARCHAR(255)", + "null": false + }, "fleetmgmt_vehicle_status": { "name": "fleetmgmt_vehicle_status", "type": "TINYINT", @@ -16,8 +117,15 @@ }, "fleetmgmt_vehicle_type": { "name": "fleetmgmt_vehicle_type", - "type": "TINYINT", - "null": false + "type": "INT", + "foreignTable": "fleetmgmt_vehicle_type", + "foreignKey": "fleetmgmt_vehicle_type_id" + }, + "fleetmgmt_vehicle_fuel": { + "name": "fleetmgmt_vehicle_fuel", + "type": "INT", + "foreignTable": "fleetmgmt_fuel_type", + "foreignKey": "fleetmgmt_fuel_type_id" }, "fleetmgmt_vehicle_info": { "name": "fleetmgmt_vehicle_info", @@ -32,7 +140,8 @@ "fleetmgmt_vehicle_responsible": { "name": "fleetmgmt_vehicle_responsible", "type": "INT", - "null": false, + "null": true, + "default": true, "foreignTable": "account", "foreignKey": "account_id" }, @@ -46,41 +155,6 @@ } } }, - "fleetmgmt_vehicle_responsible": { - "name": "fleetmgmt_vehicle_responsible", - "fields": { - "fleetmgmt_vehicle_responsible_id": { - "name": "fleetmgmt_vehicle_responsible_id", - "type": "INT", - "null": false, - "primary": true, - "autoincrement": true - }, - "fleetmgmt_vehicle_responsible_description": { - "name": "fleetmgmt_vehicle_responsible_description", - "type": "TEXT", - "null": false - }, - "fleetmgmt_vehicle_responsible_account": { - "name": "fleetmgmt_vehicle_responsible_account", - "type": "INT", - "null": false, - "foreignTable": "account", - "foreignKey": "account_id" - }, - "fleetmgmt_vehicle_responsible_start": { - "name": "fleetmgmt_vehicle_responsible_start", - "type": "DATETIME", - "null": false - }, - "fleetmgmt_vehicle_responsible_end": { - "name": "fleetmgmt_vehicle_responsible_end", - "type": "DATETIME", - "null": true, - "default": null - } - } - }, "fleetmgmt_vehicle_usage": { "name": "fleetmgmt_vehicle_usage", "fields": { @@ -326,8 +400,8 @@ "primary": true, "autoincrement": true }, - "fleetmgmt_vehicle_attr_vehicle": { - "name": "fleetmgmt_vehicle_attr_vehicle", + "fleetmgmt_vehicle_attr_item": { + "name": "fleetmgmt_vehicle_attr_item", "type": "INT(11)", "null": false, "foreignTable": "fleetmgmt_vehicle", @@ -360,19 +434,19 @@ "primary": true, "autoincrement": true }, - "fleetmgmt_vehicle_media_dst": { - "name": "fleetmgmt_vehicle_media_dst", - "type": "INT", - "null": false, - "foreignTable": "media", - "foreignKey": "media_id" - }, - "fleetmgmt_vehicle_media_src": { - "name": "fleetmgmt_vehicle_media_src", + "fleetmgmt_vehicle_media_vehicle": { + "name": "fleetmgmt_vehicle_media_vehicle", "type": "INT", "null": false, "foreignTable": "fleetmgmt_vehicle", "foreignKey": "fleetmgmt_vehicle_id" + }, + "fleetmgmt_vehicle_media_media": { + "name": "fleetmgmt_vehicle_media_media", + "type": "INT", + "null": false, + "foreignTable": "media", + "foreignKey": "media_id" } } }, @@ -386,19 +460,19 @@ "primary": true, "autoincrement": true }, - "fleetmgmt_vehicle_note_dst": { - "name": "fleetmgmt_vehicle_note_dst", - "type": "INT", - "null": false, - "foreignTable": "editor_doc", - "foreignKey": "editor_doc_id" - }, - "fleetmgmt_vehicle_note_src": { - "name": "fleetmgmt_vehicle_note_src", + "fleetmgmt_vehicle_note_item": { + "name": "fleetmgmt_vehicle_note_item", "type": "INT", "null": false, "foreignTable": "fleetmgmt_vehicle", "foreignKey": "fleetmgmt_vehicle_id" + }, + "fleetmgmt_vehicle_note_doc": { + "name": "fleetmgmt_vehicle_note_doc", + "type": "INT", + "null": false, + "foreignTable": "editor_doc", + "foreignKey": "editor_doc_id" } } } diff --git a/Admin/Install/fueltype.json b/Admin/Install/fueltype.json new file mode 100644 index 0000000..76747be --- /dev/null +++ b/Admin/Install/fueltype.json @@ -0,0 +1,135 @@ +[ + { + "name": "gasoline", + "l11n": { + "en": "Gasoline", + "de": "Benzin" + } + }, + { + "name": "diesel", + "l11n": { + "en": "Diesel", + "de": "Diesel" + } + }, + { + "name": "electirc", + "l11n": { + "en": "Electric", + "de": "Elektrisch" + } + }, + { + "name": "hydrogen", + "l11n": { + "en": "Hydrogen", + "de": "Wasserstoff" + } + }, + { + "name": "ethanol", + "l11n": { + "en": "Ethanol", + "de": "Ethanol" + } + }, + { + "name": "kerosene", + "l11n": { + "en": "Kerosene", + "de": "Kerosin" + } + }, + { + "name": "lpg", + "l11n": { + "en": "LPG", + "de": "Autogas" + } + }, + { + "name": "methanol", + "l11n": { + "en": "Methanol", + "de": "Methanol" + } + }, + { + "name": "methane", + "l11n": { + "en": "Methane", + "de": "Methan" + } + }, + { + "name": "nitromethane", + "l11n": { + "en": "Nitromethane", + "de": "Nitromethan" + } + }, + { + "name": "coal", + "l11n": { + "en": "Coal", + "de": "Kohle" + } + }, + { + "name": "wood", + "l11n": { + "en": "Wood", + "de": "Holz" + } + }, + { + "name": "petroleum", + "l11n": { + "en": "Petroleum", + "de": "Petroleum" + } + }, + { + "name": "coaltar", + "l11n": { + "en": "Coaltar", + "de": "Steinkohlenteer" + } + }, + { + "name": "coke", + "l11n": { + "en": "Coke", + "de": "Koks" + } + }, + { + "name": "charcoale", + "l11n": { + "en": "Charcoale", + "de": "Holzkohle" + } + }, + { + "name": "naturalgas", + "l11n": { + "en": "Naturalgas", + "de": "Erdgas" + } + }, + { + "name": "biogas", + "l11n": { + "en": "Biogas", + "de": "Biogas" + } + }, + { + "name": "biodiesel", + "l11n": { + "en": "Biodiesel", + "de": "Biodiesel" + } + } +] \ No newline at end of file diff --git a/Admin/Install/vehicletype.json b/Admin/Install/vehicletype.json new file mode 100644 index 0000000..f5485e0 --- /dev/null +++ b/Admin/Install/vehicletype.json @@ -0,0 +1,135 @@ +[ + { + "name": "car", + "l11n": { + "en": "Car", + "de": "Auto" + } + }, + { + "name": "truck", + "l11n": { + "en": "Truck", + "de": "LKW" + } + }, + { + "name": "motorcycle", + "l11n": { + "en": "Motorcycle", + "de": "Motorrad" + } + }, + { + "name": "bicycle", + "l11n": { + "en": "Bicycle", + "de": "Fahrrad" + } + }, + { + "name": "bus", + "l11n": { + "en": "Bus", + "de": "Bus" + } + }, + { + "name": "boat", + "l11n": { + "en": "Boat", + "de": "Boot" + } + }, + { + "name": "airplane", + "l11n": { + "en": "Airplane", + "de": "Flugzeug" + } + }, + { + "name": "helicopter", + "l11n": { + "en": "Helicopter", + "de": "Hubschrauber" + } + }, + { + "name": "train", + "l11n": { + "en": "Train", + "de": "Zug" + } + }, + { + "name": "scooter", + "l11n": { + "en": "Scooter", + "de": "Roller" + } + }, + { + "name": "moped", + "l11n": { + "en": "Moped", + "de": "Moped" + } + }, + { + "name": "RV", + "l11n": { + "en": "Recreational Vehicle", + "de": "Wohnmobil" + } + }, + { + "name": "tractor", + "l11n": { + "en": "Tractor", + "de": "Traktor" + } + }, + { + "name": "forklift", + "l11n": { + "en": "Forklift", + "de": "Gabelstapler" + } + }, + { + "name": "skateboard", + "l11n": { + "en": "Skateboard", + "de": "Skateboard" + } + }, + { + "name": "snowmobile", + "l11n": { + "en": "Snowmobile", + "de": "Schneemobil" + } + }, + { + "name": "jet_ski", + "l11n": { + "en": "Jet Ski", + "de": "Jet Ski" + } + }, + { + "name": "quad_bike", + "l11n": { + "en": "Quad Bike", + "de": "Quad Bike" + } + }, + { + "name": "golf_cart", + "l11n": { + "en": "Golf Cart", + "de": "Golf Cart" + } + } +] diff --git a/Admin/Installer.php b/Admin/Installer.php index b539310..7529423 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -14,7 +14,13 @@ declare(strict_types=1); namespace Modules\FleetManagement\Admin; +use phpOMS\Application\ApplicationAbstract; +use phpOMS\Config\SettingsInterface; +use phpOMS\Message\Http\HttpRequest; +use phpOMS\Message\Http\HttpResponse; use phpOMS\Module\InstallerAbstract; +use phpOMS\Module\ModuleInfo; +use phpOMS\Uri\HttpUri; /** * Installer class. @@ -33,4 +39,304 @@ final class Installer extends InstallerAbstract * @since 1.0.0 */ public const PATH = __DIR__; + + /** + * {@inheritdoc} + */ + public static function install(ApplicationAbstract $app, ModuleInfo $info, SettingsInterface $cfgHandler) : void + { + parent::install($app, $info, $cfgHandler); + + /* Attributes */ + $fileContent = \file_get_contents(__DIR__ . '/Install/attributes.json'); + if ($fileContent === false) { + return; + } + + /** @var array $attributes */ + $attributes = \json_decode($fileContent, true); + $attrTypes = self::createAttributeTypes($app, $attributes); + $attrValues = self::createAttributeValues($app, $attrTypes, $attributes); + + /* Fuel types */ + $fileContent = \file_get_contents(__DIR__ . '/Install/fueltype.json'); + if ($fileContent === false) { + return; + } + + /** @var array $types */ + $types = \json_decode($fileContent, true); + $fuelTypes = self::createFuelTypes($app, $types); + + /* Fuel types */ + $fileContent = \file_get_contents(__DIR__ . '/Install/vehicletype.json'); + if ($fileContent === false) { + return; + } + + /** @var array $types */ + $types = \json_decode($fileContent, true); + $vehicleTypes = self::createVehicleTypes($app, $types); + } + + /** + * Install fuel type + * + * @param ApplicationAbstract $app Application + * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createFuelTypes(ApplicationAbstract $app, array $types) : array + { + /** @var array $fuelTypes */ + $fuelTypes = []; + + /** @var \Modules\FleetManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement'); + + /** @var array $type */ + foreach ($types as $type) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('name', $type['name'] ?? ''); + $request->setData('title', \reset($type['l11n'])); + $request->setData('language', \array_keys($type['l11n'])[0] ?? 'en'); + + $module->apiFuelTypeCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $fuelTypes[$type['name']] = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $isFirst = true; + foreach ($type['l11n'] as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('type', $fuelTypes[$type['name']]['id']); + + $module->apiFuelTypeL11nCreate($request, $response); + } + } + + return $fuelTypes; + } + + /** + * Install fuel type + * + * @param ApplicationAbstract $app Application + * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createVehicleTypes(ApplicationAbstract $app, array $types) : array + { + /** @var array $fuelTypes */ + $vehicleTypes = []; + + /** @var \Modules\FleetManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement'); + + /** @var array $type */ + foreach ($types as $type) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('name', $type['name'] ?? ''); + $request->setData('title', \reset($type['l11n'])); + $request->setData('language', \array_keys($type['l11n'])[0] ?? 'en'); + + $module->apiVehicleTypeCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $vehicleTypes[$type['name']] = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $isFirst = true; + foreach ($type['l11n'] as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('type', $vehicleTypes[$type['name']]['id']); + + $module->apiVehicleTypeL11nCreate($request, $response); + } + } + + return $vehicleTypes; + } + + /** + * Install default attribute types + * + * @param ApplicationAbstract $app Application + * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createAttributeTypes(ApplicationAbstract $app, array $attributes) : array + { + /** @var array $itemAttrType */ + $itemAttrType = []; + + /** @var \Modules\FleetManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement'); + + /** @var array $attribute */ + foreach ($attributes as $attribute) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('name', $attribute['name'] ?? ''); + $request->setData('title', \reset($attribute['l11n'])); + $request->setData('language', \array_keys($attribute['l11n'])[0] ?? 'en'); + $request->setData('is_required', $attribute['is_required'] ?? false); + $request->setData('custom', $attribute['is_custom_allowed'] ?? false); + $request->setData('validation_pattern', $attribute['validation_pattern'] ?? ''); + $request->setData('datatype', (int) $attribute['value_type']); + + $module->apiVehicleAttributeTypeCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $itemAttrType[$attribute['name']] = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $isFirst = true; + foreach ($attribute['l11n'] as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('type', $itemAttrType[$attribute['name']]['id']); + + $module->apiVehicleAttributeTypeL11nCreate($request, $response); + } + } + + return $itemAttrType; + } + + /** + * Create default attribute values for types + * + * @param ApplicationAbstract $app Application + * @param array $itemAttrType Attribute types + * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createAttributeValues(ApplicationAbstract $app, array $itemAttrType, array $attributes) : array + { + /** @var array $itemAttrValue */ + $itemAttrValue = []; + + /** @var \Modules\FleetManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement'); + + foreach ($attributes as $attribute) { + $itemAttrValue[$attribute['name']] = []; + + /** @var array $value */ + foreach ($attribute['values'] as $value) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('value', $value['value'] ?? ''); + $request->setData('unit', $value['unit'] ?? ''); + $request->setData('default', true); // always true since all defined values are possible default values + $request->setData('type', $itemAttrType[$attribute['name']]['id']); + + if (isset($value['l11n']) && !empty($value['l11n'])) { + $request->setData('title', \reset($value['l11n'])); + $request->setData('language', \array_keys($value['l11n'])[0] ?? 'en'); + } + + $module->apiVehicleAttributeValueCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $attrValue = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $itemAttrValue[$attribute['name']][] = $attrValue; + + $isFirst = true; + foreach (($value['l11n'] ?? []) as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('value', $attrValue['id']); + + $module->apiVehicleAttributeValueL11nCreate($request, $response); + } + } + } + + return $itemAttrValue; + } } diff --git a/Admin/Updater.php b/Admin/Updater.php index e1f5929..5d0debb 100755 --- a/Admin/Updater.php +++ b/Admin/Updater.php @@ -26,4 +26,11 @@ use phpOMS\Module\UpdaterAbstract; */ final class Updater extends UpdaterAbstract { + /** + * Path of the file + * + * @var string + * @since 1.0.0 + */ + public const PATH = __DIR__; } diff --git a/Controller/ApiController.php b/Controller/ApiController.php index a4c5c35..9cebf70 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -14,6 +14,41 @@ declare(strict_types=1); namespace Modules\FleetManagement\Controller; +use Modules\Admin\Models\NullAccount; +use Modules\Attribute\Models\Attribute; +use Modules\Attribute\Models\AttributeType; +use Modules\Attribute\Models\AttributeValue; +use Modules\Attribute\Models\NullAttributeType; +use Modules\Attribute\Models\NullAttributeValue; +use Modules\FleetManagement\Models\FuelType; +use Modules\FleetManagement\Models\FuelTypeL11nMapper; +use Modules\FleetManagement\Models\FuelTypeMapper; +use Modules\FleetManagement\Models\NullFuelType; +use Modules\FleetManagement\Models\NullVehicleType; +use Modules\FleetManagement\Models\Vehicle; +use Modules\FleetManagement\Models\VehicleAttributeMapper; +use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; +use Modules\FleetManagement\Models\VehicleAttributeTypeMapper; +use Modules\FleetManagement\Models\VehicleAttributeValueL11nMapper; +use Modules\FleetManagement\Models\VehicleAttributeValueMapper; +use Modules\FleetManagement\Models\VehicleMapper; +use Modules\FleetManagement\Models\VehicleStatus; +use Modules\FleetManagement\Models\VehicleType; +use Modules\FleetManagement\Models\VehicleTypeL11nMapper; +use Modules\FleetManagement\Models\VehicleTypeMapper; +use Modules\Media\Models\CollectionMapper; +use Modules\Media\Models\MediaMapper; +use Modules\Media\Models\NullMedia; +use Modules\Media\Models\PathSettings; +use Modules\Media\Models\Reference; +use phpOMS\Localization\BaseStringL11n; +use phpOMS\Localization\ISO639x1Enum; +use phpOMS\Message\Http\RequestStatusCode; +use phpOMS\Message\NotificationLevel; +use phpOMS\Message\RequestAbstract; +use phpOMS\Message\ResponseAbstract; +use phpOMS\Model\Message\FormValidation; + /** * FleetManagement class. * @@ -24,5 +59,1123 @@ namespace Modules\FleetManagement\Controller; */ final class ApiController extends Controller { + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleTypeCreate($request))) { + $response->set($request->uri->__toString(), new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + return; + } + + /** @var VehicleType $vehicle */ + $vehicle = $this->createVehicleTypeFromRequest($request); + $this->createModel($request->header->account, $vehicle, VehicleTypeMapper::class, 'vehicle_type', $request->getOrigin()); + + $this->fillJsonResponse( + $request, + $response, + NotificationLevel::OK, + '', + $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $vehicle + ); + } + + /** + * Method to create vehicle from request. + * + * @param RequestAbstract $request Request + * + * @return VehicleType Returns the created vehicle from the request + * + * @since 1.0.0 + */ + public function createVehicleTypeFromRequest(RequestAbstract $request) : VehicleType + { + $type = new VehicleType(); + $type->name = $request->getDataString('name') ?? ''; + $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + + return $type; + } + + /** + * Validate vehicle create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateVehicleTypeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['name'] = !$request->hasData('name')) + || ($val['title'] = !$request->hasData('title')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleTypeL11nCreate($request))) { + $response->set('vehicle_type_l11n_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $typeL11n = $this->createVehicleTypeL11nFromRequest($request); + $this->createModel($request->header->account, $typeL11n, VehicleTypeL11nMapper::class, 'vehicle_type_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + } + + /** + * Method to create vehicle attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createVehicleTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $typeL11n = new BaseStringL11n(); + $typeL11n->ref = $request->getDataInt('type') ?? 0; + $typeL11n->setLanguage( + $request->getDataString('language') ?? $request->getLanguage() + ); + $typeL11n->content = $request->getDataString('title') ?? ''; + + return $typeL11n; + } + + /** + * Validate vehicle attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleTypeL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['type'] = !$request->hasData('type')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiFuelTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateFuelTypeCreate($request))) { + $response->set($request->uri->__toString(), new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var FuelType $vehicle */ + $vehicle = $this->createFuelTypeFromRequest($request); + $this->createModel($request->header->account, $vehicle, FuelTypeMapper::class, 'fuel_type', $request->getOrigin()); + + $this->fillJsonResponse( + $request, + $response, + NotificationLevel::OK, + '', + $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $vehicle + ); + } + + /** + * Method to create vehicle from request. + * + * @param RequestAbstract $request Request + * + * @return FuelType Returns the created vehicle from the request + * + * @since 1.0.0 + */ + public function createFuelTypeFromRequest(RequestAbstract $request) : FuelType + { + $type = new FuelType(); + $type->name = $request->getDataString('name') ?? ''; + $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + + return $type; + } + + /** + * Validate vehicle create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateFuelTypeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['name'] = !$request->hasData('name')) + || ($val['title'] = !$request->hasData('title')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiFuelTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateFuelTypeL11nCreate($request))) { + $response->set('fuel_type_l11n_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $typeL11n = $this->createFuelTypeL11nFromRequest($request); + $this->createModel($request->header->account, $typeL11n, FuelTypeL11nMapper::class, 'fuel_type_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + } + + /** + * Method to create vehicle attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createFuelTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $typeL11n = new BaseStringL11n(); + $typeL11n->ref = $request->getDataInt('type') ?? 0; + $typeL11n->setLanguage( + $request->getDataString('language') ?? $request->getLanguage() + ); + $typeL11n->content = $request->getDataString('title') ?? ''; + + return $typeL11n; + } + + /** + * Validate vehicle attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateFuelTypeL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['type'] = !$request->hasData('type')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleCreate($request))) { + $response->set($request->uri->__toString(), new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var Vehicle $vehicle */ + $vehicle = $this->createVehicleFromRequest($request); + $this->createModel($request->header->account, $vehicle, VehicleMapper::class, 'vehicle', $request->getOrigin()); + + if (!empty($request->getFiles()) + || !empty($request->getDataJson('media')) + ) { + $this->createVehicleMedia($vehicle, $request); + } + + $this->fillJsonResponse( + $request, + $response, + NotificationLevel::OK, + '', + $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $vehicle + ); + } + + /** + * Method to create vehicle from request. + * + * @param RequestAbstract $request Request + * + * @return Vehicle Returns the created vehicle from the request + * + * @since 1.0.0 + */ + public function createVehicleFromRequest(RequestAbstract $request) : Vehicle + { + $vehicle = new Vehicle(); + $vehicle->name = $request->getDataString('name') ?? ''; + $vehicle->info = $request->getDataString('info') ?? ''; + $vehicle->type = new NullVehicleType((int) ($request->getDataInt('type') ?? 0)); + $vehicle->fuelType = new NullFuelType((int) ($request->getDataInt('fuel') ?? 0)); + $vehicle->status = (int) ($request->getDataInt('status') ?? VehicleStatus::INACTIVE); + $vehicle->unit = $request->getDataInt('unit') ?? $this->app->unitId; + + return $vehicle; + } + + /** + * Create media files for vehicle + * + * @param Vehicle $vehicle Vehicle + * @param RequestAbstract $request Request incl. media do upload + * + * @return void + * + * @since 1.0.0 + */ + private function createVehicleMedia(Vehicle $vehicle, RequestAbstract $request) : void + { + $path = $this->createVehicleDir($vehicle); + + if (!empty($uploadedFiles = $request->getFiles())) { + $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( + names: [], + fileNames: [], + files: $uploadedFiles, + account: $request->header->account, + basePath: __DIR__ . '/../../../Modules/Media/Files' . $path, + virtualPath: $path, + pathSettings: PathSettings::FILE_PATH + ); + + $collection = null; + foreach ($uploaded as $media) { + $this->createModelRelation( + $request->header->account, + $vehicle->id, + $media->id, + VehicleMapper::class, + 'media', + '', + $request->getOrigin() + ); + + if ($collection === null) { + /** @var \Modules\Media\Models\Media $media */ + $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); + + if ($collection->id === 0) { + $collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection( + $path, + $request->header->account, + __DIR__ . '/../../../Modules/Media/Files' . $path + ); + } + } + + $this->createModelRelation( + $request->header->account, + $collection->id, + $media->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + } + } + + if (!empty($mediaFiles = $request->getDataJson('media'))) { + $collection = null; + + foreach ($mediaFiles as $file) { + /** @var \Modules\Media\Models\Media $media */ + $media = MediaMapper::get()->where('id', (int) $file)->limit(1)->execute(); + + $this->createModelRelation( + $request->header->account, + $vehicle->id, + $media->id, + VehicleMapper::class, + 'media', + '', + $request->getOrigin() + ); + + $ref = new Reference(); + $ref->name = $media->name; + $ref->source = new NullMedia($media->id); + $ref->createdBy = new NullAccount($request->header->account); + $ref->setVirtualPath($path); + + $this->createModel($request->header->account, $ref, ReferenceMapper::class, 'media_reference', $request->getOrigin()); + + if ($collection === null) { + /** @var \Modules\Media\Models\Media $media */ + $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); + + if ($collection->id === 0) { + $collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection( + $path, + $request->header->account, + __DIR__ . '/../../../Modules/Media/Files' . $path + ); + } + } + + $this->createModelRelation( + $request->header->account, + $collection->id, + $ref->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + } + } + } + + /** + * Validate vehicle create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateVehicleCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['name'] = !$request->hasData('name'))) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeCreate($request))) { + $response->set('attribute_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attribute = $this->createVehicleAttributeFromRequest($request); + $this->createModel($request->header->account, $attribute, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully created', $attribute); + } + + /** + * Method to create vehicle attribute from request. + * + * @param RequestAbstract $request Request + * + * @return Attribute + * + * @since 1.0.0 + */ + private function createVehicleAttributeFromRequest(RequestAbstract $request) : Attribute + { + $attribute = new Attribute(); + $attribute->ref = (int) $request->getData('vehicle'); + $attribute->type = new NullAttributeType((int) $request->getData('type')); + + if ($request->hasData('value')) { + $attribute->value = new NullAttributeValue((int) $request->getData('value')); + } else { + $newRequest = clone $request; + $newRequest->setData('value', $request->getData('custom'), true); + + $value = $this->createAttributeValueFromRequest($newRequest); + + $attribute->value = $value; + } + + return $attribute; + } + + /** + * Validate vehicle attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['type'] = !$request->hasData('type')) + || ($val['value'] = (!$request->hasData('value') && !$request->hasData('custom'))) + || ($val['vehicle'] = !$request->hasData('vehicle')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeUpdate($request))) { + $response->set('attribute_update', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $old = VehicleAttributeMapper::get() + ->with('type') + ->with('type/defaults') + ->with('value') + ->where('id', (int) $request->getData('id')) + ->execute(); + + $new = $this->updateVehicleAttributeFromRequest($request, $old->deepClone()); + $this->updateModel($request->header->account, $old, $new, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); + + if ($new->value->getValue() !== $old->value->getValue()) { + $this->updateModel($request->header->account, $old->value, $new->value, VehicleAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully updated', $new); + } + + /** + * Method to create vehicle attribute from request. + * + * @param RequestAbstract $request Request + * + * @return Attribute + * + * @since 1.0.0 + */ + private function updateVehicleAttributeFromRequest(RequestAbstract $request, Attribute $attribute) : Attribute + { + if ($attribute->type->custom) { + if ($request->hasData('value')) { + // @question: we are overwriting the old value, could there be a use case where we want to create a new value and keep the old one? + $attribute->value->setValue($request->getData('value'), $attribute->type->datatype); + } + } else { + if ($request->hasData('value')) { + // @todo: fix by only accepting the value id to be used + // this is a workaround for now because the front end doesn't allow to dynamically show default values. + $value = $attribute->type->getDefaultByValue($request->getData('value')); + + if ($value->id !== 0) { + $attribute->value = $attribute->type->getDefaultByValue($request->getData('value')); + } + } + } + + return $attribute; + } + + /** + * Validate vehicle attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeTypeL11nCreate($request))) { + $response->set('attr_type_l11n_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createVehicleAttributeTypeL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, VehicleAttributeTypeL11nMapper::class, 'attr_type_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } + + /** + * Method to create vehicle attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createVehicleAttributeTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $attrL11n = new BaseStringL11n(); + $attrL11n->ref = $request->getDataInt('type') ?? 0; + $attrL11n->setLanguage( + $request->getDataString('language') ?? $request->getLanguage() + ); + $attrL11n->content = $request->getDataString('title') ?? ''; + + return $attrL11n; + } + + /** + * Validate vehicle attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeTypeL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['type'] = !$request->hasData('type')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute type + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeTypeCreate($request))) { + $response->set('attr_type_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrType = $this->createAttributeTypeFromRequest($request); + $this->createModel($request->header->account, $attrType, VehicleAttributeTypeMapper::class, 'attr_type', $request->getOrigin()); + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute type', 'Attribute type successfully created', $attrType); + } + + /** + * Method to create vehicle attribute from request. + * + * @param RequestAbstract $request Request + * + * @return AttributeType + * + * @since 1.0.0 + */ + private function createAttributeTypeFromRequest(RequestAbstract $request) : AttributeType + { + $attrType = new AttributeType($request->getDataString('name') ?? ''); + $attrType->datatype = $request->getDataInt('datatype') ?? 0; + $attrType->custom = $request->getDataBool('custom') ?? false; + $attrType->isRequired = (bool) ($request->getData('is_required') ?? false); + $attrType->validationPattern = $request->getDataString('validation_pattern') ?? ''; + $attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + $attrType->setFields($request->getDataInt('fields') ?? 0); + + return $attrType; + } + + /** + * Validate vehicle attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeTypeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['name'] = !$request->hasData('name')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute value + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeValueCreate($request))) { + $response->set('attr_value_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrValue = $this->createAttributeValueFromRequest($request); + $this->createModel($request->header->account, $attrValue, VehicleAttributeValueMapper::class, 'attr_value', $request->getOrigin()); + + if ($attrValue->isDefault) { + $this->createModelRelation( + $request->header->account, + (int) $request->getData('type'), + $attrValue->id, + VehicleAttributeTypeMapper::class, 'defaults', '', $request->getOrigin() + ); + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute value', 'Attribute value successfully created', $attrValue); + } + + /** + * Method to create vehicle attribute value from request. + * + * @param RequestAbstract $request Request + * + * @return AttributeValue + * + * @since 1.0.0 + */ + private function createAttributeValueFromRequest(RequestAbstract $request) : AttributeValue + { + /** @var AttributeType $type */ + $type = VehicleAttributeTypeMapper::get() + ->where('id', $request->getDataInt('type') ?? 0) + ->execute(); + + $attrValue = new AttributeValue(); + $attrValue->isDefault = $request->getDataBool('default') ?? false; + $attrValue->setValue($request->getData('value'), $type->datatype); + + if ($request->hasData('title')) { + $attrValue->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + } + + return $attrValue; + } + + /** + * Validate vehicle attribute value create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeValueCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['type'] = !$request->hasData('type')) + || ($val['value'] = !$request->hasData('value')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { + $response->set('attr_value_l11n_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createAttributeValueL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } + + /** + * Method to create vehicle attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createAttributeValueL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $attrL11n = new BaseStringL11n(); + $attrL11n->ref = $request->getDataInt('value') ?? 0; + $attrL11n->setLanguage( + $request->getDataString('language') ?? $request->getLanguage() + ); + $attrL11n->content = $request->getDataString('title') ?? ''; + + return $attrL11n; + } + + /** + * Validate vehicle attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeValueL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['value'] = !$request->hasData('value')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to handle api vehicle attributes + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttribute(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { + $response->set('attr_value_l11n_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createAttributeValueL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } + + /** + * Api method to create a bill + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiMediaAddToVehicle(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateMediaAddToVehicle($request))) { + $response->set($request->uri->__toString(), new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\FleetManagement\Models\Vehicle $vehicle */ + $vehicle = VehicleMapper::get()->where('id', (int) $request->getData('vehicle'))->execute(); + $path = $this->createVehicleDir($vehicle); + + $uploaded = []; + if (!empty($uploadedFiles = $request->getFiles())) { + $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( + names: [], + fileNames: [], + files: $uploadedFiles, + account: $request->header->account, + basePath: __DIR__ . '/../../../Modules/Media/Files' . $path, + virtualPath: $path, + pathSettings: PathSettings::FILE_PATH, + hasAccountRelation: false, + readContent: (bool) ($request->getData('parse_content') ?? false) + ); + + $collection = null; + foreach ($uploaded as $media) { + $this->createModelRelation( + $request->header->account, + $vehicle->id, + $media->id, + VehicleMapper::class, + 'media', + '', + $request->getOrigin() + ); + + if ($request->hasData('type')) { + $this->createModelRelation( + $request->header->account, + $media->id, + $request->getDataInt('type'), + MediaMapper::class, + 'types', + '', + $request->getOrigin() + ); + } + + if ($collection === null) { + $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); + + if ($collection->id === 0) { + $collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection( + $path, + $request->header->account, + __DIR__ . '/../../../Modules/Media/Files' . $path, + ); + } + } + + $this->createModelRelation( + $request->header->account, + $collection->id, + $media->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + } + } + + if (!empty($mediaFiles = $request->getDataJson('media'))) { + foreach ($mediaFiles as $media) { + $this->createModelRelation( + $request->header->account, + $vehicle->id, + (int) $media, + VehicleMapper::class, + 'media', + '', + $request->getOrigin() + ); + } + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Media', 'Media added to bill.', [ + 'upload' => $uploaded, + 'media' => $mediaFiles, + ]); + } + + /** + * Create media directory path + * + * @param Vehicle $vehicle Vehicle + * + * @return string + * + * @since 1.0.0 + */ + private function createVehicleDir(Vehicle $vehicle) : string + { + return '/Modules/FleetManagement/Vehicle/' + . $this->app->unitId . '/' + . $vehicle->createdAt->format('Y/m/d') . '/' + . $vehicle->id; + } + + /** + * Method to validate bill creation from request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateMediaAddToVehicle(RequestAbstract $request) : array + { + $val = []; + if (($val['media'] = (!$request->hasData('media') && empty($request->getFiles()))) + || ($val['vehicle'] = !$request->hasData('vehicle')) + ) { + return $val; + } + + return []; + } } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 37ab768..3405264 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,6 +14,11 @@ declare(strict_types=1); namespace Modules\FleetManagement\Controller; +use phpOMS\Contract\RenderableInterface; +use phpOMS\Message\RequestAbstract; +use phpOMS\Message\ResponseAbstract; +use phpOMS\Views\View; + /** * FleetManagement class. * @@ -25,5 +30,47 @@ namespace Modules\FleetManagement\Controller; */ final class BackendController extends Controller { + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementVehicleList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-list'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response)); + + return $view; + } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementVehicleProfile(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-profile'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response)); + + return $view; + } } diff --git a/Models/Cost.php b/Models/Cost.php new file mode 100644 index 0000000..6dfcead --- /dev/null +++ b/Models/Cost.php @@ -0,0 +1,48 @@ + $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/CostType.php b/Models/CostType.php new file mode 100644 index 0000000..4306174 --- /dev/null +++ b/Models/CostType.php @@ -0,0 +1,48 @@ + $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/FuelType.php b/Models/FuelType.php new file mode 100644 index 0000000..2c7c5e2 --- /dev/null +++ b/Models/FuelType.php @@ -0,0 +1,121 @@ +name = $name; + } + + /** + * Set l11n + * + * @param string|BaseStringL11n $l11n Tag article l11n + * @param string $lang Language + * + * @return void + * + * @since 1.0.0 + */ + public function setL11n(string | BaseStringL11n $l11n, string $lang = ISO639x1Enum::_EN) : void + { + if ($l11n instanceof BaseStringL11n) { + $this->l11n = $l11n; + } elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) { + $this->l11n->content = $l11n; + $this->l11n->setLanguage($lang); + } else { + $this->l11n = new BaseStringL11n(); + $this->l11n->content = $l11n; + $this->l11n->setLanguage($lang); + } + } + + /** + * @return string + * + * @since 1.0.0 + */ + public function getL11n() : string + { + if (!isset($this->l11n)) { + return ''; + } + + return $this->l11n instanceof BaseStringL11n ? $this->l11n->content : $this->l11n; + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/FuelTypeL11nMapper.php b/Models/FuelTypeL11nMapper.php new file mode 100644 index 0000000..0b76458 --- /dev/null +++ b/Models/FuelTypeL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class FuelTypeL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_fuel_type_l11n_id' => ['name' => 'fleetmgmt_fuel_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_fuel_type_l11n_title' => ['name' => 'fleetmgmt_fuel_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_fuel_type_l11n_type' => ['name' => 'fleetmgmt_fuel_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_fuel_type_l11n_lang' => ['name' => 'fleetmgmt_fuel_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_fuel_type_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_fuel_type_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/FuelTypeMapper.php b/Models/FuelTypeMapper.php new file mode 100644 index 0000000..10c16f0 --- /dev/null +++ b/Models/FuelTypeMapper.php @@ -0,0 +1,82 @@ + + */ +final class FuelTypeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_fuel_type_id' => ['name' => 'fleetmgmt_fuel_type_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_fuel_type_name' => ['name' => 'fleetmgmt_fuel_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => FuelTypeL11nMapper::class, + 'table' => 'fleetmgmt_fuel_type_l11n', + 'self' => 'fleetmgmt_fuel_type_l11n_type', + 'column' => 'content', + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = FuelType::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_fuel_type'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_fuel_type_id'; +} diff --git a/Models/Inspection.php b/Models/Inspection.php new file mode 100644 index 0000000..e69de29 diff --git a/Models/InspectionMapper_.php b/Models/InspectionMapper_.php new file mode 100644 index 0000000..e69de29 diff --git a/Models/NullFuelType.php b/Models/NullFuelType.php new file mode 100644 index 0000000..9502384 --- /dev/null +++ b/Models/NullFuelType.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/NullInspection.php b/Models/NullInspection.php new file mode 100644 index 0000000..e69de29 diff --git a/Models/NullVehicle.php b/Models/NullVehicle.php new file mode 100644 index 0000000..41270a4 --- /dev/null +++ b/Models/NullVehicle.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/NullVehicleType.php b/Models/NullVehicleType.php new file mode 100644 index 0000000..cee550b --- /dev/null +++ b/Models/NullVehicleType.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/Vehicle.php b/Models/Vehicle.php new file mode 100644 index 0000000..e108627 --- /dev/null +++ b/Models/Vehicle.php @@ -0,0 +1,81 @@ +createdAt = new \DateTimeImmutable('now'); + $this->type = new VehicleType(); + $this->fuelType = new FuelType(); + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/VehicleAttributeMapper.php b/Models/VehicleAttributeMapper.php new file mode 100644 index 0000000..fe17883 --- /dev/null +++ b/Models/VehicleAttributeMapper.php @@ -0,0 +1,86 @@ + + */ +final class VehicleAttributeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_vehicle_attr_id' => ['name' => 'fleetmgmt_vehicle_attr_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_attr_item' => ['name' => 'fleetmgmt_vehicle_attr_item', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_vehicle_attr_type' => ['name' => 'fleetmgmt_vehicle_attr_type', 'type' => 'int', 'internal' => 'type'], + 'fleetmgmt_vehicle_attr_value' => ['name' => 'fleetmgmt_vehicle_attr_value', 'type' => 'int', 'internal' => 'value'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'type' => [ + 'mapper' => VehicleAttributeTypeMapper::class, + 'external' => 'fleetmgmt_vehicle_attr_type', + ], + 'value' => [ + 'mapper' => VehicleAttributeValueMapper::class, + 'external' => 'fleetmgmt_vehicle_attr_value', + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = Attribute::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_vehicle_attr'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_vehicle_attr_id'; +} diff --git a/Models/VehicleAttributeTypeL11nMapper.php b/Models/VehicleAttributeTypeL11nMapper.php new file mode 100644 index 0000000..b4afaaa --- /dev/null +++ b/Models/VehicleAttributeTypeL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class VehicleAttributeTypeL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_attr_type_l11n_id' => ['name' => 'fleetmgmt_attr_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_attr_type_l11n_title' => ['name' => 'fleetmgmt_attr_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_attr_type_l11n_type' => ['name' => 'fleetmgmt_attr_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_attr_type_l11n_lang' => ['name' => 'fleetmgmt_attr_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_attr_type_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_attr_type_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/VehicleAttributeTypeMapper.php b/Models/VehicleAttributeTypeMapper.php new file mode 100644 index 0000000..7f55e37 --- /dev/null +++ b/Models/VehicleAttributeTypeMapper.php @@ -0,0 +1,94 @@ + + */ +final class VehicleAttributeTypeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_attr_type_id' => ['name' => 'fleetmgmt_attr_type_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_attr_type_name' => ['name' => 'fleetmgmt_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'fleetmgmt_attr_type_datatype' => ['name' => 'fleetmgmt_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'], + 'fleetmgmt_attr_type_fields' => ['name' => 'fleetmgmt_attr_type_fields', 'type' => 'int', 'internal' => 'fields'], + 'fleetmgmt_attr_type_custom' => ['name' => 'fleetmgmt_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'], + 'fleetmgmt_attr_type_pattern' => ['name' => 'fleetmgmt_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'], + 'fleetmgmt_attr_type_required' => ['name' => 'fleetmgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => VehicleAttributeTypeL11nMapper::class, + 'table' => 'fleetmgmt_attr_type_l11n', + 'self' => 'fleetmgmt_attr_type_l11n_type', + 'column' => 'content', + 'external' => null, + ], + 'defaults' => [ + 'mapper' => VehicleAttributeValueMapper::class, + 'table' => 'fleetmgmt_vehicle_attr_default', + 'self' => 'fleetmgmt_vehicle_attr_default_type', + 'external' => 'fleetmgmt_vehicle_attr_default_value', + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = AttributeType::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_attr_type'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_attr_type_id'; +} diff --git a/Models/VehicleAttributeValueL11nMapper.php b/Models/VehicleAttributeValueL11nMapper.php new file mode 100644 index 0000000..7ddf880 --- /dev/null +++ b/Models/VehicleAttributeValueL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class VehicleAttributeValueL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_attr_value_l11n_id' => ['name' => 'fleetmgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_attr_value_l11n_title' => ['name' => 'fleetmgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_attr_value_l11n_value' => ['name' => 'fleetmgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_attr_value_l11n_lang' => ['name' => 'fleetmgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_attr_value_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_attr_value_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/VehicleAttributeValueMapper.php b/Models/VehicleAttributeValueMapper.php new file mode 100644 index 0000000..6191dff --- /dev/null +++ b/Models/VehicleAttributeValueMapper.php @@ -0,0 +1,89 @@ + + */ +final class VehicleAttributeValueMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_attr_value_id' => ['name' => 'fleetmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_attr_value_default' => ['name' => 'fleetmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], + 'fleetmgmt_attr_value_valueStr' => ['name' => 'fleetmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], + 'fleetmgmt_attr_value_valueInt' => ['name' => 'fleetmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], + 'fleetmgmt_attr_value_valueDec' => ['name' => 'fleetmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], + 'fleetmgmt_attr_value_valueDat' => ['name' => 'fleetmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], + 'fleetmgmt_attr_value_unit' => ['name' => 'fleetmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], + 'fleetmgmt_attr_value_deptype' => ['name' => 'fleetmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], + 'fleetmgmt_attr_value_depvalue' => ['name' => 'fleetmgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => VehicleAttributeValueL11nMapper::class, + 'table' => 'fleetmgmt_attr_value_l11n', + 'self' => 'fleetmgmt_attr_value_l11n_value', + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = AttributeValue::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_attr_value'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_attr_value_id'; +} diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php new file mode 100644 index 0000000..b8f697f --- /dev/null +++ b/Models/VehicleMapper.php @@ -0,0 +1,110 @@ + + */ +final class VehicleMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_vehicle_id' => ['name' => 'fleetmgmt_vehicle_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_name' => ['name' => 'fleetmgmt_vehicle_name', 'type' => 'string', 'internal' => 'name'], + 'fleetmgmt_vehicle_status' => ['name' => 'fleetmgmt_vehicle_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_vehicle_info' => ['name' => 'fleetmgmt_vehicle_info', 'type' => 'string', 'internal' => 'info'], + 'fleetmgmt_vehicle_unit' => ['name' => 'fleetmgmt_vehicle_unit', 'type' => 'int', 'internal' => 'unit'], + 'fleetmgmt_vehicle_responsible' => ['name' => 'fleetmgmt_vehicle_responsible', 'type' => 'int', 'internal' => 'responsible'], + 'fleetmgmt_vehicle_created_at' => ['name' => 'fleetmgmt_vehicle_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'media' => [ + 'mapper' => MediaMapper::class, + 'table' => 'fleetmgmt_vehicle_media', + 'external' => 'fleetmgmt_vehicle_media_media', + 'self' => 'fleetmgmt_vehicle_media_vehicle', + ], + 'attributes' => [ + 'mapper' => VehicleAttributeMapper::class, + 'table' => 'fleetmgmt_vehicle_attr', + 'self' => 'fleetmgmt_vehicle_attr_item', + 'external' => null, + ], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'type' => [ + 'mapper' => VehicleTypeMapper::class, + 'external' => 'fleetmgmt_vehicle_type', + ], + 'fuelType' => [ + 'mapper' => FuelTypeMapper::class, + 'external' => 'fleetmgmt_vehicle_fuel', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_vehicle'; + + /** + * Created at. + * + * @var string + * @since 1.0.0 + */ + public const CREATED_AT = 'fleetmgmt_vehicle_created_at'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_vehicle_id'; +} diff --git a/Models/VehicleStatus.php b/Models/VehicleStatus.php new file mode 100644 index 0000000..2adc3d9 --- /dev/null +++ b/Models/VehicleStatus.php @@ -0,0 +1,36 @@ +name = $name; + } + + /** + * Set l11n + * + * @param string|BaseStringL11n $l11n Tag article l11n + * @param string $lang Language + * + * @return void + * + * @since 1.0.0 + */ + public function setL11n(string | BaseStringL11n $l11n, string $lang = ISO639x1Enum::_EN) : void + { + if ($l11n instanceof BaseStringL11n) { + $this->l11n = $l11n; + } elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) { + $this->l11n->content = $l11n; + $this->l11n->setLanguage($lang); + } else { + $this->l11n = new BaseStringL11n(); + $this->l11n->content = $l11n; + $this->l11n->setLanguage($lang); + } + } + + /** + * @return string + * + * @since 1.0.0 + */ + public function getL11n() : string + { + if (!isset($this->l11n)) { + return ''; + } + + return $this->l11n instanceof BaseStringL11n ? $this->l11n->content : $this->l11n; + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/VehicleTypeL11nMapper.php b/Models/VehicleTypeL11nMapper.php new file mode 100644 index 0000000..87ef2c8 --- /dev/null +++ b/Models/VehicleTypeL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class VehicleTypeL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_vehicle_type_l11n_id' => ['name' => 'fleetmgmt_vehicle_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_type_l11n_title' => ['name' => 'fleetmgmt_vehicle_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_vehicle_type_l11n_type' => ['name' => 'fleetmgmt_vehicle_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_vehicle_type_l11n_lang' => ['name' => 'fleetmgmt_vehicle_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_vehicle_type_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_vehicle_type_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/VehicleTypeMapper.php b/Models/VehicleTypeMapper.php new file mode 100644 index 0000000..b188470 --- /dev/null +++ b/Models/VehicleTypeMapper.php @@ -0,0 +1,82 @@ + + */ +final class VehicleTypeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_vehicle_type_id' => ['name' => 'fleetmgmt_vehicle_type_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_type_name' => ['name' => 'fleetmgmt_vehicle_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => VehicleTypeL11nMapper::class, + 'table' => 'fleetmgmt_vehicle_type_l11n', + 'self' => 'fleetmgmt_vehicle_type_l11n_type', + 'column' => 'content', + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = VehicleType::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_vehicle_type'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_vehicle_type_id'; +} diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index 89165a9..bd7015c 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -13,7 +13,6 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Client', - 'Region' => 'Region', - 'SalesRep' => 'SalesRep', + 'FleetManagement' => 'Fleet Management', + 'Vehicles' => 'Vehicles', ]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 99b60d7..8734b98 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -12,116 +12,6 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ - 'Accounting' => 'Accounting', - 'Addition' => 'Addition', - 'Address' => 'Address', - 'Addresses' => 'Addresses', - 'Africa' => 'Africa', - 'AllCustomers' => 'All Customers', - 'America' => 'America', - 'Analyse' => 'Analyse', - 'AreaManager' => 'Area Manager', - 'Articlegroup' => 'Articlegroup', - 'Articles' => 'Articles', - 'Asia' => 'Asia', - 'Attribute' => 'Attribute', - 'Attributes' => 'Attributes', - 'Balance' => 'Balance', - 'BaseTime' => 'Base time', - 'Bills' => 'Bills', - 'Bonus' => 'Bonus', - 'Business' => 'Business', - 'CIS' => 'CIS', - 'CLV' => 'CLV', - 'Calendar' => 'Calendar', - 'City' => 'City', - 'Client' => 'Client', - 'ClientID' => 'Client Id', - 'Clients' => 'Clients', - 'ComparisonTime' => 'Comparison time', - 'Contact' => 'Contact', - 'Country' => 'Country', - 'Created' => 'Created', - 'CreatedAt' => 'Created at', - 'CreditRating' => 'Credit Rating', - 'Creditcard' => 'Creditcard', - 'Customers' => 'Customers', - 'DSO' => 'DSO', - 'Date' => 'Date', - 'Default' => 'Default', - 'Delivery' => 'Delivery', - 'Discount' => 'Discount', - 'DiscountBonus' => 'Discount bonus', - 'DiscountP' => 'Discount %', - 'Documents' => 'Documents', - 'Due' => 'Due', - 'Email' => 'Email', - 'Europe' => 'Europe', - 'Fax' => 'Fax', - 'Files' => 'Files', - 'Filter' => 'Filter', - 'Freightage' => 'Freightage', - 'Group' => 'Group', - 'ID' => 'ID', - 'Info' => 'Info', - 'Invoice' => 'Invoice', - 'Invoices' => 'Invoices', - 'IsDefault' => 'Is default?', - 'Items' => 'Items', - 'LastContact' => 'Last Contact', - 'LastOrder' => 'Last Order', - 'Log' => 'Log', - 'Logs' => 'Logs', - 'LostCustomers' => 'Lost customers', - 'MRR' => 'MRR', - 'MTDSales' => 'MTD Sales', - 'Margin' => 'Margin', - 'Messages' => 'Messages', - 'Modified' => 'Modified', - 'Modules' => 'Modules', - 'Name' => 'Name', - 'Name1' => 'Name1', - 'Name2' => 'Name2', - 'Name3' => 'Name3', - 'Net' => 'Net', - 'NewCustomers' => 'New customers', - 'Notes' => 'Notes', - 'Number' => 'Number', - 'Office' => 'Office', - 'Other' => 'Other', - 'Payment' => 'Payment', - 'PaymentTerm' => 'Payment Term', - 'Permission' => 'Permission', - 'Phone' => 'Phone', - 'Postal' => 'Postal', - 'Price' => 'Price', - 'Prices' => 'Prices', - 'Private' => 'Private', - 'Productgroup' => 'Productgroup', - 'Profile' => 'Profile', - 'Profit' => 'Profit', - 'Purchase' => 'Purchase', - 'Quantity' => 'Quantity', - 'RecentInvoices' => 'Recent Invoices', - 'Region' => 'Region', - 'Rep' => 'Rep', - 'Retention' => 'Retention', - 'Sales' => 'Sales', - 'Segment' => 'Segment', - 'Segments' => 'Segments', - 'Subtype' => 'Subtype', - 'Support' => 'Support', - 'Tags' => 'Tags', - 'Title' => 'Title', - 'Total' => 'Total', - 'TotalPrice' => 'Total price', - 'Type' => 'Type', - 'UnitPrice' => 'Unit price', - 'Value' => 'Value', - 'Website' => 'Website', - 'Wire' => 'Wire', - 'YTDSales' => 'YTD Sales', - 'Zip' => 'Zip', - 'IMG_alt_map' => 'Map', +return ['FleetManagement' => [ + 'Vehicle' => 'Vehicle', ]]; diff --git a/Theme/Backend/vehicle-list.tpl.php b/Theme/Backend/vehicle-list.tpl.php index 2adf467..407fe37 100755 --- a/Theme/Backend/vehicle-list.tpl.php +++ b/Theme/Backend/vehicle-list.tpl.php @@ -17,13 +17,13 @@ use Modules\Media\Models\NullMedia; use phpOMS\Uri\UriFactory; /** @var \phpOMS\Views\View $this */ -$clients = $this->getData('client'); +$vehicles = $this->getData('vehicles') ?? []; echo $this->getData('nav')->render(); ?>
-
getHtml('Clients'); ?>
+
getHtml('Vehicles'); ?>
@@ -41,7 +41,7 @@ echo $this->getData('nav')->render(); ?> - - $value) : ++$count; - $url = UriFactory::build('{/base}/sales/client/profile?{?}&id=' . $value->id); - $image = $value->getFileByTypeName('client_profile_image'); + $value) : ++$count; + $url = UriFactory::build('{/base}/sales/vehicle/profile?{?}&id=' . $value->id); + $image = $value->getFileByTypeName('vehicle_profile_image'); ?> - - $value) : ++$count; - $url = UriFactory::build('{/base}/sales/vehicle/profile?{?}&id=' . $value->id); - $image = $value->getFileByTypeName('vehicle_profile_image'); - ?> + $value) : + ++$count; + $url = UriFactory::build('{/base}/fleet/vehicle/profile?{?}&id=' . $value->id); + ?> - $value) : ++$c; ?> data['inspections'] as $inspection) : ?> - $value) : ++$c; ?>
getHtml('Name'); ?> + getHtml('Status'); ?> getHtml('City'); ?> + getHtml('Name'); ?> getHtml('Zip'); ?> + getHtml('Type'); ?> getHtml('Address'); ?> - - - - getHtml('Country'); ?> - - -
<?= $this->getHtml('IMG_alt_client'); ?><?= $this->getHtml('IMG_alt_vehicle'); ?> diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index ab6a5c0..502d02b 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -12,6 +12,7 @@ */ declare(strict_types=1); +use Modules\FleetManagement\Models\NullVehicle; use Modules\Profile\Models\ContactType; use phpOMS\Uri\UriFactory; @@ -19,15 +20,11 @@ $countryCodes = \phpOMS\Localization\ISO3166TwoEnum::getConstants(); $countries = \phpOMS\Localization\ISO3166NameEnum::getConstants(); /** - * @var \Modules\ClientManagement\Models\Client $client + * @var \Modules\FleetManagement\Models\Vehicle $vehicle */ -$client = $this->getData('client'); -$notes = $client->getNotes(); +$vehicle = $this->getData('vehicle') ?? new NullVehicle(); $files = $client->getFiles(); -$newestInvoices = $this->getData('newestInvoices') ?? []; -$monthlySalesCosts = $this->getData('monthlySalesCosts') ?? []; - /** * @var \phpOMS\Views\View $this */ @@ -37,582 +34,83 @@ echo $this->getData('nav')->render();
request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
-
+
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
+
+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
-
- getHtml('Contact'); ?> - -
-
- -
-
-
-
-
-
-
-
+
+
+
+
-
- getHtml('Address'); ?> - - - - - -
-
- - mainAddress->addition)) : ?> -
-
- -
-
-
-
-
-
-
-
-
- mainAddress->getCountry()) . '.svg')) : ?> - <?= $this->getHtml('IMG_alt_map'); ?> - -
-
-
- -
-
- -
-
-
-
-
-
-
-
- -
getHtml('YTDSales'); ?>: - -
getHtml('MTDSales'); ?>: - -
getHtml('CLV'); ?>: - -
getHtml('MRR'); ?>: - -
-
-
-
- -
-
-
- -
getHtml('LastContact'); ?>: - -
getHtml('LastOrder'); ?>: - -
getHtml('Created'); ?>: - -
getHtml('Modified'); ?>: - -
-
-
-
- -
-
-
- -
getHtml('DSO'); ?>: - -
getHtml('Due'); ?>: - -
getHtml('Balance'); ?>: - -
getHtml('CreditRating'); ?>: - -
-
-
-
-
- -
-
-
-
getHtml('Notes'); ?>
-
- - - - - id); - ?> - -
getHtml('Title'); ?> - getHtml('CreatedAt'); ?> -
title; ?> - createdAt->format('Y-m-d'); ?> - -
-
-
-
- -
-
-
getHtml('Documents'); ?>
-
- - - - - id); - ?> - -
getHtml('Title'); ?> - - getHtml('CreatedAt'); ?> -
name; ?> - extension; ?> - createdAt->format('Y-m-d'); ?> - -
-
-
-
-
- -
-
-
-
getHtml('RecentInvoices'); ?>
- - - - - id); - ?> - -
getHtml('Number'); ?> - getHtml('Type'); ?> - getHtml('Name'); ?> - getHtml('Net'); ?> - getHtml('Date'); ?> -
getNumber(); ?> - type->getL11n(); ?> - billTo; ?> - netSales->getCurrency(); ?> - createdAt->format('Y-m-d'); ?> - -
-
-
-
- -
-
-
-
getHtml('Segments'); ?>
-
-
-
- -
-
-
getHtml('Sales'); ?>
-
- - - ], - "datasets": [ - { - "label": "getHtml('Margin'); ?>", - "type": "line", - "data": [ - - - ], - "yAxisID": "axis-2", - "fill": false, - "borderColor": "rgb(255, 99, 132)", - "backgroundColor": "rgb(255, 99, 132)" - }, - { - "label": "getHtml('Sales'); ?>", - "type": "bar", - "data": [ - - - ], - "yAxisID": "axis-1", - "backgroundColor": "rgb(54, 162, 235)" - } - ] - }, - "options": { - "scales": { - "yAxes": [ - { - "id": "axis-1", - "display": true, - "position": "left" - }, - { - "id": "axis-2", - "display": true, - "position": "right", - "scaleLabel": { - "display": true, - "labelString": "getHtml('Margin'); ?> %" - }, - "gridLines": { - "display": false - }, - "beginAtZero": true, - "ticks": { - "min": 0, - "max": 100, - "stepSize": 10 - } - } - ] - } - } - }'> -
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Address'); ?>

-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-

getHtml('Contact'); ?>

-
-
- -
-
-
-
-
-
-
-
-
-
-
-
+
+
+
- request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Payment'); ?>

-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-

getHtml('PaymentTerm'); ?>

-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-6' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Price'); ?>

-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-7' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('AreaManager'); ?>

-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-8' ? ' checked' : ''; ?>> -
-
- request->uri->fragment === 'c-tab-9' ? ' checked' : ''; ?>> -
- -
- request->uri->fragment === 'c-tab-9' ? ' checked' : ''; ?>> -
- -
- request->uri->fragment === 'c-tab-10' ? ' checked' : ''; ?>> -
-
-
- l11nManager, $this->request, $this->response); - $footerView->setTemplate('/Web/Templates/Lists/Footer/PaginationBig'); - $footerView->setPages(20); - $footerView->setPage(1); - ?> -
- - - - - - - - -
getHtml('Logs'); ?>
IP - getHtml('ID', '0', '0'); ?> - getHtml('Name'); ?> - getHtml('Log'); ?> - getHtml('Date'); ?> -
-
printHtml($this->request->getOrigin()); ?> - printHtml((string) $this->request->header->account); ?> - printHtml((string) $this->request->header->account); ?> - Creating customer - printHtml((new \DateTime('now'))->format('Y-m-d H:i:s')); ?> -
-
-
-
-
-
+
\ No newline at end of file From 63a40318d14ea114e5902b9f74bcaf05a5a4cef7 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 24 May 2023 18:11:37 +0000 Subject: [PATCH 13/89] bug fixes and item management improvements --- Admin/Install/Media.install.json | 14 +++ Admin/Install/Navigation.install.json | 4 +- Admin/Install/vehicletype.json | 42 ------- Controller/ApiController.php | 11 +- Controller/BackendController.php | 126 +++++++++++++++++++ Models/NullVehicle.php | 1 + Models/Vehicle.php | 7 +- Models/VehicleMapper.php | 4 +- Models/VehicleStatus.php | 2 + Theme/Backend/Lang/en.lang.php | 23 ++++ Theme/Backend/attribute-type-list.tpl.php | 71 +++++++++++ Theme/Backend/attribute-type.tpl.php | 98 +++++++++++++++ Theme/Backend/vehicle-list.tpl.php | 26 ++-- Theme/Backend/vehicle-profile.tpl.php | 143 ++++++++++++---------- 14 files changed, 441 insertions(+), 131 deletions(-) create mode 100755 Theme/Backend/attribute-type-list.tpl.php create mode 100755 Theme/Backend/attribute-type.tpl.php diff --git a/Admin/Install/Media.install.json b/Admin/Install/Media.install.json index 58397fa..c012cd3 100755 --- a/Admin/Install/Media.install.json +++ b/Admin/Install/Media.install.json @@ -1,4 +1,18 @@ [ + { + "type": "type", + "name": "vehicle_profile_image", + "l11n": [ + { + "title": "Profile image", + "lang": "en" + }, + { + "title": "Profilbild", + "lang": "de" + } + ] + }, { "type": "collection", "create_directory": true, diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index b41258b..a82b041 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -75,7 +75,7 @@ "children": [ { "id": 1003503101, - "pid": "/sales", + "pid": "/fleet/vehicle/attribute", "type": 3, "subtype": 1, "name": "Types", @@ -90,7 +90,7 @@ }, { "id": 1003503201, - "pid": "/sales", + "pid": "/fleet/vehicle/attribute", "type": 3, "subtype": 1, "name": "Values", diff --git a/Admin/Install/vehicletype.json b/Admin/Install/vehicletype.json index f5485e0..e68fed8 100644 --- a/Admin/Install/vehicletype.json +++ b/Admin/Install/vehicletype.json @@ -76,13 +76,6 @@ "de": "Moped" } }, - { - "name": "RV", - "l11n": { - "en": "Recreational Vehicle", - "de": "Wohnmobil" - } - }, { "name": "tractor", "l11n": { @@ -96,40 +89,5 @@ "en": "Forklift", "de": "Gabelstapler" } - }, - { - "name": "skateboard", - "l11n": { - "en": "Skateboard", - "de": "Skateboard" - } - }, - { - "name": "snowmobile", - "l11n": { - "en": "Snowmobile", - "de": "Schneemobil" - } - }, - { - "name": "jet_ski", - "l11n": { - "en": "Jet Ski", - "de": "Jet Ski" - } - }, - { - "name": "quad_bike", - "l11n": { - "en": "Quad Bike", - "de": "Quad Bike" - } - }, - { - "name": "golf_cart", - "l11n": { - "en": "Golf Cart", - "de": "Golf Cart" - } } ] diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 9cebf70..e75dab1 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -536,7 +536,9 @@ final class ApiController extends Controller private function validateVehicleCreate(RequestAbstract $request) : array { $val = []; - if (($val['name'] = !$request->hasData('name'))) { + if (($val['name'] = !$request->hasData('name')) + || ($val['type'] = !$request->hasData('type')) + ) { return $val; } @@ -1080,7 +1082,7 @@ final class ApiController extends Controller $vehicle->id, $media->id, VehicleMapper::class, - 'media', + 'files', '', $request->getOrigin() ); @@ -1128,14 +1130,14 @@ final class ApiController extends Controller $vehicle->id, (int) $media, VehicleMapper::class, - 'media', + 'files', '', $request->getOrigin() ); } } - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Media', 'Media added to bill.', [ + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Media', 'Media added to vehicle.', [ 'upload' => $uploaded, 'media' => $mediaFiles, ]); @@ -1154,7 +1156,6 @@ final class ApiController extends Controller { return '/Modules/FleetManagement/Vehicle/' . $this->app->unitId . '/' - . $vehicle->createdAt->format('Y/m/d') . '/' . $vehicle->id; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 3405264..33b2c0e 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,7 +14,14 @@ declare(strict_types=1); namespace Modules\FleetManagement\Controller; +use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; +use Modules\FleetManagement\Models\VehicleAttributeTypeMapper; +use Modules\FleetManagement\Models\VehicleMapper; +use Modules\FleetManagement\Models\VehicleTypeMapper; +use Modules\Media\Models\MediaMapper; +use Modules\Media\Models\MediaTypeMapper; use phpOMS\Contract\RenderableInterface; +use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Views\View; @@ -30,6 +37,35 @@ use phpOMS\Views\View; */ final class BackendController extends Controller { + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type-list'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003503001, $request, $response)); + + /** @var \Modules\Attribute\Models\AttributeType[] $attributes */ + $attributes = VehicleAttributeTypeMapper::getAll() + ->with('l11n') + ->where('l11n/language', $response->getLanguage()) + ->execute(); + + $view->addData('attributes', $attributes); + + return $view; + } + /** * Routing end-point for application behaviour. * @@ -49,6 +85,50 @@ final class BackendController extends Controller $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-list'); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response)); + $list = VehicleMapper::getAll() + ->with('type') + ->with('type/l11n') + ->where('type/l11n/language', $response->getLanguage()) + ->sort('id', 'DESC') + ->execute(); + + $view->setData('vehicles', $list); + + return $view; + } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementAttributeType(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response)); + + /** @var \Modules\Attribute\Models\AttributeType $attribute */ + $attribute = VehicleAttributeTypeMapper::get() + ->with('l11n') + ->where('id', (int) $request->getData('id')) + ->where('l11n/language', $response->getLanguage()) + ->execute(); + + $l11ns = VehicleAttributeTypeL11nMapper::getAll() + ->where('ref', $attribute->id) + ->execute(); + + $view->addData('attribute', $attribute); + $view->addData('l11ns', $l11ns); + return $view; } @@ -71,6 +151,52 @@ final class BackendController extends Controller $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-profile'); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response)); + $vehicle = VehicleMapper::get() + ->with('attributes') + ->with('attributes/type') + ->with('attributes/value') + ->with('attributes/type/l11n') + ->with('type') + ->with('type/l11n') + ->with('fuelType') + ->with('fuelType/l11n') + ->where('id', (int) $request->getData('id')) + ->where('type/l11n/language', $response->getLanguage()) + ->where('fuelType/l11n/language', $response->getLanguage()) + ->where('attributes/type/l11n/language', $response->getLanguage()) + ->execute(); + + $view->setData('vehicle', $vehicle); + + $query = new Builder($this->app->dbPool->get()); + $results = $query->selectAs(VehicleMapper::HAS_MANY['files']['external'], 'file') + ->from(VehicleMapper::TABLE) + ->leftJoin(VehicleMapper::HAS_MANY['files']['table']) + ->on(VehicleMapper::HAS_MANY['files']['table'] . '.' . VehicleMapper::HAS_MANY['files']['self'], '=', VehicleMapper::TABLE . '.' . VehicleMapper::PRIMARYFIELD) + ->leftJoin(MediaMapper::TABLE) + ->on(VehicleMapper::HAS_MANY['files']['table'] . '.' . VehicleMapper::HAS_MANY['files']['external'], '=', MediaMapper::TABLE . '.' . MediaMapper::PRIMARYFIELD) + ->leftJoin(MediaMapper::HAS_MANY['types']['table']) + ->on(MediaMapper::TABLE . '.' . MediaMapper::PRIMARYFIELD, '=', MediaMapper::HAS_MANY['types']['table'] . '.' . MediaMapper::HAS_MANY['types']['self']) + ->leftJoin(MediaTypeMapper::TABLE) + ->on(MediaMapper::HAS_MANY['types']['table'] . '.' . MediaMapper::HAS_MANY['types']['external'], '=', MediaTypeMapper::TABLE . '.' . MediaTypeMapper::PRIMARYFIELD) + ->where(VehicleMapper::HAS_MANY['files']['self'], '=', $vehicle->id) + ->where(MediaTypeMapper::TABLE . '.' . MediaTypeMapper::getColumnByMember('name'), '=', 'vehicle_profile_image'); + + $vehicleImage = MediaMapper::get() + ->with('types') + ->where('id', $results) + ->limit(1) + ->execute(); + + $view->addData('vehicleImage', $vehicleImage); + + $vehicleTypes = VehicleTypeMapper::getAll() + ->with('l11n') + ->where('l11n/language', $response->getLanguage()) + ->execute(); + + $view->addData('types', $vehicleTypes); + return $view; } } diff --git a/Models/NullVehicle.php b/Models/NullVehicle.php index 41270a4..033c37c 100644 --- a/Models/NullVehicle.php +++ b/Models/NullVehicle.php @@ -34,6 +34,7 @@ final class NullVehicle extends Vehicle public function __construct(int $id = 0) { $this->id = $id; + parent::__construct(); } /** diff --git a/Models/Vehicle.php b/Models/Vehicle.php index e108627..b5840ee 100644 --- a/Models/Vehicle.php +++ b/Models/Vehicle.php @@ -40,12 +40,8 @@ class Vehicle implements \JsonSerializable public array $inspections = []; - public array $attributes = []; - public array $milage = []; - public array $media = []; - public array $notes = []; public int $unit = 0; @@ -78,4 +74,7 @@ class Vehicle implements \JsonSerializable { return $this->toArray(); } + + use \Modules\Media\Models\MediaListTrait; + use \Modules\Attribute\Models\AttributeHolderTrait; } diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php index b8f697f..34a0f17 100644 --- a/Models/VehicleMapper.php +++ b/Models/VehicleMapper.php @@ -42,6 +42,8 @@ final class VehicleMapper extends DataMapperFactory 'fleetmgmt_vehicle_status' => ['name' => 'fleetmgmt_vehicle_status', 'type' => 'int', 'internal' => 'status'], 'fleetmgmt_vehicle_info' => ['name' => 'fleetmgmt_vehicle_info', 'type' => 'string', 'internal' => 'info'], 'fleetmgmt_vehicle_unit' => ['name' => 'fleetmgmt_vehicle_unit', 'type' => 'int', 'internal' => 'unit'], + 'fleetmgmt_vehicle_type' => ['name' => 'fleetmgmt_vehicle_type', 'type' => 'int', 'internal' => 'type'], + 'fleetmgmt_vehicle_fuel' => ['name' => 'fleetmgmt_vehicle_fuel', 'type' => 'int', 'internal' => 'fuelType'], 'fleetmgmt_vehicle_responsible' => ['name' => 'fleetmgmt_vehicle_responsible', 'type' => 'int', 'internal' => 'responsible'], 'fleetmgmt_vehicle_created_at' => ['name' => 'fleetmgmt_vehicle_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], ]; @@ -53,7 +55,7 @@ final class VehicleMapper extends DataMapperFactory * @since 1.0.0 */ public const HAS_MANY = [ - 'media' => [ + 'files' => [ 'mapper' => MediaMapper::class, 'table' => 'fleetmgmt_vehicle_media', 'external' => 'fleetmgmt_vehicle_media_media', diff --git a/Models/VehicleStatus.php b/Models/VehicleStatus.php index 2adc3d9..5b2545a 100644 --- a/Models/VehicleStatus.php +++ b/Models/VehicleStatus.php @@ -33,4 +33,6 @@ abstract class VehicleStatus extends Enum public const DAMAGED = 3; public const OUT_OF_ORDER = 4; + + public const MAINTENANCE = 5; } diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 8734b98..dcba1b7 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -14,4 +14,27 @@ declare(strict_types=1); return ['FleetManagement' => [ 'Vehicle' => 'Vehicle', + 'Vehicles' => 'Vehicles', + 'Status' => 'Status', + 'Name' => 'Name', + 'Type' => 'Type', + 'Make' => 'Make', + 'Model' => 'Model', + 'Start' => 'Start', + 'End' => 'End', + 'Profile' => 'Profile', + 'Attributes' => 'Attributes', + 'Files' => 'Files', + 'Notes' => 'Notes', + 'Inspections' => 'Inspections', + 'Drivers' => 'Drivers', + 'Milage' => 'Milage', + 'Driver' => 'Driver', + 'Vin' => 'Vin', + 'PurchasePrice' => 'Purchase Price', + 'LeasingFee' => 'Leasing Fee', + ':status1' => 'Active', + ':status2' => 'Inactive', + ':status3' => 'Damaged', + ':status4' => 'Out of order', ]]; diff --git a/Theme/Backend/attribute-type-list.tpl.php b/Theme/Backend/attribute-type-list.tpl.php new file mode 100755 index 0000000..e98dac5 --- /dev/null +++ b/Theme/Backend/attribute-type-list.tpl.php @@ -0,0 +1,71 @@ +getData('attributes'); + +echo $this->getData('nav')->render(); ?> + +
+
+
+
getHtml('AttributeTypes', 'Attribute', 'Backend'); ?>
+
+ + + + + $value) : ++$count; + $url = UriFactory::build('{/base}/fleet/vehicle/attribute/type?{?}&id=' . $value->id); + ?> + +
getHtml('ID', '0', '0'); ?> + + + + getHtml('Name'); ?> + + + +
id; ?> + printHtml($value->getL11n()); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
+
diff --git a/Theme/Backend/attribute-type.tpl.php b/Theme/Backend/attribute-type.tpl.php new file mode 100755 index 0000000..c8306c7 --- /dev/null +++ b/Theme/Backend/attribute-type.tpl.php @@ -0,0 +1,98 @@ +getData('attribute'); +$l11ns = $this->getData('l11ns'); + +echo $this->getData('nav')->render(); ?> + +
+
+
+
getHtml('Attribute', 'Attribute', 'Backend'); ?>
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+
+
+
+ +
+
+
getHtml('Language', '0', '0'); ?>
+ + + + + $value) : ++$c; ?> + +
+ + getHtml('Language', '0', '0'); ?> + getHtml('Title', 'Attribute', 'Backend'); ?> +
+ + getLanguage())); ?> + content; ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
diff --git a/Theme/Backend/vehicle-list.tpl.php b/Theme/Backend/vehicle-list.tpl.php index 407fe37..d8cb0b5 100755 --- a/Theme/Backend/vehicle-list.tpl.php +++ b/Theme/Backend/vehicle-list.tpl.php @@ -13,7 +13,6 @@ */ declare(strict_types=1); -use Modules\Media\Models\NullMedia; use phpOMS\Uri\UriFactory; /** @var \phpOMS\Views\View $this */ @@ -78,21 +77,18 @@ echo $this->getData('nav')->render(); ?>
<?= $this->getHtml('IMG_alt_vehicle'); ?> - printHtml($value->number); ?> - printHtml($value->profile->account->name1); ?> printHtml($value->profile->account->name2); ?> - printHtml($value->mainAddress->city); ?> - printHtml($value->mainAddress->postal); ?> - printHtml($value->mainAddress->address); ?> - printHtml($value->mainAddress->getCountry()); ?> + + printHtml((string) $value->id); ?> + getHtml(':status' . $value->status); ?> + printHtml($value->name); ?> + printHtml($value->type->getL11n()); ?>
getHtml('Empty', '0', '0'); ?> diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 502d02b..9f6123f 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -13,17 +13,21 @@ declare(strict_types=1); use Modules\FleetManagement\Models\NullVehicle; -use Modules\Profile\Models\ContactType; +use Modules\FleetManagement\Models\VehicleStatus; +use Modules\Media\Models\NullMedia; use phpOMS\Uri\UriFactory; $countryCodes = \phpOMS\Localization\ISO3166TwoEnum::getConstants(); $countries = \phpOMS\Localization\ISO3166NameEnum::getConstants(); +$vehicleStatus = VehicleStatus::getConstants(); /** * @var \Modules\FleetManagement\Models\Vehicle $vehicle */ $vehicle = $this->getData('vehicle') ?? new NullVehicle(); -$files = $client->getFiles(); +$files = $vehicle->getFiles(); +$vehicleImage = $this->getData('vehicleImage') ?? new NullMedia(); +$vehicleTypes = $this->getData('types') ?? []; /** * @var \phpOMS\Views\View $this @@ -33,11 +37,11 @@ echo $this->getData('nav')->render();
@@ -45,69 +49,84 @@ echo $this->getData('nav')->render();
request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
-
-
-
-
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
-
-
- -
-
-
-
-
-
- +
getHtml('Profile'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
-
-
-
+
- +
+ +
From 43c23df55881f0d23572e023389e7f13910e369b Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 28 May 2023 01:13:22 +0000 Subject: [PATCH 14/89] style fixes, bug fixes --- Theme/Backend/attribute-type-list.tpl.php | 2 +- Theme/Backend/attribute-type.tpl.php | 2 +- Theme/Backend/vehicle-list.tpl.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Theme/Backend/attribute-type-list.tpl.php b/Theme/Backend/attribute-type-list.tpl.php index e98dac5..09bdaee 100755 --- a/Theme/Backend/attribute-type-list.tpl.php +++ b/Theme/Backend/attribute-type-list.tpl.php @@ -22,7 +22,7 @@ echo $this->getData('nav')->render(); ?>
-
getHtml('AttributeTypes', 'Attribute', 'Backend'); ?>
+
getHtml('AttributeTypes', 'Attribute', 'Backend'); ?>
diff --git a/Theme/Backend/attribute-type.tpl.php b/Theme/Backend/attribute-type.tpl.php index c8306c7..378a585 100755 --- a/Theme/Backend/attribute-type.tpl.php +++ b/Theme/Backend/attribute-type.tpl.php @@ -73,7 +73,7 @@ echo $this->getData('nav')->render(); ?>
-
getHtml('Language', '0', '0'); ?>
+
getHtml('Language', '0', '0'); ?>
diff --git a/Theme/Backend/vehicle-list.tpl.php b/Theme/Backend/vehicle-list.tpl.php index d8cb0b5..0eafa88 100755 --- a/Theme/Backend/vehicle-list.tpl.php +++ b/Theme/Backend/vehicle-list.tpl.php @@ -22,7 +22,7 @@ echo $this->getData('nav')->render(); ?>
-
getHtml('Vehicles'); ?>
+
getHtml('Vehicles'); ?>
From a208f09732166d57cfd17c164d4401d758f8606e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 28 May 2023 12:19:03 +0000 Subject: [PATCH 15/89] phpcs autofixes --- .github/workflows/main.yml | 2 +- Admin/Installer.php | 4 +- Controller/ApiController.php | 16 ++++---- Models/Vehicle.php | 4 +- Models/VehicleAttributeValueMapper.php | 16 ++++---- Models/VehicleMapper.php | 16 ++++---- Theme/Backend/Lang/Navigation.en.lang.php | 2 +- Theme/Backend/Lang/en.lang.php | 46 +++++++++++------------ Theme/Backend/attribute-type.tpl.php | 2 +- Theme/Backend/vehicle-profile.tpl.php | 8 ++-- tests/Controller/ApiControllerTest.php | 12 +++--- tests/Models/Vehicle.php | 2 +- 12 files changed, 65 insertions(+), 65 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6dcd721..e8d598e 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: - name: Setup Composer run: composer install - name: Autoformat - run: 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes' + run: 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes' - name: Check for modified files id: git-check run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) diff --git a/Admin/Installer.php b/Admin/Installer.php index 7529423..f45e934 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -65,7 +65,7 @@ final class Installer extends InstallerAbstract } /** @var array $types */ - $types = \json_decode($fileContent, true); + $types = \json_decode($fileContent, true); $fuelTypes = self::createFuelTypes($app, $types); /* Fuel types */ @@ -75,7 +75,7 @@ final class Installer extends InstallerAbstract } /** @var array $types */ - $types = \json_decode($fileContent, true); + $types = \json_decode($fileContent, true); $vehicleTypes = self::createVehicleTypes($app, $types); } diff --git a/Controller/ApiController.php b/Controller/ApiController.php index e75dab1..01553ae 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -400,13 +400,13 @@ final class ApiController extends Controller */ public function createVehicleFromRequest(RequestAbstract $request) : Vehicle { - $vehicle = new Vehicle(); - $vehicle->name = $request->getDataString('name') ?? ''; - $vehicle->info = $request->getDataString('info') ?? ''; - $vehicle->type = new NullVehicleType((int) ($request->getDataInt('type') ?? 0)); + $vehicle = new Vehicle(); + $vehicle->name = $request->getDataString('name') ?? ''; + $vehicle->info = $request->getDataString('info') ?? ''; + $vehicle->type = new NullVehicleType((int) ($request->getDataInt('type') ?? 0)); $vehicle->fuelType = new NullFuelType((int) ($request->getDataInt('fuel') ?? 0)); - $vehicle->status = (int) ($request->getDataInt('status') ?? VehicleStatus::INACTIVE); - $vehicle->unit = $request->getDataInt('unit') ?? $this->app->unitId; + $vehicle->status = (int) ($request->getDataInt('status') ?? VehicleStatus::INACTIVE); + $vehicle->unit = $request->getDataInt('unit') ?? $this->app->unitId; return $vehicle; } @@ -414,7 +414,7 @@ final class ApiController extends Controller /** * Create media files for vehicle * - * @param Vehicle $vehicle Vehicle + * @param Vehicle $vehicle Vehicle * @param RequestAbstract $request Request incl. media do upload * * @return void @@ -1059,7 +1059,7 @@ final class ApiController extends Controller /** @var \Modules\FleetManagement\Models\Vehicle $vehicle */ $vehicle = VehicleMapper::get()->where('id', (int) $request->getData('vehicle'))->execute(); - $path = $this->createVehicleDir($vehicle); + $path = $this->createVehicleDir($vehicle); $uploaded = []; if (!empty($uploadedFiles = $request->getFiles())) { diff --git a/Models/Vehicle.php b/Models/Vehicle.php index b5840ee..eb010e7 100644 --- a/Models/Vehicle.php +++ b/Models/Vehicle.php @@ -53,8 +53,8 @@ class Vehicle implements \JsonSerializable public function __construct() { $this->createdAt = new \DateTimeImmutable('now'); - $this->type = new VehicleType(); - $this->fuelType = new FuelType(); + $this->type = new VehicleType(); + $this->fuelType = new FuelType(); } /** diff --git a/Models/VehicleAttributeValueMapper.php b/Models/VehicleAttributeValueMapper.php index 6191dff..5699b27 100644 --- a/Models/VehicleAttributeValueMapper.php +++ b/Models/VehicleAttributeValueMapper.php @@ -37,14 +37,14 @@ final class VehicleAttributeValueMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'fleetmgmt_attr_value_id' => ['name' => 'fleetmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_attr_value_default' => ['name' => 'fleetmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], - 'fleetmgmt_attr_value_valueStr' => ['name' => 'fleetmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], - 'fleetmgmt_attr_value_valueInt' => ['name' => 'fleetmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], - 'fleetmgmt_attr_value_valueDec' => ['name' => 'fleetmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], - 'fleetmgmt_attr_value_valueDat' => ['name' => 'fleetmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], - 'fleetmgmt_attr_value_unit' => ['name' => 'fleetmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], - 'fleetmgmt_attr_value_deptype' => ['name' => 'fleetmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], + 'fleetmgmt_attr_value_id' => ['name' => 'fleetmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_attr_value_default' => ['name' => 'fleetmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], + 'fleetmgmt_attr_value_valueStr' => ['name' => 'fleetmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], + 'fleetmgmt_attr_value_valueInt' => ['name' => 'fleetmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], + 'fleetmgmt_attr_value_valueDec' => ['name' => 'fleetmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], + 'fleetmgmt_attr_value_valueDat' => ['name' => 'fleetmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], + 'fleetmgmt_attr_value_unit' => ['name' => 'fleetmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], + 'fleetmgmt_attr_value_deptype' => ['name' => 'fleetmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], 'fleetmgmt_attr_value_depvalue' => ['name' => 'fleetmgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], ]; diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php index 34a0f17..ea732e4 100644 --- a/Models/VehicleMapper.php +++ b/Models/VehicleMapper.php @@ -37,15 +37,15 @@ final class VehicleMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'fleetmgmt_vehicle_id' => ['name' => 'fleetmgmt_vehicle_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_vehicle_name' => ['name' => 'fleetmgmt_vehicle_name', 'type' => 'string', 'internal' => 'name'], - 'fleetmgmt_vehicle_status' => ['name' => 'fleetmgmt_vehicle_status', 'type' => 'int', 'internal' => 'status'], - 'fleetmgmt_vehicle_info' => ['name' => 'fleetmgmt_vehicle_info', 'type' => 'string', 'internal' => 'info'], - 'fleetmgmt_vehicle_unit' => ['name' => 'fleetmgmt_vehicle_unit', 'type' => 'int', 'internal' => 'unit'], - 'fleetmgmt_vehicle_type' => ['name' => 'fleetmgmt_vehicle_type', 'type' => 'int', 'internal' => 'type'], - 'fleetmgmt_vehicle_fuel' => ['name' => 'fleetmgmt_vehicle_fuel', 'type' => 'int', 'internal' => 'fuelType'], + 'fleetmgmt_vehicle_id' => ['name' => 'fleetmgmt_vehicle_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_name' => ['name' => 'fleetmgmt_vehicle_name', 'type' => 'string', 'internal' => 'name'], + 'fleetmgmt_vehicle_status' => ['name' => 'fleetmgmt_vehicle_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_vehicle_info' => ['name' => 'fleetmgmt_vehicle_info', 'type' => 'string', 'internal' => 'info'], + 'fleetmgmt_vehicle_unit' => ['name' => 'fleetmgmt_vehicle_unit', 'type' => 'int', 'internal' => 'unit'], + 'fleetmgmt_vehicle_type' => ['name' => 'fleetmgmt_vehicle_type', 'type' => 'int', 'internal' => 'type'], + 'fleetmgmt_vehicle_fuel' => ['name' => 'fleetmgmt_vehicle_fuel', 'type' => 'int', 'internal' => 'fuelType'], 'fleetmgmt_vehicle_responsible' => ['name' => 'fleetmgmt_vehicle_responsible', 'type' => 'int', 'internal' => 'responsible'], - 'fleetmgmt_vehicle_created_at' => ['name' => 'fleetmgmt_vehicle_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], + 'fleetmgmt_vehicle_created_at' => ['name' => 'fleetmgmt_vehicle_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], ]; /** diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index bd7015c..0792899 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -14,5 +14,5 @@ declare(strict_types=1); return ['Navigation' => [ 'FleetManagement' => 'Fleet Management', - 'Vehicles' => 'Vehicles', + 'Vehicles' => 'Vehicles', ]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index dcba1b7..12dfa07 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -13,28 +13,28 @@ declare(strict_types=1); return ['FleetManagement' => [ - 'Vehicle' => 'Vehicle', - 'Vehicles' => 'Vehicles', - 'Status' => 'Status', - 'Name' => 'Name', - 'Type' => 'Type', - 'Make' => 'Make', - 'Model' => 'Model', - 'Start' => 'Start', - 'End' => 'End', - 'Profile' => 'Profile', - 'Attributes' => 'Attributes', - 'Files' => 'Files', - 'Notes' => 'Notes', - 'Inspections' => 'Inspections', - 'Drivers' => 'Drivers', - 'Milage' => 'Milage', - 'Driver' => 'Driver', - 'Vin' => 'Vin', + 'Vehicle' => 'Vehicle', + 'Vehicles' => 'Vehicles', + 'Status' => 'Status', + 'Name' => 'Name', + 'Type' => 'Type', + 'Make' => 'Make', + 'Model' => 'Model', + 'Start' => 'Start', + 'End' => 'End', + 'Profile' => 'Profile', + 'Attributes' => 'Attributes', + 'Files' => 'Files', + 'Notes' => 'Notes', + 'Inspections' => 'Inspections', + 'Drivers' => 'Drivers', + 'Milage' => 'Milage', + 'Driver' => 'Driver', + 'Vin' => 'Vin', 'PurchasePrice' => 'Purchase Price', - 'LeasingFee' => 'Leasing Fee', - ':status1' => 'Active', - ':status2' => 'Inactive', - ':status3' => 'Damaged', - ':status4' => 'Out of order', + 'LeasingFee' => 'Leasing Fee', + ':status1' => 'Active', + ':status2' => 'Inactive', + ':status3' => 'Damaged', + ':status4' => 'Out of order', ]]; diff --git a/Theme/Backend/attribute-type.tpl.php b/Theme/Backend/attribute-type.tpl.php index 378a585..bed6997 100755 --- a/Theme/Backend/attribute-type.tpl.php +++ b/Theme/Backend/attribute-type.tpl.php @@ -18,7 +18,7 @@ use phpOMS\Localization\ISO639Enum; $types = AttributeValueType::getConstants(); $attribute = $this->getData('attribute'); -$l11ns = $this->getData('l11ns'); +$l11ns = $this->getData('l11ns'); echo $this->getData('nav')->render(); ?> diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 9f6123f..1f2e22f 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -17,15 +17,15 @@ use Modules\FleetManagement\Models\VehicleStatus; use Modules\Media\Models\NullMedia; use phpOMS\Uri\UriFactory; -$countryCodes = \phpOMS\Localization\ISO3166TwoEnum::getConstants(); -$countries = \phpOMS\Localization\ISO3166NameEnum::getConstants(); +$countryCodes = \phpOMS\Localization\ISO3166TwoEnum::getConstants(); +$countries = \phpOMS\Localization\ISO3166NameEnum::getConstants(); $vehicleStatus = VehicleStatus::getConstants(); /** * @var \Modules\FleetManagement\Models\Vehicle $vehicle */ -$vehicle = $this->getData('vehicle') ?? new NullVehicle(); -$files = $vehicle->getFiles(); +$vehicle = $this->getData('vehicle') ?? new NullVehicle(); +$files = $vehicle->getFiles(); $vehicleImage = $this->getData('vehicleImage') ?? new NullMedia(); $vehicleTypes = $this->getData('types') ?? []; diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 5054ad3..83f38c9 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -53,13 +53,13 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase protected string $appName = 'Api'; }; - $this->app->dbPool = $GLOBALS['dbpool']; + $this->app->dbPool = $GLOBALS['dbpool']; $this->app->unitId = 1; - $this->app->accountManager = new AccountManager($GLOBALS['session']); - $this->app->appSettings = new CoreSettings(); - $this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../../Modules/'); - $this->app->dispatcher = new Dispatcher($this->app); - $this->app->eventManager = new EventManager($this->app->dispatcher); + $this->app->accountManager = new AccountManager($GLOBALS['session']); + $this->app->appSettings = new CoreSettings(); + $this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../../Modules/'); + $this->app->dispatcher = new Dispatcher($this->app); + $this->app->eventManager = new EventManager($this->app->dispatcher); $this->app->eventManager->importFromFile(__DIR__ . '/../../../../Web/Api/Hooks.php'); $this->app->sessionManager = new HttpSession(36000); $this->app->l11nManager = new L11nManager(); diff --git a/tests/Models/Vehicle.php b/tests/Models/Vehicle.php index 73ac808..c8104dc 100755 --- a/tests/Models/Vehicle.php +++ b/tests/Models/Vehicle.php @@ -17,4 +17,4 @@ namespace Modules\FleetManagement\Models; class Vehicle { public int $id = 0; -} \ No newline at end of file +} From a2ffb8cc2fd085b6e6b4f1bbdaa6b8c4b89a4f03 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 28 May 2023 12:38:27 +0000 Subject: [PATCH 16/89] phcbf autofixes --- .gitignore | 1 + Admin/Installer.php | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 22d0d82..03b6968 100755 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vendor +Build diff --git a/Admin/Installer.php b/Admin/Installer.php index f45e934..d274d97 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -65,8 +65,8 @@ final class Installer extends InstallerAbstract } /** @var array $types */ - $types = \json_decode($fileContent, true); - $fuelTypes = self::createFuelTypes($app, $types); + $types = \json_decode($fileContent, true); + $fuelTypes = self::createFuelTypes($app, $types); /* Fuel types */ $fileContent = \file_get_contents(__DIR__ . '/Install/vehicletype.json'); @@ -75,8 +75,8 @@ final class Installer extends InstallerAbstract } /** @var array $types */ - $types = \json_decode($fileContent, true); - $vehicleTypes = self::createVehicleTypes($app, $types); + $types = \json_decode($fileContent, true); + $vehicleTypes = self::createVehicleTypes($app, $types); } /** From 21a4af40e93cef90fda882e1e94daeaf314c0886 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 28 May 2023 12:40:01 +0000 Subject: [PATCH 17/89] add phpcbf fixes --- .github/workflows/main.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8d598e..095dbc6 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,8 +25,21 @@ jobs: restore-keys: ${{ runner.os }}-composer- - name: Setup Composer run: composer install + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + - name: Checkout Build Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + ref: develop + repository: Karaka-Management/Build + path: Build - name: Autoformat - run: 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes' + run: | + 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes' + php vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ - name: Check for modified files id: git-check run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) From 6e0198bac2dca6f1f3bd1a96f5ed60502d476ef7 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 28 May 2023 13:11:25 +0000 Subject: [PATCH 18/89] start fixing composer --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 095dbc6..7db49b1 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,6 +40,7 @@ jobs: run: | 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes' php vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ + vendor/bin/rector process --config Build/Config/rector.php ./ - name: Check for modified files id: git-check run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) From cdee2e17ed1c6f55543987caeefb15cfffecd8f5 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 28 May 2023 13:51:31 +0000 Subject: [PATCH 19/89] expand composer --- composer.json | 3 +- composer.lock | 88 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 6fc1e5d..1786c28 100755 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "squizlabs/php_codesniffer": ">=3.6", "phpmd/phpmd": ">=2.9", "phpstan/phpstan": ">=1.8.6", - "phan/phan": ">=3.2.6" + "phan/phan": ">=3.2.6", + "rector/rector": "^0.16.0" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/composer.lock b/composer.lock index 1885692..e706042 100755 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "83c956950eced6728b0e73b4374aacd7", + "content-hash": "64d7374a3cbdb7713d00fa01717ec92c", "packages": [], "packages-dev": [ { @@ -1399,16 +1399,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.5.4", + "version": "1.10.15", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "bbf68cae24f6dc023c607ea0f87da55dd9d55c2b" + "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bbf68cae24f6dc023c607ea0f87da55dd9d55c2b", - "reference": "bbf68cae24f6dc023c607ea0f87da55dd9d55c2b", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/762c4dac4da6f8756eebb80e528c3a47855da9bd", + "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd", "shasum": "" }, "require": { @@ -1432,9 +1432,16 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.5.4" + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { @@ -1445,16 +1452,12 @@ "url": "https://github.com/phpstan", "type": "github" }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, { "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", "type": "tidelift" } ], - "time": "2022-04-03T12:39:00+00:00" + "time": "2023-05-09T15:28:01+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2079,6 +2082,67 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "rector/rector", + "version": "0.16.0", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "2125ff71ea05b079562a8f59ca48a97eb78dc07f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/2125ff71ea05b079562a8f59ca48a97eb78dc07f", + "reference": "2125ff71ea05b079562a8f59ca48a97eb78dc07f", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.14" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.15-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.16.0" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-05-05T12:12:17+00:00" + }, { "name": "sabre/event", "version": "5.1.4", @@ -4798,5 +4862,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.2.0" } From 44abf6044de179c786765ddff100325c4bdfb3be Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 30 May 2023 01:41:22 +0200 Subject: [PATCH 20/89] Implement Inspections and BaseStringL11nType --- Admin/Install/db.json | 88 +++++++++++++ Controller/ApiController.php | 30 ++--- Models/FuelType.php | 121 ------------------ Models/FuelTypeMapper.php | 5 +- Models/Inspection.php | 54 ++++++++ Models/InspectionMapper.php | 84 ++++++++++++ Models/InspectionMapper_.php | 0 ...{NullFuelType.php => InspectionStatus.php} | 30 ++--- Models/InspectionTypeL11nMapper.php | 69 ++++++++++ Models/InspectionTypeMapper.php | 83 ++++++++++++ Models/NullVehicleType.php | 46 ------- Models/Vehicle.php | 8 +- Models/VehicleType.php | 121 ------------------ Models/VehicleTypeL11nMapper.php | 1 - Models/VehicleTypeMapper.php | 8 +- 15 files changed, 415 insertions(+), 333 deletions(-) delete mode 100644 Models/FuelType.php create mode 100644 Models/InspectionMapper.php delete mode 100644 Models/InspectionMapper_.php rename Models/{NullFuelType.php => InspectionStatus.php} (52%) create mode 100644 Models/InspectionTypeL11nMapper.php create mode 100644 Models/InspectionTypeMapper.php delete mode 100644 Models/NullVehicleType.php delete mode 100644 Models/VehicleType.php diff --git a/Admin/Install/db.json b/Admin/Install/db.json index ddda20c..f790e47 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -95,6 +95,54 @@ } } }, + "fleetmgmt_inspection_type": { + "name": "fleetmgmt_inspection_type", + "fields": { + "fleetmgmt_inspection_type_id": { + "name": "fleetmgmt_inspection_type_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_inspection_type_name": { + "name": "fleetmgmt_inspection_type_name", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "fleetmgmt_inspection_type_l11n": { + "name": "fleetmgmt_inspection_type_l11n", + "fields": { + "fleetmgmt_inspection_type_l11n_id": { + "name": "fleetmgmt_inspection_type_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_inspection_type_l11n_title": { + "name": "fleetmgmt_inspection_type_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_inspection_type_l11n_type": { + "name": "fleetmgmt_inspection_type_l11n_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_inspection_type", + "foreignKey": "fleetmgmt_inspection_type_id" + }, + "fleetmgmt_inspection_type_l11n_lang": { + "name": "fleetmgmt_inspection_type_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, "fleetmgmt_vehicle": { "name": "fleetmgmt_vehicle", "fields": { @@ -155,6 +203,46 @@ } } }, + "fleetmgmt_vehicle_inspection": { + "name": "fleetmgmt_vehicle_inspection", + "fields": { + "fleetmgmt_vehicle_inspection_id": { + "name": "fleetmgmt_vehicle_inspection_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_vehicle_inspection_description": { + "name": "fleetmgmt_vehicle_inspection_description", + "type": "TEXT", + "null": false + }, + "fleetmgmt_vehicle_inspection_status": { + "name": "fleetmgmt_vehicle_inspection_status", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_vehicle_inspection_interval": { + "name": "fleetmgmt_vehicle_inspection_interval", + "type": "TINYINT(3)", + "null": false + }, + "fleetmgmt_vehicle_inspection_next": { + "name": "fleetmgmt_vehicle_inspection_next", + "type": "DATETIME", + "null": true, + "default": null + }, + "fleetmgmt_vehicle_inspection_type": { + "name": "fleetmgmt_vehicle_inspection_type", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_inspection_type", + "foreignKey": "fleetmgmt_inspection_type_id" + } + } + }, "fleetmgmt_vehicle_usage": { "name": "fleetmgmt_vehicle_usage", "fields": { diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 01553ae..5c2a874 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -20,11 +20,8 @@ use Modules\Attribute\Models\AttributeType; use Modules\Attribute\Models\AttributeValue; use Modules\Attribute\Models\NullAttributeType; use Modules\Attribute\Models\NullAttributeValue; -use Modules\FleetManagement\Models\FuelType; use Modules\FleetManagement\Models\FuelTypeL11nMapper; use Modules\FleetManagement\Models\FuelTypeMapper; -use Modules\FleetManagement\Models\NullFuelType; -use Modules\FleetManagement\Models\NullVehicleType; use Modules\FleetManagement\Models\Vehicle; use Modules\FleetManagement\Models\VehicleAttributeMapper; use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; @@ -33,7 +30,8 @@ use Modules\FleetManagement\Models\VehicleAttributeValueL11nMapper; use Modules\FleetManagement\Models\VehicleAttributeValueMapper; use Modules\FleetManagement\Models\VehicleMapper; use Modules\FleetManagement\Models\VehicleStatus; -use Modules\FleetManagement\Models\VehicleType; +use phpOMS\Localization\NullBaseStringL11nType; +use phpOMS\Localization\BaseStringL11nType; use Modules\FleetManagement\Models\VehicleTypeL11nMapper; use Modules\FleetManagement\Models\VehicleTypeMapper; use Modules\Media\Models\CollectionMapper; @@ -81,7 +79,7 @@ final class ApiController extends Controller return; } - /** @var VehicleType $vehicle */ + /** @var BaseStringL11nType $vehicle */ $vehicle = $this->createVehicleTypeFromRequest($request); $this->createModel($request->header->account, $vehicle, VehicleTypeMapper::class, 'vehicle_type', $request->getOrigin()); @@ -100,14 +98,14 @@ final class ApiController extends Controller * * @param RequestAbstract $request Request * - * @return VehicleType Returns the created vehicle from the request + * @return BaseStringL11nType Returns the created vehicle from the request * * @since 1.0.0 */ - public function createVehicleTypeFromRequest(RequestAbstract $request) : VehicleType + public function createVehicleTypeFromRequest(RequestAbstract $request) : BaseStringL11nType { - $type = new VehicleType(); - $type->name = $request->getDataString('name') ?? ''; + $type = new BaseStringL11nType(); + $type->title = $request->getDataString('name') ?? ''; $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); return $type; @@ -225,7 +223,7 @@ final class ApiController extends Controller return; } - /** @var FuelType $vehicle */ + /** @var BaseStringL11nType $vehicle */ $vehicle = $this->createFuelTypeFromRequest($request); $this->createModel($request->header->account, $vehicle, FuelTypeMapper::class, 'fuel_type', $request->getOrigin()); @@ -244,14 +242,14 @@ final class ApiController extends Controller * * @param RequestAbstract $request Request * - * @return FuelType Returns the created vehicle from the request + * @return BaseStringL11nType Returns the created vehicle from the request * * @since 1.0.0 */ - public function createFuelTypeFromRequest(RequestAbstract $request) : FuelType + public function createFuelTypeFromRequest(RequestAbstract $request) : BaseStringL11nType { - $type = new FuelType(); - $type->name = $request->getDataString('name') ?? ''; + $type = new BaseStringL11nType(); + $type->title = $request->getDataString('name') ?? ''; $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); return $type; @@ -403,8 +401,8 @@ final class ApiController extends Controller $vehicle = new Vehicle(); $vehicle->name = $request->getDataString('name') ?? ''; $vehicle->info = $request->getDataString('info') ?? ''; - $vehicle->type = new NullVehicleType((int) ($request->getDataInt('type') ?? 0)); - $vehicle->fuelType = new NullFuelType((int) ($request->getDataInt('fuel') ?? 0)); + $vehicle->type = new NullBaseStringL11nType((int) ($request->getDataInt('type') ?? 0)); + $vehicle->fuelType = new NullBaseStringL11nType((int) ($request->getDataInt('fuel') ?? 0)); $vehicle->status = (int) ($request->getDataInt('status') ?? VehicleStatus::INACTIVE); $vehicle->unit = $request->getDataInt('unit') ?? $this->app->unitId; diff --git a/Models/FuelType.php b/Models/FuelType.php deleted file mode 100644 index 2c7c5e2..0000000 --- a/Models/FuelType.php +++ /dev/null @@ -1,121 +0,0 @@ -name = $name; - } - - /** - * Set l11n - * - * @param string|BaseStringL11n $l11n Tag article l11n - * @param string $lang Language - * - * @return void - * - * @since 1.0.0 - */ - public function setL11n(string | BaseStringL11n $l11n, string $lang = ISO639x1Enum::_EN) : void - { - if ($l11n instanceof BaseStringL11n) { - $this->l11n = $l11n; - } elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) { - $this->l11n->content = $l11n; - $this->l11n->setLanguage($lang); - } else { - $this->l11n = new BaseStringL11n(); - $this->l11n->content = $l11n; - $this->l11n->setLanguage($lang); - } - } - - /** - * @return string - * - * @since 1.0.0 - */ - public function getL11n() : string - { - if (!isset($this->l11n)) { - return ''; - } - - return $this->l11n instanceof BaseStringL11n ? $this->l11n->content : $this->l11n; - } - - /** - * {@inheritdoc} - */ - public function toArray() : array - { - return [ - 'id' => $this->id, - 'name' => $this->name, - ]; - } - - /** - * {@inheritdoc} - */ - public function jsonSerialize() : mixed - { - return $this->toArray(); - } -} diff --git a/Models/FuelTypeMapper.php b/Models/FuelTypeMapper.php index 10c16f0..0059b21 100644 --- a/Models/FuelTypeMapper.php +++ b/Models/FuelTypeMapper.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; +use phpOMS\Localization\BaseStringL11nType; /** * Item mapper class. @@ -37,7 +38,7 @@ final class FuelTypeMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_fuel_type_id' => ['name' => 'fleetmgmt_fuel_type_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_fuel_type_name' => ['name' => 'fleetmgmt_fuel_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'fleetmgmt_fuel_type_name' => ['name' => 'fleetmgmt_fuel_type_name', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], ]; /** @@ -62,7 +63,7 @@ final class FuelTypeMapper extends DataMapperFactory * @var class-string * @since 1.0.0 */ - public const MODEL = FuelType::class; + public const MODEL = BaseStringL11nType::class; /** * Primary table. diff --git a/Models/Inspection.php b/Models/Inspection.php index e69de29..3d90bb2 100644 --- a/Models/Inspection.php +++ b/Models/Inspection.php @@ -0,0 +1,54 @@ +type = new BaseStringL11nType(); + } + + use \Modules\Media\Models\MediaListTrait; +} diff --git a/Models/InspectionMapper.php b/Models/InspectionMapper.php new file mode 100644 index 0000000..66a798b --- /dev/null +++ b/Models/InspectionMapper.php @@ -0,0 +1,84 @@ + + */ +final class InspectionMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_vehicle_inspection_id' => ['name' => 'fleetmgmt_vehicle_inspection_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_inspection_description' => ['name' => 'fleetmgmt_vehicle_inspection_description', 'type' => 'string', 'internal' => 'description'], + 'fleetmgmt_vehicle_inspection_status' => ['name' => 'fleetmgmt_vehicle_inspection_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_vehicle_inspection_interval' => ['name' => 'fleetmgmt_vehicle_inspection_interval', 'type' => 'int', 'internal' => 'interval'], + 'fleetmgmt_vehicle_inspection_next' => ['name' => 'fleetmgmt_vehicle_inspection_next', 'type' => 'DateTime', 'internal' => 'next'], + 'fleetmgmt_vehicle_inspection_type' => ['name' => 'fleetmgmt_vehicle_inspection_type', 'type' => 'int', 'internal' => 'type'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'type' => [ + 'mapper' => InspectionTypeMapper::class, + 'external' => 'fleetmgmt_vehicle_inspection_type', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_vehicle_inspection'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_vehicle_inspection_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = Inspection::class; +} diff --git a/Models/InspectionMapper_.php b/Models/InspectionMapper_.php deleted file mode 100644 index e69de29..0000000 diff --git a/Models/NullFuelType.php b/Models/InspectionStatus.php similarity index 52% rename from Models/NullFuelType.php rename to Models/InspectionStatus.php index 9502384..c4a8921 100644 --- a/Models/NullFuelType.php +++ b/Models/InspectionStatus.php @@ -14,33 +14,23 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; +use phpOMS\Stdlib\Base\Enum; + /** - * Null model + * Inspection status enum. * * @package Modules\FleetManagement\Models * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 */ -final class NullFuelType extends FuelType +abstract class InspectionStatus extends Enum { - /** - * Constructor - * - * @param int $id Model id - * - * @since 1.0.0 - */ - public function __construct(int $id = 0) - { - $this->id = $id; - } + public const DONE = 1; - /** - * {@inheritdoc} - */ - public function jsonSerialize() : mixed - { - return ['id' => $this->id]; - } + public const PASSED = 2; + + public const ONGOING = 4; + + public const TODO = 5; } diff --git a/Models/InspectionTypeL11nMapper.php b/Models/InspectionTypeL11nMapper.php new file mode 100644 index 0000000..f5485ff --- /dev/null +++ b/Models/InspectionTypeL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class InspectionTypeL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_inspection_type_l11n_id' => ['name' => 'fleetmgmt_inspection_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_inspection_type_l11n_title' => ['name' => 'fleetmgmt_inspection_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_inspection_type_l11n_type' => ['name' => 'fleetmgmt_inspection_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_inspection_type_l11n_lang' => ['name' => 'fleetmgmt_inspection_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_inspection_type_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_inspection_type_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/InspectionTypeMapper.php b/Models/InspectionTypeMapper.php new file mode 100644 index 0000000..01ddbe5 --- /dev/null +++ b/Models/InspectionTypeMapper.php @@ -0,0 +1,83 @@ + + */ +final class InspectionTypeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_inspection_type_id' => ['name' => 'fleetmgmt_inspection_type_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_inspection_type_name' => ['name' => 'fleetmgmt_inspection_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => FuelTypeL11nMapper::class, + 'table' => 'fleetmgmt_inspection_type_l11n', + 'self' => 'fleetmgmt_inspection_type_l11n_type', + 'column' => 'content', + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11nType::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_inspection_type'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_inspection_type_id'; +} diff --git a/Models/NullVehicleType.php b/Models/NullVehicleType.php deleted file mode 100644 index cee550b..0000000 --- a/Models/NullVehicleType.php +++ /dev/null @@ -1,46 +0,0 @@ -id = $id; - } - - /** - * {@inheritdoc} - */ - public function jsonSerialize() : mixed - { - return ['id' => $this->id]; - } -} diff --git a/Models/Vehicle.php b/Models/Vehicle.php index eb010e7..d16c316 100644 --- a/Models/Vehicle.php +++ b/Models/Vehicle.php @@ -14,8 +14,10 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; +use phpOMS\Localization\BaseStringL11n; + /** - * class. + * Vehicle class. * * @package Modules\Attribute\Models * @license OMS License 2.0 @@ -30,7 +32,7 @@ class Vehicle implements \JsonSerializable public int $status = VehicleStatus::ACTIVE; - public VehicleType $type; + public BaseStringL11n $type; public FuelType $fuelType; @@ -53,7 +55,7 @@ class Vehicle implements \JsonSerializable public function __construct() { $this->createdAt = new \DateTimeImmutable('now'); - $this->type = new VehicleType(); + $this->type = new BaseStringL11n(); $this->fuelType = new FuelType(); } diff --git a/Models/VehicleType.php b/Models/VehicleType.php deleted file mode 100644 index c3c2bf9..0000000 --- a/Models/VehicleType.php +++ /dev/null @@ -1,121 +0,0 @@ -name = $name; - } - - /** - * Set l11n - * - * @param string|BaseStringL11n $l11n Tag article l11n - * @param string $lang Language - * - * @return void - * - * @since 1.0.0 - */ - public function setL11n(string | BaseStringL11n $l11n, string $lang = ISO639x1Enum::_EN) : void - { - if ($l11n instanceof BaseStringL11n) { - $this->l11n = $l11n; - } elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) { - $this->l11n->content = $l11n; - $this->l11n->setLanguage($lang); - } else { - $this->l11n = new BaseStringL11n(); - $this->l11n->content = $l11n; - $this->l11n->setLanguage($lang); - } - } - - /** - * @return string - * - * @since 1.0.0 - */ - public function getL11n() : string - { - if (!isset($this->l11n)) { - return ''; - } - - return $this->l11n instanceof BaseStringL11n ? $this->l11n->content : $this->l11n; - } - - /** - * {@inheritdoc} - */ - public function toArray() : array - { - return [ - 'id' => $this->id, - 'name' => $this->name, - ]; - } - - /** - * {@inheritdoc} - */ - public function jsonSerialize() : mixed - { - return $this->toArray(); - } -} diff --git a/Models/VehicleTypeL11nMapper.php b/Models/VehicleTypeL11nMapper.php index 87ef2c8..48a6eb2 100644 --- a/Models/VehicleTypeL11nMapper.php +++ b/Models/VehicleTypeL11nMapper.php @@ -40,7 +40,6 @@ final class VehicleTypeL11nMapper extends DataMapperFactory 'fleetmgmt_vehicle_type_l11n_id' => ['name' => 'fleetmgmt_vehicle_type_l11n_id', 'type' => 'int', 'internal' => 'id'], 'fleetmgmt_vehicle_type_l11n_title' => ['name' => 'fleetmgmt_vehicle_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], 'fleetmgmt_vehicle_type_l11n_type' => ['name' => 'fleetmgmt_vehicle_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], - 'fleetmgmt_vehicle_type_l11n_lang' => ['name' => 'fleetmgmt_vehicle_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], ]; /** diff --git a/Models/VehicleTypeMapper.php b/Models/VehicleTypeMapper.php index b188470..f222719 100644 --- a/Models/VehicleTypeMapper.php +++ b/Models/VehicleTypeMapper.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; +use phpOMS\Localization\BaseStringL11nType; /** * Item mapper class. @@ -24,7 +25,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; * @link https://jingga.app * @since 1.0.0 * - * @template T of VehicleType + * @template T of BaseStringL11nType * @extends DataMapperFactory */ final class VehicleTypeMapper extends DataMapperFactory @@ -37,7 +38,8 @@ final class VehicleTypeMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_vehicle_type_id' => ['name' => 'fleetmgmt_vehicle_type_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_vehicle_type_name' => ['name' => 'fleetmgmt_vehicle_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'fleetmgmt_vehicle_type_name' => ['name' => 'fleetmgmt_vehicle_type_name', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], + ]; /** @@ -62,7 +64,7 @@ final class VehicleTypeMapper extends DataMapperFactory * @var class-string * @since 1.0.0 */ - public const MODEL = VehicleType::class; + public const MODEL = BaseStringL11nType::class; /** * Primary table. From 28f9162c10bd04792e3485323fc2bb58825890f2 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 30 May 2023 02:05:40 +0200 Subject: [PATCH 21/89] Switch to BaseStringL11nType --- Controller/ApiController.php | 146 ++++++++++++++++++++++++++++++++ Models/FuelTypeMapper.php | 2 +- Models/InspectionTypeMapper.php | 4 +- Models/PermissionCategory.php | 10 +++ 4 files changed, 159 insertions(+), 3 deletions(-) diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 5c2a874..a83a70e 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -22,6 +22,8 @@ use Modules\Attribute\Models\NullAttributeType; use Modules\Attribute\Models\NullAttributeValue; use Modules\FleetManagement\Models\FuelTypeL11nMapper; use Modules\FleetManagement\Models\FuelTypeMapper; +use Modules\FleetManagement\Models\InspectionTypeL11nMapper; +use Modules\FleetManagement\Models\InspectionTypeMapper; use Modules\FleetManagement\Models\Vehicle; use Modules\FleetManagement\Models\VehicleAttributeMapper; use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; @@ -1177,4 +1179,148 @@ final class ApiController extends Controller return []; } + + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateInspectionTypeCreate($request))) { + $response->set($request->uri->__toString(), new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var BaseStringL11nType $vehicle */ + $vehicle = $this->createInspectionTypeFromRequest($request); + $this->createModel($request->header->account, $vehicle, InspectionTypeMapper::class, 'inspection_type', $request->getOrigin()); + + $this->fillJsonResponse( + $request, + $response, + NotificationLevel::OK, + '', + $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $vehicle + ); + } + + /** + * Method to create vehicle from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11nType Returns the created vehicle from the request + * + * @since 1.0.0 + */ + public function createInspectionTypeFromRequest(RequestAbstract $request) : BaseStringL11nType + { + $type = new BaseStringL11nType(); + $type->title = $request->getDataString('name') ?? ''; + $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + + return $type; + } + + /** + * Validate vehicle create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateInspectionTypeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['name'] = !$request->hasData('name')) + || ($val['title'] = !$request->hasData('title')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateInspectionTypeL11nCreate($request))) { + $response->set('inspection_type_l11n_create', new FormValidation($val)); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $typeL11n = $this->createInspectionTypeL11nFromRequest($request); + $this->createModel($request->header->account, $typeL11n, InspectionTypeL11nMapper::class, 'inspection_type_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + } + + /** + * Method to create vehicle attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createInspectionTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $typeL11n = new BaseStringL11n(); + $typeL11n->ref = $request->getDataInt('type') ?? 0; + $typeL11n->setLanguage( + $request->getDataString('language') ?? $request->getLanguage() + ); + $typeL11n->content = $request->getDataString('title') ?? ''; + + return $typeL11n; + } + + /** + * Validate vehicle attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateInspectionTypeL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['type'] = !$request->hasData('type')) + ) { + return $val; + } + + return []; + } } diff --git a/Models/FuelTypeMapper.php b/Models/FuelTypeMapper.php index 0059b21..d1c5eec 100644 --- a/Models/FuelTypeMapper.php +++ b/Models/FuelTypeMapper.php @@ -25,7 +25,7 @@ use phpOMS\Localization\BaseStringL11nType; * @link https://jingga.app * @since 1.0.0 * - * @template T of FuelType + * @template T of BaseStringL11nType * @extends DataMapperFactory */ final class FuelTypeMapper extends DataMapperFactory diff --git a/Models/InspectionTypeMapper.php b/Models/InspectionTypeMapper.php index 01ddbe5..f7df79f 100644 --- a/Models/InspectionTypeMapper.php +++ b/Models/InspectionTypeMapper.php @@ -25,7 +25,7 @@ use phpOMS\Localization\BaseStringL11nType; * @link https://jingga.app * @since 1.0.0 * - * @template T of FuelType + * @template T of BaseStringL11nType * @extends DataMapperFactory */ final class InspectionTypeMapper extends DataMapperFactory @@ -49,7 +49,7 @@ final class InspectionTypeMapper extends DataMapperFactory */ public const HAS_MANY = [ 'l11n' => [ - 'mapper' => FuelTypeL11nMapper::class, + 'mapper' => InspectionTypeL11nMapper::class, 'table' => 'fleetmgmt_inspection_type_l11n', 'self' => 'fleetmgmt_inspection_type_l11n_type', 'column' => 'content', diff --git a/Models/PermissionCategory.php b/Models/PermissionCategory.php index 0dd83ba..f13ab8f 100755 --- a/Models/PermissionCategory.php +++ b/Models/PermissionCategory.php @@ -27,4 +27,14 @@ use phpOMS\Stdlib\Base\Enum; abstract class PermissionCategory extends Enum { public const VEHICLE = 1; + + public const FUEL_TYPE = 2; + + public const VEHICLE_TYPE = 3; + + public const INSPECTION_TYPE = 4; + + public const INSPECTION = 5; + + public const ATTRIBUTE_TYPE = 6; } From 2951f6d2758cac558bcb4c0bb0cd0c81d1b4ac10 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 30 May 2023 02:37:01 +0200 Subject: [PATCH 22/89] remove getId() --- Models/Vehicle.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Models/Vehicle.php b/Models/Vehicle.php index d16c316..fb1b779 100644 --- a/Models/Vehicle.php +++ b/Models/Vehicle.php @@ -14,7 +14,7 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; -use phpOMS\Localization\BaseStringL11n; +use phpOMS\Localization\BaseStringL11nType; /** * Vehicle class. @@ -32,9 +32,9 @@ class Vehicle implements \JsonSerializable public int $status = VehicleStatus::ACTIVE; - public BaseStringL11n $type; + public BaseStringL11nType $type; - public FuelType $fuelType; + public BaseStringL11nType $fuelType; public string $info = ''; @@ -55,8 +55,8 @@ class Vehicle implements \JsonSerializable public function __construct() { $this->createdAt = new \DateTimeImmutable('now'); - $this->type = new BaseStringL11n(); - $this->fuelType = new FuelType(); + $this->type = new BaseStringL11nType(); + $this->fuelType = new BaseStringL11nType(); } /** From 2ea7a004d6ace73d49292e5460970ad0675f8abc Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 30 May 2023 03:42:46 +0200 Subject: [PATCH 23/89] use direct data access for response data --- Controller/ApiController.php | 38 +++++++++++++-------------- Theme/Backend/vehicle-profile.tpl.php | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Controller/ApiController.php b/Controller/ApiController.php index a83a70e..478dbdb 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -75,7 +75,7 @@ final class ApiController extends Controller public function apiVehicleTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleTypeCreate($request))) { - $response->set($request->uri->__toString(), new FormValidation($val)); + $response->data[$request->uri->__toString()] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -150,7 +150,7 @@ final class ApiController extends Controller public function apiVehicleTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleTypeL11nCreate($request))) { - $response->set('vehicle_type_l11n_create', new FormValidation($val)); + $response->data['vehicle_type_l11n_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -219,7 +219,7 @@ final class ApiController extends Controller public function apiFuelTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateFuelTypeCreate($request))) { - $response->set($request->uri->__toString(), new FormValidation($val)); + $response->data[$request->uri->__toString()] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -294,7 +294,7 @@ final class ApiController extends Controller public function apiFuelTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateFuelTypeL11nCreate($request))) { - $response->set('fuel_type_l11n_create', new FormValidation($val)); + $response->data['fuel_type_l11n_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -363,7 +363,7 @@ final class ApiController extends Controller public function apiVehicleCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleCreate($request))) { - $response->set($request->uri->__toString(), new FormValidation($val)); + $response->data[$request->uri->__toString()] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -373,7 +373,7 @@ final class ApiController extends Controller $vehicle = $this->createVehicleFromRequest($request); $this->createModel($request->header->account, $vehicle, VehicleMapper::class, 'vehicle', $request->getOrigin()); - if (!empty($request->getFiles()) + if (!empty($request->files) || !empty($request->getDataJson('media')) ) { $this->createVehicleMedia($vehicle, $request); @@ -425,7 +425,7 @@ final class ApiController extends Controller { $path = $this->createVehicleDir($vehicle); - if (!empty($uploadedFiles = $request->getFiles())) { + if (!empty($uploadedFiles = $request->files)) { $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( names: [], fileNames: [], @@ -561,7 +561,7 @@ final class ApiController extends Controller public function apiVehicleAttributeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleAttributeCreate($request))) { - $response->set('attribute_create', new FormValidation($val)); + $response->data['attribute_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -640,7 +640,7 @@ final class ApiController extends Controller public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleAttributeUpdate($request))) { - $response->set('attribute_update', new FormValidation($val)); + $response->data['attribute_update'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -730,7 +730,7 @@ final class ApiController extends Controller public function apiVehicleAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleAttributeTypeL11nCreate($request))) { - $response->set('attr_type_l11n_create', new FormValidation($val)); + $response->data['attr_type_l11n_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -799,7 +799,7 @@ final class ApiController extends Controller public function apiVehicleAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleAttributeTypeCreate($request))) { - $response->set('attr_type_create', new FormValidation($val)); + $response->data['attr_type_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -870,7 +870,7 @@ final class ApiController extends Controller public function apiVehicleAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleAttributeValueCreate($request))) { - $response->set('attr_value_create', new FormValidation($val)); + $response->data['attr_value_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -955,7 +955,7 @@ final class ApiController extends Controller public function apiVehicleAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { - $response->set('attr_value_l11n_create', new FormValidation($val)); + $response->data['attr_value_l11n_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -1024,7 +1024,7 @@ final class ApiController extends Controller public function apiVehicleAttribute(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { - $response->set('attr_value_l11n_create', new FormValidation($val)); + $response->data['attr_value_l11n_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -1051,7 +1051,7 @@ final class ApiController extends Controller public function apiMediaAddToVehicle(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateMediaAddToVehicle($request))) { - $response->set($request->uri->__toString(), new FormValidation($val)); + $response->data[$request->uri->__toString()] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -1062,7 +1062,7 @@ final class ApiController extends Controller $path = $this->createVehicleDir($vehicle); $uploaded = []; - if (!empty($uploadedFiles = $request->getFiles())) { + if (!empty($uploadedFiles = $request->files)) { $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( names: [], fileNames: [], @@ -1171,7 +1171,7 @@ final class ApiController extends Controller private function validateMediaAddToVehicle(RequestAbstract $request) : array { $val = []; - if (($val['media'] = (!$request->hasData('media') && empty($request->getFiles()))) + if (($val['media'] = (!$request->hasData('media') && empty($request->files))) || ($val['vehicle'] = !$request->hasData('vehicle')) ) { return $val; @@ -1196,7 +1196,7 @@ final class ApiController extends Controller public function apiInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateInspectionTypeCreate($request))) { - $response->set($request->uri->__toString(), new FormValidation($val)); + $response->data[$request->uri->__toString()] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; @@ -1271,7 +1271,7 @@ final class ApiController extends Controller public function apiInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateInspectionTypeL11nCreate($request))) { - $response->set('inspection_type_l11n_create', new FormValidation($val)); + $response->data['inspection_type_l11n_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 1f2e22f..f22b656 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -25,7 +25,7 @@ $vehicleStatus = VehicleStatus::getConstants(); * @var \Modules\FleetManagement\Models\Vehicle $vehicle */ $vehicle = $this->getData('vehicle') ?? new NullVehicle(); -$files = $vehicle->getFiles(); +$files = $vehicle->files; $vehicleImage = $this->getData('vehicleImage') ?? new NullMedia(); $vehicleTypes = $this->getData('types') ?? []; From fe4ad79ba2d2b48865d38418c924b7237c27dd5f Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 30 May 2023 04:15:36 +0200 Subject: [PATCH 24/89] continue with getter/setter removal --- Controller/ApiController.php | 18 +++++++++--------- Controller/BackendController.php | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 478dbdb..206393e 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -90,7 +90,7 @@ final class ApiController extends Controller $response, NotificationLevel::OK, '', - $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), $vehicle ); } @@ -175,7 +175,7 @@ final class ApiController extends Controller $typeL11n = new BaseStringL11n(); $typeL11n->ref = $request->getDataInt('type') ?? 0; $typeL11n->setLanguage( - $request->getDataString('language') ?? $request->getLanguage() + $request->getDataString('language') ?? $request->header->l11n->language ); $typeL11n->content = $request->getDataString('title') ?? ''; @@ -234,7 +234,7 @@ final class ApiController extends Controller $response, NotificationLevel::OK, '', - $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), $vehicle ); } @@ -319,7 +319,7 @@ final class ApiController extends Controller $typeL11n = new BaseStringL11n(); $typeL11n->ref = $request->getDataInt('type') ?? 0; $typeL11n->setLanguage( - $request->getDataString('language') ?? $request->getLanguage() + $request->getDataString('language') ?? $request->header->l11n->language ); $typeL11n->content = $request->getDataString('title') ?? ''; @@ -384,7 +384,7 @@ final class ApiController extends Controller $response, NotificationLevel::OK, '', - $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), $vehicle ); } @@ -755,7 +755,7 @@ final class ApiController extends Controller $attrL11n = new BaseStringL11n(); $attrL11n->ref = $request->getDataInt('type') ?? 0; $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->getLanguage() + $request->getDataString('language') ?? $request->header->l11n->language ); $attrL11n->content = $request->getDataString('title') ?? ''; @@ -980,7 +980,7 @@ final class ApiController extends Controller $attrL11n = new BaseStringL11n(); $attrL11n->ref = $request->getDataInt('value') ?? 0; $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->getLanguage() + $request->getDataString('language') ?? $request->header->l11n->language ); $attrL11n->content = $request->getDataString('title') ?? ''; @@ -1211,7 +1211,7 @@ final class ApiController extends Controller $response, NotificationLevel::OK, '', - $this->app->l11nManager->getText($response->getLanguage(), '0', '0', 'SucessfulCreate'), + $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), $vehicle ); } @@ -1296,7 +1296,7 @@ final class ApiController extends Controller $typeL11n = new BaseStringL11n(); $typeL11n->ref = $request->getDataInt('type') ?? 0; $typeL11n->setLanguage( - $request->getDataString('language') ?? $request->getLanguage() + $request->getDataString('language') ?? $request->header->l11n->language ); $typeL11n->content = $request->getDataString('title') ?? ''; diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 33b2c0e..6ca2c85 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -58,7 +58,7 @@ final class BackendController extends Controller /** @var \Modules\Attribute\Models\AttributeType[] $attributes */ $attributes = VehicleAttributeTypeMapper::getAll() ->with('l11n') - ->where('l11n/language', $response->getLanguage()) + ->where('l11n/language', $response->header->l11n->language) ->execute(); $view->addData('attributes', $attributes); @@ -88,7 +88,7 @@ final class BackendController extends Controller $list = VehicleMapper::getAll() ->with('type') ->with('type/l11n') - ->where('type/l11n/language', $response->getLanguage()) + ->where('type/l11n/language', $response->header->l11n->language) ->sort('id', 'DESC') ->execute(); @@ -119,7 +119,7 @@ final class BackendController extends Controller $attribute = VehicleAttributeTypeMapper::get() ->with('l11n') ->where('id', (int) $request->getData('id')) - ->where('l11n/language', $response->getLanguage()) + ->where('l11n/language', $response->header->l11n->language) ->execute(); $l11ns = VehicleAttributeTypeL11nMapper::getAll() @@ -161,9 +161,9 @@ final class BackendController extends Controller ->with('fuelType') ->with('fuelType/l11n') ->where('id', (int) $request->getData('id')) - ->where('type/l11n/language', $response->getLanguage()) - ->where('fuelType/l11n/language', $response->getLanguage()) - ->where('attributes/type/l11n/language', $response->getLanguage()) + ->where('type/l11n/language', $response->header->l11n->language) + ->where('fuelType/l11n/language', $response->header->l11n->language) + ->where('attributes/type/l11n/language', $response->header->l11n->language) ->execute(); $view->setData('vehicle', $vehicle); @@ -192,7 +192,7 @@ final class BackendController extends Controller $vehicleTypes = VehicleTypeMapper::getAll() ->with('l11n') - ->where('l11n/language', $response->getLanguage()) + ->where('l11n/language', $response->header->l11n->language) ->execute(); $view->addData('types', $vehicleTypes); From cb44e3ac3aa443f3c7548a4ec2a8ee35acf4b70c Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 30 May 2023 15:44:18 +0200 Subject: [PATCH 25/89] Continue with getter/setter cleanup --- Controller/BackendController.php | 22 +++++++++++----------- Theme/Backend/attribute-type-list.tpl.php | 4 ++-- Theme/Backend/attribute-type.tpl.php | 6 +++--- Theme/Backend/vehicle-create.tpl.php | 2 +- Theme/Backend/vehicle-list.tpl.php | 4 ++-- Theme/Backend/vehicle-profile.tpl.php | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 6ca2c85..f7d468d 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -53,7 +53,7 @@ final class BackendController extends Controller { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type-list'); - $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003503001, $request, $response)); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003503001, $request, $response); /** @var \Modules\Attribute\Models\AttributeType[] $attributes */ $attributes = VehicleAttributeTypeMapper::getAll() @@ -61,7 +61,7 @@ final class BackendController extends Controller ->where('l11n/language', $response->header->l11n->language) ->execute(); - $view->addData('attributes', $attributes); + $view->data['attributes'] = $attributes; return $view; } @@ -83,7 +83,7 @@ final class BackendController extends Controller $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-list'); - $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response)); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); $list = VehicleMapper::getAll() ->with('type') @@ -92,7 +92,7 @@ final class BackendController extends Controller ->sort('id', 'DESC') ->execute(); - $view->setData('vehicles', $list); + $view->data['vehicles'] = $list; return $view; } @@ -113,7 +113,7 @@ final class BackendController extends Controller { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type'); - $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response)); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response); /** @var \Modules\Attribute\Models\AttributeType $attribute */ $attribute = VehicleAttributeTypeMapper::get() @@ -126,8 +126,8 @@ final class BackendController extends Controller ->where('ref', $attribute->id) ->execute(); - $view->addData('attribute', $attribute); - $view->addData('l11ns', $l11ns); + $view->data['attribute'] = $attribute; + $view->data['l11ns'] = $l11ns; return $view; } @@ -149,7 +149,7 @@ final class BackendController extends Controller $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-profile'); - $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response)); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); $vehicle = VehicleMapper::get() ->with('attributes') @@ -166,7 +166,7 @@ final class BackendController extends Controller ->where('attributes/type/l11n/language', $response->header->l11n->language) ->execute(); - $view->setData('vehicle', $vehicle); + $view->data['vehicle'] = $vehicle; $query = new Builder($this->app->dbPool->get()); $results = $query->selectAs(VehicleMapper::HAS_MANY['files']['external'], 'file') @@ -188,14 +188,14 @@ final class BackendController extends Controller ->limit(1) ->execute(); - $view->addData('vehicleImage', $vehicleImage); + $view->data['vehicleImage'] = $vehicleImage; $vehicleTypes = VehicleTypeMapper::getAll() ->with('l11n') ->where('l11n/language', $response->header->l11n->language) ->execute(); - $view->addData('types', $vehicleTypes); + $view->data['types'] = $vehicleTypes; return $view; } diff --git a/Theme/Backend/attribute-type-list.tpl.php b/Theme/Backend/attribute-type-list.tpl.php index 09bdaee..edcbe2d 100755 --- a/Theme/Backend/attribute-type-list.tpl.php +++ b/Theme/Backend/attribute-type-list.tpl.php @@ -15,9 +15,9 @@ declare(strict_types=1); use phpOMS\Uri\UriFactory; /** @var \phpOMS\Views\View $this */ -$attributes = $this->getData('attributes'); +$attributes = $this->data['attributes']; -echo $this->getData('nav')->render(); ?> +echo $this->data['nav']->render(); ?>
diff --git a/Theme/Backend/attribute-type.tpl.php b/Theme/Backend/attribute-type.tpl.php index bed6997..ab560c4 100755 --- a/Theme/Backend/attribute-type.tpl.php +++ b/Theme/Backend/attribute-type.tpl.php @@ -17,10 +17,10 @@ use phpOMS\Localization\ISO639Enum; $types = AttributeValueType::getConstants(); -$attribute = $this->getData('attribute'); -$l11ns = $this->getData('l11ns'); +$attribute = $this->data['attribute']; +$l11ns = $this->data['l11ns']; -echo $this->getData('nav')->render(); ?> +echo $this->data['nav']->render(); ?>
diff --git a/Theme/Backend/vehicle-create.tpl.php b/Theme/Backend/vehicle-create.tpl.php index 62d4c00..868169a 100755 --- a/Theme/Backend/vehicle-create.tpl.php +++ b/Theme/Backend/vehicle-create.tpl.php @@ -15,7 +15,7 @@ declare(strict_types=1); /** * @var \phpOMS\Views\View $this */ -echo $this->getData('nav')->render(); ?> +echo $this->data['nav']->render(); ?>
diff --git a/Theme/Backend/vehicle-list.tpl.php b/Theme/Backend/vehicle-list.tpl.php index 0eafa88..c8ad41e 100755 --- a/Theme/Backend/vehicle-list.tpl.php +++ b/Theme/Backend/vehicle-list.tpl.php @@ -16,9 +16,9 @@ declare(strict_types=1); use phpOMS\Uri\UriFactory; /** @var \phpOMS\Views\View $this */ -$vehicles = $this->getData('vehicles') ?? []; +$vehicles = $this->data['vehicles'] ?? []; -echo $this->getData('nav')->render(); ?> +echo $this->data['nav']->render(); ?>
diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index f22b656..af594f9 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -27,12 +27,12 @@ $vehicleStatus = VehicleStatus::getConstants(); $vehicle = $this->getData('vehicle') ?? new NullVehicle(); $files = $vehicle->files; $vehicleImage = $this->getData('vehicleImage') ?? new NullMedia(); -$vehicleTypes = $this->getData('types') ?? []; +$vehicleTypes = $this->data['types'] ?? []; /** * @var \phpOMS\Views\View $this */ -echo $this->getData('nav')->render(); +echo $this->data['nav']->render(); ?>
From c4364e243b59c5832a727a7e6dedd2f70d864944 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 31 May 2023 12:03:53 +0000 Subject: [PATCH 26/89] fix getters/setters --- Controller/Controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Controller/Controller.php b/Controller/Controller.php index 18c63e3..a1ab275 100755 --- a/Controller/Controller.php +++ b/Controller/Controller.php @@ -64,7 +64,7 @@ class Controller extends ModuleAbstract * @var string[] * @since 1.0.0 */ - protected static array $providing = []; + public static array $providing = []; /** * Dependencies. @@ -72,5 +72,5 @@ class Controller extends ModuleAbstract * @var string[] * @since 1.0.0 */ - protected static array $dependencies = []; + public static array $dependencies = []; } From c22b2890a7dbeff3e9ce94339f04d272476d8fea Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 31 May 2023 13:21:47 +0000 Subject: [PATCH 27/89] automated phpcs fixes --- Controller/ApiController.php | 40 ++++++++++++++++---------------- Controller/BackendController.php | 2 +- Models/Inspection.php | 1 - Models/InspectionMapper.php | 10 ++++---- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 206393e..2fa0585 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -32,8 +32,6 @@ use Modules\FleetManagement\Models\VehicleAttributeValueL11nMapper; use Modules\FleetManagement\Models\VehicleAttributeValueMapper; use Modules\FleetManagement\Models\VehicleMapper; use Modules\FleetManagement\Models\VehicleStatus; -use phpOMS\Localization\NullBaseStringL11nType; -use phpOMS\Localization\BaseStringL11nType; use Modules\FleetManagement\Models\VehicleTypeL11nMapper; use Modules\FleetManagement\Models\VehicleTypeMapper; use Modules\Media\Models\CollectionMapper; @@ -42,7 +40,9 @@ use Modules\Media\Models\NullMedia; use Modules\Media\Models\PathSettings; use Modules\Media\Models\Reference; use phpOMS\Localization\BaseStringL11n; +use phpOMS\Localization\BaseStringL11nType; use phpOMS\Localization\ISO639x1Enum; +use phpOMS\Localization\NullBaseStringL11nType; use phpOMS\Message\Http\RequestStatusCode; use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; @@ -76,7 +76,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleTypeCreate($request))) { $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -106,7 +106,7 @@ final class ApiController extends Controller */ public function createVehicleTypeFromRequest(RequestAbstract $request) : BaseStringL11nType { - $type = new BaseStringL11nType(); + $type = new BaseStringL11nType(); $type->title = $request->getDataString('name') ?? ''; $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); @@ -151,7 +151,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleTypeL11nCreate($request))) { $response->data['vehicle_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -220,7 +220,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateFuelTypeCreate($request))) { $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -250,7 +250,7 @@ final class ApiController extends Controller */ public function createFuelTypeFromRequest(RequestAbstract $request) : BaseStringL11nType { - $type = new BaseStringL11nType(); + $type = new BaseStringL11nType(); $type->title = $request->getDataString('name') ?? ''; $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); @@ -295,7 +295,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateFuelTypeL11nCreate($request))) { $response->data['fuel_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -364,7 +364,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleCreate($request))) { $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -562,7 +562,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleAttributeCreate($request))) { $response->data['attribute_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -641,7 +641,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleAttributeUpdate($request))) { $response->data['attribute_update'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -731,7 +731,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleAttributeTypeL11nCreate($request))) { $response->data['attr_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -800,7 +800,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleAttributeTypeCreate($request))) { $response->data['attr_type_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -871,7 +871,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleAttributeValueCreate($request))) { $response->data['attr_value_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -956,7 +956,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -1025,7 +1025,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -1052,7 +1052,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateMediaAddToVehicle($request))) { $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -1197,7 +1197,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateInspectionTypeCreate($request))) { $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } @@ -1227,7 +1227,7 @@ final class ApiController extends Controller */ public function createInspectionTypeFromRequest(RequestAbstract $request) : BaseStringL11nType { - $type = new BaseStringL11nType(); + $type = new BaseStringL11nType(); $type->title = $request->getDataString('name') ?? ''; $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); @@ -1272,7 +1272,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateInspectionTypeL11nCreate($request))) { $response->data['inspection_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index f7d468d..031ce1b 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -127,7 +127,7 @@ final class BackendController extends Controller ->execute(); $view->data['attribute'] = $attribute; - $view->data['l11ns'] = $l11ns; + $view->data['l11ns'] = $l11ns; return $view; } diff --git a/Models/Inspection.php b/Models/Inspection.php index 3d90bb2..be899ab 100644 --- a/Models/Inspection.php +++ b/Models/Inspection.php @@ -44,7 +44,6 @@ class Inspection implements \JsonSerializable */ public int $interval = 0; - public function __construct() { $this->type = new BaseStringL11nType(); diff --git a/Models/InspectionMapper.php b/Models/InspectionMapper.php index 66a798b..65f8d80 100644 --- a/Models/InspectionMapper.php +++ b/Models/InspectionMapper.php @@ -37,12 +37,12 @@ final class InspectionMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'fleetmgmt_vehicle_inspection_id' => ['name' => 'fleetmgmt_vehicle_inspection_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_inspection_id' => ['name' => 'fleetmgmt_vehicle_inspection_id', 'type' => 'int', 'internal' => 'id'], 'fleetmgmt_vehicle_inspection_description' => ['name' => 'fleetmgmt_vehicle_inspection_description', 'type' => 'string', 'internal' => 'description'], - 'fleetmgmt_vehicle_inspection_status' => ['name' => 'fleetmgmt_vehicle_inspection_status', 'type' => 'int', 'internal' => 'status'], - 'fleetmgmt_vehicle_inspection_interval' => ['name' => 'fleetmgmt_vehicle_inspection_interval', 'type' => 'int', 'internal' => 'interval'], - 'fleetmgmt_vehicle_inspection_next' => ['name' => 'fleetmgmt_vehicle_inspection_next', 'type' => 'DateTime', 'internal' => 'next'], - 'fleetmgmt_vehicle_inspection_type' => ['name' => 'fleetmgmt_vehicle_inspection_type', 'type' => 'int', 'internal' => 'type'], + 'fleetmgmt_vehicle_inspection_status' => ['name' => 'fleetmgmt_vehicle_inspection_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_vehicle_inspection_interval' => ['name' => 'fleetmgmt_vehicle_inspection_interval', 'type' => 'int', 'internal' => 'interval'], + 'fleetmgmt_vehicle_inspection_next' => ['name' => 'fleetmgmt_vehicle_inspection_next', 'type' => 'DateTime', 'internal' => 'next'], + 'fleetmgmt_vehicle_inspection_type' => ['name' => 'fleetmgmt_vehicle_inspection_type', 'type' => 'int', 'internal' => 'type'], ]; /** From 64b6bd4ea910eaf56712ab375a016bbd3c6ce186 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 5 Jun 2023 03:38:09 +0200 Subject: [PATCH 28/89] Add notes. --- Admin/Install/db.json | 4 +-- Controller/ApiController.php | 58 ++++++++++++++++++++++++++++++++++++ Models/VehicleMapper.php | 7 +++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/Admin/Install/db.json b/Admin/Install/db.json index f790e47..d4e3a9a 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -548,8 +548,8 @@ "primary": true, "autoincrement": true }, - "fleetmgmt_vehicle_note_item": { - "name": "fleetmgmt_vehicle_note_item", + "fleetmgmt_vehicle_note_vehicle": { + "name": "fleetmgmt_vehicle_note_vehicle", "type": "INT", "null": false, "foreignTable": "fleetmgmt_vehicle", diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 2fa0585..b52eeb4 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -1323,4 +1323,62 @@ final class ApiController extends Controller return []; } + + /** + * Api method to create item files + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateNoteCreate($request))) { + $response->data['vehicle_note_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $request->setData('virtualpath', '/Modules/FleetManagement/Items/' . $request->getData('id'), true); + $this->app->moduleManager->get('Editor', 'Api')->apiEditorCreate($request, $response, $data); + + if ($response->header->status !== RequestStatusCode::R_200) { + return; + } + + $responseData = $response->get($request->uri->__toString()); + if (!\is_array($responseData)) { + return; + } + + $model = $responseData['response']; + $this->createModelRelation($request->header->account, (int) $request->getData('id'), $model->id, VehicleMapper::class, 'notes', '', $request->getOrigin()); + } + + /** + * Validate item note create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateNoteCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + ) { + return $val; + } + + return []; + } } diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php index ea732e4..6c2659f 100644 --- a/Models/VehicleMapper.php +++ b/Models/VehicleMapper.php @@ -16,6 +16,7 @@ namespace Modules\FleetManagement\Models; use Modules\Media\Models\MediaMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; +use Modules\Editor\Models\EditorDocMapper; /** * Mapper class. @@ -67,6 +68,12 @@ final class VehicleMapper extends DataMapperFactory 'self' => 'fleetmgmt_vehicle_attr_item', 'external' => null, ], + 'notes' => [ + 'mapper' => EditorDocMapper::class, /* mapper of the related object */ + 'table' => 'bizexpenses_expense_note', /* table of the related object, null if no relation table is used (many->1) */ + 'external' => 'bizexpenses_expense_note_doc', + 'self' => 'bizexpenses_expense_note_expense', + ], ]; /** From 37f7adc7d8627af17b375959630a428e2749b04c Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 9 Jun 2023 19:32:20 +0200 Subject: [PATCH 29/89] Implement helper traits --- Controller/BackendController.php | 1 + Models/Vehicle.php | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 031ce1b..4a3be41 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -151,6 +151,7 @@ final class BackendController extends Controller $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-profile'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + // @todo: This langauge filtering doesn't work. But it was working with the old mappers. Maybe there is a bug in the where() definition. Need to inspect the actual query. $vehicle = VehicleMapper::get() ->with('attributes') ->with('attributes/type') diff --git a/Models/Vehicle.php b/Models/Vehicle.php index fb1b779..80f67a0 100644 --- a/Models/Vehicle.php +++ b/Models/Vehicle.php @@ -44,8 +44,6 @@ class Vehicle implements \JsonSerializable public array $milage = []; - public array $notes = []; - public int $unit = 0; public ?int $responsible = null; @@ -76,7 +74,8 @@ class Vehicle implements \JsonSerializable { return $this->toArray(); } - + use \Modules\Media\Models\MediaListTrait; + use \Modules\Editor\Models\EditorDocListTrait; use \Modules\Attribute\Models\AttributeHolderTrait; } From 595dc5c8ed74766db07ce7780186216457b2d978 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 9 Jun 2023 17:36:42 +0000 Subject: [PATCH 30/89] continue implementation --- Admin/Install/Navigation.install.json | 100 +++++++- Admin/Install/inspectiontype.json | 37 +++ Admin/Routes/Web/Api.php | 52 ++++ Admin/Routes/Web/Backend.php | 69 ++++++ Controller/BackendController.php | 51 ++++ Models/VehicleTypeL11nMapper.php | 1 + Theme/Backend/Lang/Navigation.en.lang.php | 1 + Theme/Backend/Lang/en.lang.php | 1 + Theme/Backend/vehicle-create.tpl.php | 289 ---------------------- Theme/Backend/vehicle-profile.tpl.php | 246 +++++++++++++++++- 10 files changed, 545 insertions(+), 302 deletions(-) create mode 100644 Admin/Install/inspectiontype.json create mode 100644 Admin/Routes/Web/Api.php delete mode 100755 Theme/Backend/vehicle-create.tpl.php diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index a82b041..3e31646 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -64,6 +64,98 @@ "pid": "/", "type": 2, "subtype": 1, + "name": "Drivers", + "uri": "{/base}/fleet/driver/list", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003501001, + "children": [ + { + "id": 1003503101, + "pid": "/fleet/driver", + "type": 3, + "subtype": 1, + "name": "List", + "uri": "{/base}/fleet/driver/list", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003503001, + "children": [] + }, + { + "id": 1003503201, + "pid": "/fleet/driver", + "type": 3, + "subtype": 1, + "name": "Create", + "uri": "{/base}/fleet/driver/create?{?}", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 4, "category": null, "element": null }, + "parent": 1003503001, + "children": [] + } + ] + }, + { + "id": 1003504001, + "pid": "/", + "type": 2, + "subtype": 1, + "name": "Inspection", + "uri": "{/base}/fleet/inspection/list", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003501001, + "children": [ + { + "id": 1003504101, + "pid": "/fleet/inspection", + "type": 3, + "subtype": 1, + "name": "List", + "uri": "{/base}/fleet/inspection/list", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003504001, + "children": [] + }, + { + "id": 1003504201, + "pid": "/fleet/inspection", + "type": 3, + "subtype": 1, + "name": "Create", + "uri": "{/base}/fleet/inspection/create?{?}", + "target": "self", + "icon": null, + "order": 1, + "from": "FleetManagement", + "permission": { "permission": 4, "category": null, "element": null }, + "parent": 1003504001, + "children": [] + } + ] + }, + { + "id": 1003505001, + "pid": "/", + "type": 2, + "subtype": 1, "name": "Attributes", "uri": "{/base}/fleet/vehicle/attribute/type/list?{?}", "target": "self", @@ -74,7 +166,7 @@ "parent": 1003501001, "children": [ { - "id": 1003503101, + "id": 1003505101, "pid": "/fleet/vehicle/attribute", "type": 3, "subtype": 1, @@ -85,11 +177,11 @@ "order": 15, "from": "FleetManagement", "permission": { "permission": 2, "category": null, "element": null }, - "parent": 1003503001, + "parent": 1003505001, "children": [] }, { - "id": 1003503201, + "id": 1003505201, "pid": "/fleet/vehicle/attribute", "type": 3, "subtype": 1, @@ -100,7 +192,7 @@ "order": 15, "from": "FleetManagement", "permission": { "permission": 2, "category": null, "element": null }, - "parent": 1003503001, + "parent": 1003505001, "children": [] } ] diff --git a/Admin/Install/inspectiontype.json b/Admin/Install/inspectiontype.json new file mode 100644 index 0000000..033e032 --- /dev/null +++ b/Admin/Install/inspectiontype.json @@ -0,0 +1,37 @@ +[ + { + "name": "tire_change", + "l11n": { + "en": "Tire change", + "de": "Reifenwechsel" + } + }, + { + "name": "oil_change", + "l11n": { + "en": "Oil change", + "de": "Ölwechsel" + } + }, + { + "name": "mot", + "l11n": { + "en": "MOT test", + "de": "TÜV" + } + }, + { + "name": "emissions_test", + "l11n": { + "en": "Emissions test", + "de": "Abgasuntersuchung" + } + }, + { + "name": "general", + "l11n": { + "en": "General", + "de": "Allgemein" + } + } +] \ No newline at end of file diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php new file mode 100644 index 0000000..0623738 --- /dev/null +++ b/Admin/Routes/Web/Api.php @@ -0,0 +1,52 @@ + [ + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiController:apiVehicleFind', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => ApiController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/vehicle/attribute.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiController:apiVehicleAttributeCreate', + 'verb' => RouteVerb::PUT, + 'permission' => [ + 'module' => ApiController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiController:apiVehicleAttributeUpdate', + 'verb' => RouteVerb::SET, + 'permission' => [ + 'module' => ApiController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], +]; diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index dcaf6fb..5ba77d1 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -40,6 +40,7 @@ return [ ], ], ], + '^.*/fleet/vehicle/list.*$' => [ [ 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleList', @@ -73,4 +74,72 @@ return [ ], ], ], + + '^.*/fleet/driver/list.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementDriverList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/driver/create.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementDriverCreate', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::CREATE, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/driver/profile.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementDriverProfile', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + + '^.*/fleet/inspection/list.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/inspection/create.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleCreate', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::CREATE, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/inspection/profile.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleProfile', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], ]; diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 031ce1b..cd8ed46 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,12 +14,15 @@ declare(strict_types=1); namespace Modules\FleetManagement\Controller; +use Modules\Admin\Models\LocalizationMapper; +use Modules\Admin\Models\SettingsEnum; use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; use Modules\FleetManagement\Models\VehicleAttributeTypeMapper; use Modules\FleetManagement\Models\VehicleMapper; use Modules\FleetManagement\Models\VehicleTypeMapper; use Modules\Media\Models\MediaMapper; use Modules\Media\Models\MediaTypeMapper; +use Modules\Organization\Models\UnitMapper; use phpOMS\Contract\RenderableInterface; use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\Message\RequestAbstract; @@ -132,6 +135,39 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementVehicleCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-profile'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + /** @var \Model\Setting $settings */ + $settings = $this->app->appSettings->get(null, [ + SettingsEnum::DEFAULT_LOCALIZATION, + ]); + + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); + + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['vehicle-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); + + return $view; + } + /** * Routing end-point for application behaviour. * @@ -197,6 +233,21 @@ final class BackendController extends Controller $view->data['types'] = $vehicleTypes; + $units = UnitMapper::getAll() + ->execute(); + $view->data['units'] = $units; + + /** @var \Model\Setting $settings */ + $settings = $this->app->appSettings->get(null, [ + SettingsEnum::DEFAULT_LOCALIZATION, + ]); + + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); + + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['vehicle-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); + return $view; } } diff --git a/Models/VehicleTypeL11nMapper.php b/Models/VehicleTypeL11nMapper.php index 48a6eb2..5d97869 100644 --- a/Models/VehicleTypeL11nMapper.php +++ b/Models/VehicleTypeL11nMapper.php @@ -40,6 +40,7 @@ final class VehicleTypeL11nMapper extends DataMapperFactory 'fleetmgmt_vehicle_type_l11n_id' => ['name' => 'fleetmgmt_vehicle_type_l11n_id', 'type' => 'int', 'internal' => 'id'], 'fleetmgmt_vehicle_type_l11n_title' => ['name' => 'fleetmgmt_vehicle_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], 'fleetmgmt_vehicle_type_l11n_type' => ['name' => 'fleetmgmt_vehicle_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_vehicle_type_l11n_lang' => ['name' => 'fleetmgmt_vehicle_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], ]; /** diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index 0792899..e7ff236 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -15,4 +15,5 @@ declare(strict_types=1); return ['Navigation' => [ 'FleetManagement' => 'Fleet Management', 'Vehicles' => 'Vehicles', + 'Drivers' => 'Drivers', ]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 12dfa07..054fdc4 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -26,6 +26,7 @@ return ['FleetManagement' => [ 'Attributes' => 'Attributes', 'Files' => 'Files', 'Notes' => 'Notes', + 'Costs' => 'Costs', 'Inspections' => 'Inspections', 'Drivers' => 'Drivers', 'Milage' => 'Milage', diff --git a/Theme/Backend/vehicle-create.tpl.php b/Theme/Backend/vehicle-create.tpl.php deleted file mode 100755 index 868169a..0000000 --- a/Theme/Backend/vehicle-create.tpl.php +++ /dev/null @@ -1,289 +0,0 @@ -data['nav']->render(); ?> - -
-
- -
-
- request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Client'); ?>

-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
- request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Contact'); ?>

-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Address'); ?>

-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('PaymentTerm'); ?>

-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Payment'); ?>

-
-
- -
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-6' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('Price'); ?>

-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-7' ? ' checked' : ''; ?>> -
-
-
-
-

getHtml('AreaManager'); ?>

-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- request->uri->fragment === 'c-tab-8' ? ' checked' : ''; ?>> -
-
- request->uri->fragment === 'c-tab-9' ? ' checked' : ''; ?>> -
-
-
- l11nManager, $this->request, $this->response); - $footerView->setTemplate('/Web/Templates/Lists/Footer/PaginationBig'); - $footerView->setPages(20); - $footerView->setPage(1); - ?> -
- - - - - - -
getHtml('Logs'); ?>
IP - getHtml('ID', '0', '0'); ?> - getHtml('Name'); ?> - getHtml('Log'); ?> - getHtml('Date'); ?> -
printHtml($this->request->getOrigin()); ?> - printHtml((string) $this->request->header->account); ?> - printHtml((string) $this->request->header->account); ?> - Creating customer - printHtml((new \DateTime('now'))->format('Y-m-d H:i:s')); ?> -
-
-
-
-
-
-
diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index af594f9..5195d70 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -24,10 +24,11 @@ $vehicleStatus = VehicleStatus::getConstants(); /** * @var \Modules\FleetManagement\Models\Vehicle $vehicle */ -$vehicle = $this->getData('vehicle') ?? new NullVehicle(); +$vehicle = $this->data['vehicle'] ?? new NullVehicle(); $files = $vehicle->files; -$vehicleImage = $this->getData('vehicleImage') ?? new NullMedia(); +$vehicleImage = $this->data['vehicleImage'] ?? new NullMedia(); $vehicleTypes = $this->data['types'] ?? []; +$attributeView = $this->data['attributeView']; /** * @var \phpOMS\Views\View $this @@ -38,12 +39,12 @@ echo $this->data['nav']->render();
@@ -109,14 +110,21 @@ echo $this->data['nav']->render();
- +
- +
+
+ id === 0) : ?> + + + + +
@@ -131,5 +139,225 @@ echo $this->data['nav']->render();
+ + request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> +
+
+ render( + $vehicle->getAttributes(), + $this->data['attributeTypes'] ?? [], + $this->data['units'] ?? [], + '{/api}fleet/vehicle/attribute' + ); + ?> +
+
+ + request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+ data['media-upload']->render('vehicle-file', 'files', '', $vehicle->files); ?> +
+ + request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>> +
+ data['vehicle-notes']->render('vehicle-notes', '', $vehicle->notes); ?> +
+ + request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> +
+ +
+
+
+
getHtml('Upcoming'); ?>
+ + + + + +
getHtml('Date'); ?> + getHtml('Type'); ?> + getHtml('Responsible'); ?> +
+ + +
+
+
+ +
+
+
getHtml('History'); ?>
+ + + + + +
getHtml('Date'); ?> + getHtml('Type'); ?> + getHtml('Responsible'); ?> +
+ + +
+
+
+
+
+ + request->uri->fragment === 'c-tab-7' ? ' checked' : ''; ?>> +
+
+
+
+
+
getHtml('Milage'); ?>
+
+
+ + +
+ +
+ +
+
+ + + + +
+ 0) : ?> + + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +

+                                
+
+
+ + + +
+
+
+
+ +
+
+
getHtml('Milage'); ?>
+
+ + + + + + $value) : ++$c; ?> + + +
+ getHtml('ID', '0', '0'); ?> + getHtml('Driver'); ?> + getHtml('Milage'); ?> + getHtml('Start'); ?> + getHtml('End'); ?> +
+ + type->isRequired) : ?> + + + + + + + + id; ?> + printHtml($value->type->getL11n()); ?> + value->getValue() instanceof \DateTime ? $value->value->getValue()->format('Y-m-d') : $this->printHtml((string) $value->value->getValue()); ?> + printHtml($value->value->unit); ?> + printHtml($value->value->unit); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
+
+
+ + request->uri->fragment === 'c-tab-8' ? ' checked' : ''; ?>> +
+
+
+
+
+
\ No newline at end of file From 364626bf8595e84a2596e699f0da9f795091d428 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 13 Jun 2023 18:55:51 +0000 Subject: [PATCH 31/89] Quick backup before crash --- Admin/Install/Navigation.install.json | 48 +- Admin/Install/db.json | 394 ++++++++++++ Admin/Installer.php | 113 +++- Admin/Routes/Web/Api.php | 36 +- Admin/Routes/Web/Backend.php | 23 + Controller/ApiDriverAttributeController.php | 534 ++++++++++++++++ Controller/ApiDriverController.php | 588 ++++++++++++++++++ Controller/ApiVehicleAttributeController.php | 534 ++++++++++++++++ ...ontroller.php => ApiVehicleController.php} | 518 +-------------- Controller/BackendController.php | 11 +- Models/Driver/Driver.php | 79 +++ Models/Driver/DriverAttributeMapper.php | 86 +++ .../Driver/DriverAttributeTypeL11nMapper.php | 69 ++ Models/Driver/DriverAttributeTypeMapper.php | 94 +++ .../Driver/DriverAttributeValueL11nMapper.php | 69 ++ Models/Driver/DriverAttributeValueMapper.php | 89 +++ Models/Driver/DriverInspection.php | 78 +++ Models/Driver/DriverInspectionMapper.php | 84 +++ Models/Driver/DriverInspectionStatus.php | 36 ++ .../Driver/DriverInspectionTypeL11nMapper.php | 69 ++ Models/Driver/DriverInspectionTypeMapper.php | 83 +++ Models/Driver/DriverMapper.php | 102 +++ Models/Driver/DriverStatus.php | 34 + Models/Driver/NullDriver.php | 46 ++ Models/Driver/NullDriverInspection.php | 46 ++ Models/Inspection.php | 27 +- Models/InspectionTypeMapper.php | 2 +- Models/License.php | 0 Models/LicenseType.php | 0 Models/NullInspection.php | 46 ++ Models/Vehicle.php | 7 +- Models/VehicleMapper.php | 6 +- 32 files changed, 3404 insertions(+), 547 deletions(-) create mode 100644 Controller/ApiDriverAttributeController.php create mode 100644 Controller/ApiDriverController.php create mode 100644 Controller/ApiVehicleAttributeController.php rename Controller/{ApiController.php => ApiVehicleController.php} (61%) create mode 100644 Models/Driver/Driver.php create mode 100644 Models/Driver/DriverAttributeMapper.php create mode 100644 Models/Driver/DriverAttributeTypeL11nMapper.php create mode 100644 Models/Driver/DriverAttributeTypeMapper.php create mode 100644 Models/Driver/DriverAttributeValueL11nMapper.php create mode 100644 Models/Driver/DriverAttributeValueMapper.php create mode 100644 Models/Driver/DriverInspection.php create mode 100644 Models/Driver/DriverInspectionMapper.php create mode 100644 Models/Driver/DriverInspectionStatus.php create mode 100644 Models/Driver/DriverInspectionTypeL11nMapper.php create mode 100644 Models/Driver/DriverInspectionTypeMapper.php create mode 100644 Models/Driver/DriverMapper.php create mode 100644 Models/Driver/DriverStatus.php create mode 100644 Models/Driver/NullDriver.php create mode 100644 Models/Driver/NullDriverInspection.php create mode 100644 Models/License.php create mode 100644 Models/LicenseType.php diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 3e31646..12ec25e 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -156,7 +156,7 @@ "pid": "/", "type": 2, "subtype": 1, - "name": "Attributes", + "name": "VehicleAttributes", "uri": "{/base}/fleet/vehicle/attribute/type/list?{?}", "target": "self", "icon": null, @@ -196,6 +196,52 @@ "children": [] } ] + }, + { + "id": 1003506001, + "pid": "/", + "type": 2, + "subtype": 1, + "name": "DriverAttributes", + "uri": "{/base}/fleet/driver/attribute/type/list?{?}", + "target": "self", + "icon": null, + "order": 5, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003501001, + "children": [ + { + "id": 1003506101, + "pid": "/fleet/driver/attribute", + "type": 3, + "subtype": 1, + "name": "Types", + "uri": "{/base}/fleet/driver/attribute/type/list?{?}", + "target": "self", + "icon": null, + "order": 15, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003506001, + "children": [] + }, + { + "id": 1003506201, + "pid": "/fleet/driver/attribute", + "type": 3, + "subtype": 1, + "name": "Values", + "uri": "{/base}/fleet/driver/attribute/value/list?{?}", + "target": "self", + "icon": null, + "order": 15, + "from": "FleetManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003506001, + "children": [] + } + ] } ] } diff --git a/Admin/Install/db.json b/Admin/Install/db.json index d4e3a9a..1bc0a61 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -243,6 +243,119 @@ } } }, + "fleetmgmt_driver_inspection_type": { + "name": "fleetmgmt_driver_inspection_type", + "fields": { + "fleetmgmt_driver_inspection_type_id": { + "name": "fleetmgmt_driver_inspection_type_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_inspection_type_name": { + "name": "fleetmgmt_driver_inspection_type_name", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "fleetmgmt_driver_inspection_type_l11n": { + "name": "fleetmgmt_driver_inspection_type_l11n", + "fields": { + "fleetmgmt_driver_inspection_type_l11n_id": { + "name": "fleetmgmt_driver_inspection_type_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_inspection_type_l11n_title": { + "name": "fleetmgmt_driver_inspection_type_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_driver_inspection_type_l11n_type": { + "name": "fleetmgmt_driver_inspection_type_l11n_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_driver_inspection_type", + "foreignKey": "fleetmgmt_driver_inspection_type_id" + }, + "fleetmgmt_driver_inspection_type_l11n_lang": { + "name": "fleetmgmt_driver_inspection_type_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, + "fleetmgmt_driver": { + "name": "fleetmgmt_driver", + "fields": { + "fleetmgmt_driver_id": { + "name": "fleetmgmt_driver_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_status": { + "name": "fleetmgmt_driver_status", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_driver_account": { + "name": "fleetmgmt_driver_account", + "type": "INT", + "null": true, + "default": true, + "foreignTable": "account", + "foreignKey": "account_id" + } + } + }, + "fleetmgmt_driver_inspection": { + "name": "fleetmgmt_driver_inspection", + "fields": { + "fleetmgmt_driver_inspection_id": { + "name": "fleetmgmt_driver_inspection_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_inspection_description": { + "name": "fleetmgmt_driver_inspection_description", + "type": "TEXT", + "null": false + }, + "fleetmgmt_driver_inspection_status": { + "name": "fleetmgmt_driver_inspection_status", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_driver_inspection_interval": { + "name": "fleetmgmt_driver_inspection_interval", + "type": "TINYINT(3)", + "null": false + }, + "fleetmgmt_driver_inspection_next": { + "name": "fleetmgmt_driver_inspection_next", + "type": "DATETIME", + "null": true, + "default": null + }, + "fleetmgmt_driver_inspection_type": { + "name": "fleetmgmt_driver_inspection_type", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_driver_inspection_type", + "foreignKey": "fleetmgmt_driver_inspection_type_id" + } + } + }, "fleetmgmt_vehicle_usage": { "name": "fleetmgmt_vehicle_usage", "fields": { @@ -563,5 +676,286 @@ "foreignKey": "editor_doc_id" } } + }, + "fleetmgmt_driver_attr_type": { + "name": "fleetmgmt_driver_attr_type", + "fields": { + "fleetmgmt_driver_attr_type_id": { + "name": "fleetmgmt_driver_attr_type_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_attr_type_name": { + "name": "fleetmgmt_driver_attr_type_name", + "type": "VARCHAR(255)", + "null": false, + "unique": true + }, + "fleetmgmt_driver_attr_type_datatype": { + "name": "fleetmgmt_driver_attr_type_datatype", + "type": "INT(11)", + "null": false + }, + "fleetmgmt_driver_attr_type_fields": { + "name": "fleetmgmt_driver_attr_type_fields", + "type": "INT(11)", + "null": false + }, + "fleetmgmt_driver_attr_type_custom": { + "name": "fleetmgmt_driver_attr_type_custom", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_driver_attr_type_required": { + "description": "Every item must have this attribute type if set to true.", + "name": "fleetmgmt_driver_attr_type_required", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_driver_attr_type_pattern": { + "description": "This is a regex validation pattern.", + "name": "fleetmgmt_driver_attr_type_pattern", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "fleetmgmt_driver_attr_type_l11n": { + "name": "fleetmgmt_driver_attr_type_l11n", + "fields": { + "fleetmgmt_driver_attr_type_l11n_id": { + "name": "fleetmgmt_driver_attr_type_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_attr_type_l11n_title": { + "name": "fleetmgmt_driver_attr_type_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_driver_attr_type_l11n_type": { + "name": "fleetmgmt_driver_attr_type_l11n_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_driver_attr_type", + "foreignKey": "fleetmgmt_driver_attr_type_id" + }, + "fleetmgmt_driver_attr_type_l11n_lang": { + "name": "fleetmgmt_driver_attr_type_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, + "fleetmgmt_driver_attr_value": { + "name": "fleetmgmt_driver_attr_value", + "fields": { + "fleetmgmt_driver_attr_value_id": { + "name": "fleetmgmt_driver_attr_value_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_attr_value_default": { + "name": "fleetmgmt_driver_attr_value_default", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_driver_attr_value_valueStr": { + "name": "fleetmgmt_driver_attr_value_valueStr", + "type": "VARCHAR(255)", + "null": true, + "default": null + }, + "fleetmgmt_driver_attr_value_valueInt": { + "name": "fleetmgmt_driver_attr_value_valueInt", + "type": "INT(11)", + "null": true, + "default": null + }, + "fleetmgmt_driver_attr_value_valueDec": { + "name": "fleetmgmt_driver_attr_value_valueDec", + "type": "DECIMAL(19,5)", + "null": true, + "default": null + }, + "fleetmgmt_driver_attr_value_valueDat": { + "name": "fleetmgmt_driver_attr_value_valueDat", + "type": "DATETIME", + "null": true, + "default": null + }, + "fleetmgmt_driver_attr_value_unit": { + "name": "fleetmgmt_driver_attr_value_unit", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_driver_attr_value_deptype": { + "name": "fleetmgmt_driver_attr_value_deptype", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "fleetmgmt_driver_attr_type", + "foreignKey": "fleetmgmt_driver_attr_type_id" + }, + "fleetmgmt_driver_attr_value_depvalue": { + "name": "fleetmgmt_driver_attr_value_depvalue", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "fleetmgmt_driver_attr_value", + "foreignKey": "fleetmgmt_driver_attr_value_id" + } + } + }, + "fleetmgmt_driver_attr_value_l11n": { + "name": "fleetmgmt_driver_attr_value_l11n", + "fields": { + "fleetmgmt_driver_attr_value_l11n_id": { + "name": "fleetmgmt_driver_attr_value_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_attr_value_l11n_title": { + "name": "fleetmgmt_driver_attr_value_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "fleetmgmt_driver_attr_value_l11n_value": { + "name": "fleetmgmt_driver_attr_value_l11n_value", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_driver_attr_value", + "foreignKey": "fleetmgmt_driver_attr_value_id" + }, + "fleetmgmt_driver_attr_value_l11n_lang": { + "name": "fleetmgmt_driver_attr_value_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, + "fleetmgmt_driver_attr_default": { + "name": "fleetmgmt_driver_attr_default", + "fields": { + "fleetmgmt_driver_attr_default_id": { + "name": "fleetmgmt_driver_attr_default_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_attr_default_type": { + "name": "fleetmgmt_driver_attr_default_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_type", + "foreignKey": "fleetmgmt_attr_type_id" + }, + "fleetmgmt_driver_attr_default_value": { + "name": "fleetmgmt_driver_attr_default_value", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_value", + "foreignKey": "fleetmgmt_attr_value_id" + } + } + }, + "fleetmgmt_driver_attr": { + "name": "fleetmgmt_driver_attr", + "fields": { + "fleetmgmt_driver_attr_id": { + "name": "fleetmgmt_driver_attr_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_attr_item": { + "name": "fleetmgmt_driver_attr_item", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_driver", + "foreignKey": "fleetmgmt_driver_id" + }, + "fleetmgmt_driver_attr_type": { + "name": "fleetmgmt_driver_attr_type", + "type": "INT(11)", + "null": false, + "foreignTable": "fleetmgmt_attr_type", + "foreignKey": "fleetmgmt_attr_type_id" + }, + "fleetmgmt_driver_attr_value": { + "name": "fleetmgmt_driver_attr_value", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "fleetmgmt_attr_value", + "foreignKey": "fleetmgmt_attr_value_id" + } + } + }, + "fleetmgmt_driver_media": { + "name": "fleetmgmt_driver_media", + "fields": { + "fleetmgmt_driver_media_id": { + "name": "fleetmgmt_driver_media_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_media_vehicle": { + "name": "fleetmgmt_driver_media_vehicle", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_driver", + "foreignKey": "fleetmgmt_driver_id" + }, + "fleetmgmt_driver_media_media": { + "name": "fleetmgmt_driver_media_media", + "type": "INT", + "null": false, + "foreignTable": "media", + "foreignKey": "media_id" + } + } + }, + "fleetmgmt_driver_note": { + "name": "fleetmgmt_driver_note", + "fields": { + "fleetmgmt_driver_note_id": { + "name": "fleetmgmt_driver_note_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_driver_note_driver": { + "name": "fleetmgmt_driver_note_driver", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_driver", + "foreignKey": "fleetmgmt_driver_id" + }, + "fleetmgmt_driver_note_doc": { + "name": "fleetmgmt_driver_note_doc", + "type": "INT", + "null": false, + "foreignTable": "editor_doc", + "foreignKey": "editor_doc_id" + } + } } } \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php index d274d97..7ada66c 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -68,7 +68,7 @@ final class Installer extends InstallerAbstract $types = \json_decode($fileContent, true); $fuelTypes = self::createFuelTypes($app, $types); - /* Fuel types */ + /* Vehicle types */ $fileContent = \file_get_contents(__DIR__ . '/Install/vehicletype.json'); if ($fileContent === false) { return; @@ -77,15 +77,25 @@ final class Installer extends InstallerAbstract /** @var array $types */ $types = \json_decode($fileContent, true); $vehicleTypes = self::createVehicleTypes($app, $types); + + /* Inspection types */ + $fileContent = \file_get_contents(__DIR__ . '/Install/inspectiontype.json'); + if ($fileContent === false) { + return; + } + + /** @var array $types */ + $types = \json_decode($fileContent, true); + $inspectionTypes = self::createInspectionTypes($app, $types); } /** * Install fuel type * - * @param ApplicationAbstract $app Application - * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * @param ApplicationAbstract $app Application + * @param array $types Attribute definition * - * @return array + * @return array * * @since 1.0.0 */ @@ -94,8 +104,8 @@ final class Installer extends InstallerAbstract /** @var array $fuelTypes */ $fuelTypes = []; - /** @var \Modules\FleetManagement\Controller\ApiController $module */ - $module = $app->moduleManager->getModuleInstance('FleetManagement'); + /** @var \Modules\FleetManagement\Controller\ApiVehicleController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement', 'ApiVehicle'); /** @var array $type */ foreach ($types as $type) { @@ -141,22 +151,22 @@ final class Installer extends InstallerAbstract } /** - * Install fuel type + * Install vehicle type * - * @param ApplicationAbstract $app Application - * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * @param ApplicationAbstract $app Application + * @param array $types Attribute definition * - * @return array + * @return array * * @since 1.0.0 */ private static function createVehicleTypes(ApplicationAbstract $app, array $types) : array { - /** @var array $fuelTypes */ + /** @var array $vehicleTypes */ $vehicleTypes = []; - /** @var \Modules\FleetManagement\Controller\ApiController $module */ - $module = $app->moduleManager->getModuleInstance('FleetManagement'); + /** @var \Modules\FleetManagement\Controller\ApiVehicleController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement', 'ApiVehicle'); /** @var array $type */ foreach ($types as $type) { @@ -201,13 +211,74 @@ final class Installer extends InstallerAbstract return $vehicleTypes; } + /** + * Install inspection type + * + * @param ApplicationAbstract $app Application + * @param array $types Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createInspectionTypes(ApplicationAbstract $app, array $types) : array + { + /** @var array $inspectionTypes */ + $inspectionTypes = []; + + /** @var \Modules\FleetManagement\Controller\ApiVehicleController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement', 'ApiVehicle'); + + /** @var array $type */ + foreach ($types as $type) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('name', $type['name'] ?? ''); + $request->setData('title', \reset($type['l11n'])); + $request->setData('language', \array_keys($type['l11n'])[0] ?? 'en'); + + $module->apiInspectionTypeCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $inspectionTypes[$type['name']] = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $isFirst = true; + foreach ($type['l11n'] as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('type', $inspectionTypes[$type['name']]['id']); + + $module->apiInspectionTypeL11nCreate($request, $response); + } + } + + return $inspectionTypes; + } + /** * Install default attribute types * - * @param ApplicationAbstract $app Application - * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * @param ApplicationAbstract $app Application + * @param array $attributes Attribute definition * - * @return array + * @return array * * @since 1.0.0 */ @@ -216,8 +287,8 @@ final class Installer extends InstallerAbstract /** @var array $itemAttrType */ $itemAttrType = []; - /** @var \Modules\FleetManagement\Controller\ApiController $module */ - $module = $app->moduleManager->getModuleInstance('FleetManagement'); + /** @var \Modules\FleetManagement\Controller\ApiVehicleAttributeController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement', 'ApiVehicleAttribute'); /** @var array $attribute */ foreach ($attributes as $attribute) { @@ -273,7 +344,7 @@ final class Installer extends InstallerAbstract * @param array $itemAttrType Attribute types * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition * - * @return array + * @return array * * @since 1.0.0 */ @@ -282,8 +353,8 @@ final class Installer extends InstallerAbstract /** @var array $itemAttrValue */ $itemAttrValue = []; - /** @var \Modules\FleetManagement\Controller\ApiController $module */ - $module = $app->moduleManager->getModuleInstance('FleetManagement'); + /** @var \Modules\FleetManagement\Controller\ApiVehicleAttributeController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement', 'ApiVehicleAttribute'); foreach ($attributes as $attribute) { $itemAttrValue[$attribute['name']] = []; diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index 0623738..614fe96 100644 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -12,7 +12,7 @@ */ declare(strict_types=1); -use Modules\FleetManagement\Controller\ApiController; +use Modules\FleetManagement\Controller\Controller; use Modules\FleetManagement\Models\PermissionCategory; use phpOMS\Account\PermissionType; use phpOMS\Router\RouteVerb; @@ -20,30 +20,52 @@ use phpOMS\Router\RouteVerb; return [ '^.*/fleet/vehicle/find.*$' => [ [ - 'dest' => '\Modules\FleetManagement\Controller\ApiController:apiVehicleFind', + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleController:apiVehicleFind', 'verb' => RouteVerb::GET, 'permission' => [ - 'module' => ApiController::NAME, + 'module' => Controller::NAME, 'type' => PermissionType::READ, 'state' => PermissionCategory::VEHICLE, ], ], ], + '^.*/fleet/vehicle/attribute.*$' => [ [ - 'dest' => '\Modules\FleetManagement\Controller\ApiController:apiVehicleAttributeCreate', + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleAttributeController:apiVehicleAttributeCreate', 'verb' => RouteVerb::PUT, 'permission' => [ - 'module' => ApiController::NAME, + 'module' => Controller::NAME, 'type' => PermissionType::READ, 'state' => PermissionCategory::VEHICLE, ], ], [ - 'dest' => '\Modules\FleetManagement\Controller\ApiController:apiVehicleAttributeUpdate', + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleAttributeController:apiVehicleAttributeUpdate', 'verb' => RouteVerb::SET, 'permission' => [ - 'module' => ApiController::NAME, + 'module' => Controller::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + + '^.*/fleet/driver/attribute.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiDriverAttributeController:apiDriverAttributeCreate', + 'verb' => RouteVerb::PUT, + 'permission' => [ + 'module' => Controller::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiDriverAttributeController:apiDriverAttributeUpdate', + 'verb' => RouteVerb::SET, + 'permission' => [ + 'module' => Controller::NAME, 'type' => PermissionType::READ, 'state' => PermissionCategory::VEHICLE, ], diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 5ba77d1..91b6c0c 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -75,6 +75,29 @@ return [ ], ], + '^.*/fleet/driver/attribute/type/list.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementDriverAttributeTypeList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/driver/attribute/type\?.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementDriverAttributeType', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/driver/list.*$' => [ [ 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementDriverList', diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php new file mode 100644 index 0000000..e00b002 --- /dev/null +++ b/Controller/ApiDriverAttributeController.php @@ -0,0 +1,534 @@ +validateDriverAttributeCreate($request))) { + $response->data['attribute_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attribute = $this->createDriverAttributeFromRequest($request); + $this->createModel($request->header->account, $attribute, DriverAttributeMapper::class, 'attribute', $request->getOrigin()); + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully created', $attribute); + } + + /** + * Method to create driver attribute from request. + * + * @param RequestAbstract $request Request + * + * @return Attribute + * + * @since 1.0.0 + */ + private function createDriverAttributeFromRequest(RequestAbstract $request) : Attribute + { + $attribute = new Attribute(); + $attribute->ref = (int) $request->getData('driver'); + $attribute->type = new NullAttributeType((int) $request->getData('type')); + + if ($request->hasData('value')) { + $attribute->value = new NullAttributeValue((int) $request->getData('value')); + } else { + $newRequest = clone $request; + $newRequest->setData('value', $request->getData('custom'), true); + + $value = $this->createAttributeValueFromRequest($newRequest); + + $attribute->value = $value; + } + + return $attribute; + } + + /** + * Validate driver attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateDriverAttributeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['type'] = !$request->hasData('type')) + || ($val['value'] = (!$request->hasData('value') && !$request->hasData('custom'))) + || ($val['driver'] = !$request->hasData('driver')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create driver attribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverAttributeUpdate($request))) { + $response->data['attribute_update'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $old = DriverAttributeMapper::get() + ->with('type') + ->with('type/defaults') + ->with('value') + ->where('id', (int) $request->getData('id')) + ->execute(); + + $new = $this->updateDriverAttributeFromRequest($request, $old->deepClone()); + $this->updateModel($request->header->account, $old, $new, DriverAttributeMapper::class, 'attribute', $request->getOrigin()); + + if ($new->value->getValue() !== $old->value->getValue()) { + $this->updateModel($request->header->account, $old->value, $new->value, DriverAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully updated', $new); + } + + /** + * Method to create driver attribute from request. + * + * @param RequestAbstract $request Request + * + * @return Attribute + * + * @since 1.0.0 + */ + private function updateDriverAttributeFromRequest(RequestAbstract $request, Attribute $attribute) : Attribute + { + if ($attribute->type->custom) { + if ($request->hasData('value')) { + // @question: we are overwriting the old value, could there be a use case where we want to create a new value and keep the old one? + $attribute->value->setValue($request->getData('value'), $attribute->type->datatype); + } + } else { + if ($request->hasData('value')) { + // @todo: fix by only accepting the value id to be used + // this is a workaround for now because the front end doesn't allow to dynamically show default values. + $value = $attribute->type->getDefaultByValue($request->getData('value')); + + if ($value->id !== 0) { + $attribute->value = $attribute->type->getDefaultByValue($request->getData('value')); + } + } + } + + return $attribute; + } + + /** + * Validate driver attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateDriverAttributeUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create driver attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverAttributeTypeL11nCreate($request))) { + $response->data['attr_type_l11n_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createDriverAttributeTypeL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, DriverAttributeTypeL11nMapper::class, 'attr_type_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } + + /** + * Method to create driver attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createDriverAttributeTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $attrL11n = new BaseStringL11n(); + $attrL11n->ref = $request->getDataInt('type') ?? 0; + $attrL11n->setLanguage( + $request->getDataString('language') ?? $request->header->l11n->language + ); + $attrL11n->content = $request->getDataString('title') ?? ''; + + return $attrL11n; + } + + /** + * Validate driver attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateDriverAttributeTypeL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['type'] = !$request->hasData('type')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create driver attribute type + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverAttributeTypeCreate($request))) { + $response->data['attr_type_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrType = $this->createAttributeTypeFromRequest($request); + $this->createModel($request->header->account, $attrType, DriverAttributeTypeMapper::class, 'attr_type', $request->getOrigin()); + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute type', 'Attribute type successfully created', $attrType); + } + + /** + * Method to create driver attribute from request. + * + * @param RequestAbstract $request Request + * + * @return AttributeType + * + * @since 1.0.0 + */ + private function createAttributeTypeFromRequest(RequestAbstract $request) : AttributeType + { + $attrType = new AttributeType($request->getDataString('name') ?? ''); + $attrType->datatype = $request->getDataInt('datatype') ?? 0; + $attrType->custom = $request->getDataBool('custom') ?? false; + $attrType->isRequired = (bool) ($request->getData('is_required') ?? false); + $attrType->validationPattern = $request->getDataString('validation_pattern') ?? ''; + $attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + $attrType->setFields($request->getDataInt('fields') ?? 0); + + return $attrType; + } + + /** + * Validate driver attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateDriverAttributeTypeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['name'] = !$request->hasData('name')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create driver attribute value + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverAttributeValueCreate($request))) { + $response->data['attr_value_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrValue = $this->createAttributeValueFromRequest($request); + $this->createModel($request->header->account, $attrValue, DriverAttributeValueMapper::class, 'attr_value', $request->getOrigin()); + + if ($attrValue->isDefault) { + $this->createModelRelation( + $request->header->account, + (int) $request->getData('type'), + $attrValue->id, + DriverAttributeTypeMapper::class, 'defaults', '', $request->getOrigin() + ); + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute value', 'Attribute value successfully created', $attrValue); + } + + /** + * Method to create driver attribute value from request. + * + * @param RequestAbstract $request Request + * + * @return AttributeValue + * + * @since 1.0.0 + */ + private function createAttributeValueFromRequest(RequestAbstract $request) : AttributeValue + { + /** @var AttributeType $type */ + $type = DriverAttributeTypeMapper::get() + ->where('id', $request->getDataInt('type') ?? 0) + ->execute(); + + $attrValue = new AttributeValue(); + $attrValue->isDefault = $request->getDataBool('default') ?? false; + $attrValue->setValue($request->getData('value'), $type->datatype); + + if ($request->hasData('title')) { + $attrValue->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + } + + return $attrValue; + } + + /** + * Validate driver attribute value create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateDriverAttributeValueCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['type'] = !$request->hasData('type')) + || ($val['value'] = !$request->hasData('value')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create driver attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverAttributeValueL11nCreate($request))) { + $response->data['attr_value_l11n_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createAttributeValueL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, DriverAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } + + /** + * Method to create driver attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createAttributeValueL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $attrL11n = new BaseStringL11n(); + $attrL11n->ref = $request->getDataInt('value') ?? 0; + $attrL11n->setLanguage( + $request->getDataString('language') ?? $request->header->l11n->language + ); + $attrL11n->content = $request->getDataString('title') ?? ''; + + return $attrL11n; + } + + /** + * Validate driver attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateDriverAttributeValueL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['value'] = !$request->hasData('value')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to handle api driver attributes + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttribute(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverAttributeValueL11nCreate($request))) { + $response->data['attr_value_l11n_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createAttributeValueL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, DriverAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } +} diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php new file mode 100644 index 0000000..a955901 --- /dev/null +++ b/Controller/ApiDriverController.php @@ -0,0 +1,588 @@ +validateDriverCreate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var Driver $driver */ + $driver = $this->createDriverFromRequest($request); + $this->createModel($request->header->account, $driver, DriverMapper::class, 'driver', $request->getOrigin()); + + if (!empty($request->files) + || !empty($request->getDataJson('media')) + ) { + $this->createDriverMedia($driver, $request); + } + + $this->fillJsonResponse( + $request, + $response, + NotificationLevel::OK, + '', + $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), + $driver + ); + } + + /** + * Method to create driver from request. + * + * @param RequestAbstract $request Request + * + * @return Driver Returns the created driver from the request + * + * @since 1.0.0 + */ + public function createDriverFromRequest(RequestAbstract $request) : Driver + { + $driver = new Driver(); + $driver->account = new NullAccount($request->getDataInt('account') ?? 1); + $driver->status = (int) ($request->getDataInt('status') ?? DriverStatus::INACTIVE); + + return $driver; + } + + /** + * Create media files for driver + * + * @param Driver $driver Driver + * @param RequestAbstract $request Request incl. media do upload + * + * @return void + * + * @since 1.0.0 + */ + private function createDriverMedia(Driver $driver, RequestAbstract $request) : void + { + $path = $this->createDriverDir($driver); + + if (!empty($uploadedFiles = $request->files)) { + $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( + names: [], + fileNames: [], + files: $uploadedFiles, + account: $request->header->account, + basePath: __DIR__ . '/../../../Modules/Media/Files' . $path, + virtualPath: $path, + pathSettings: PathSettings::FILE_PATH + ); + + $collection = null; + foreach ($uploaded as $media) { + $this->createModelRelation( + $request->header->account, + $driver->id, + $media->id, + DriverMapper::class, + 'media', + '', + $request->getOrigin() + ); + + if ($collection === null) { + /** @var \Modules\Media\Models\Collection $collection */ + $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); + + if ($collection->id === 0) { + $collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection( + $path, + $request->header->account, + __DIR__ . '/../../../Modules/Media/Files' . $path + ); + } + } + + $this->createModelRelation( + $request->header->account, + $collection->id, + $media->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + } + } + + if (!empty($mediaFiles = $request->getDataJson('media'))) { + $collection = null; + + foreach ($mediaFiles as $file) { + /** @var \Modules\Media\Models\Media $media */ + $media = MediaMapper::get()->where('id', (int) $file)->limit(1)->execute(); + + $this->createModelRelation( + $request->header->account, + $driver->id, + $media->id, + DriverMapper::class, + 'media', + '', + $request->getOrigin() + ); + + $ref = new Reference(); + $ref->name = $media->name; + $ref->source = new NullMedia($media->id); + $ref->createdBy = new NullAccount($request->header->account); + $ref->setVirtualPath($path); + + $this->createModel($request->header->account, $ref, ReferenceMapper::class, 'media_reference', $request->getOrigin()); + + if ($collection === null) { + /** @var \Modules\Media\Models\Collection $collection */ + $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); + + if ($collection->id === 0) { + $collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection( + $path, + $request->header->account, + __DIR__ . '/../../../Modules/Media/Files' . $path + ); + } + } + + $this->createModelRelation( + $request->header->account, + $collection->id, + $ref->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + } + } + } + + /** + * Validate driver create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateDriverCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['account'] = !$request->hasData('account')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create a bill + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiMediaAddToDriver(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateMediaAddToDriver($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\FleetManagement\Models\Driver\Driver $driver */ + $driver = DriverMapper::get()->where('id', (int) $request->getData('driver'))->execute(); + $path = $this->createDriverDir($driver); + + $uploaded = []; + if (!empty($uploadedFiles = $request->files)) { + $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( + names: [], + fileNames: [], + files: $uploadedFiles, + account: $request->header->account, + basePath: __DIR__ . '/../../../Modules/Media/Files' . $path, + virtualPath: $path, + pathSettings: PathSettings::FILE_PATH, + hasAccountRelation: false, + readContent: (bool) ($request->getData('parse_content') ?? false) + ); + + $collection = null; + foreach ($uploaded as $media) { + $this->createModelRelation( + $request->header->account, + $driver->id, + $media->id, + DriverMapper::class, + 'files', + '', + $request->getOrigin() + ); + + if ($request->hasData('type')) { + $this->createModelRelation( + $request->header->account, + $media->id, + $request->getDataInt('type'), + MediaMapper::class, + 'types', + '', + $request->getOrigin() + ); + } + + if ($collection === null) { + /** @var \Modules\Media\Models\Collection $collection */ + $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); + + if ($collection->id === 0) { + $collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection( + $path, + $request->header->account, + __DIR__ . '/../../../Modules/Media/Files' . $path, + ); + } + } + + $this->createModelRelation( + $request->header->account, + $collection->id, + $media->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + } + } + + if (!empty($mediaFiles = $request->getDataJson('media'))) { + foreach ($mediaFiles as $media) { + $this->createModelRelation( + $request->header->account, + $driver->id, + (int) $media, + DriverMapper::class, + 'files', + '', + $request->getOrigin() + ); + } + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Media', 'Media added to driver.', [ + 'upload' => $uploaded, + 'media' => $mediaFiles, + ]); + } + + /** + * Create media directory path + * + * @param Driver $driver Driver + * + * @return string + * + * @since 1.0.0 + */ + private function createDriverDir(Driver $driver) : string + { + return '/Modules/FleetManagement/Driver/' + . $this->app->unitId . '/' + . $driver->id; + } + + /** + * Method to validate bill creation from request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateMediaAddToDriver(RequestAbstract $request) : array + { + $val = []; + if (($val['media'] = (!$request->hasData('media') && empty($request->files))) + || ($val['driver'] = !$request->hasData('driver')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create a driver + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverInspectionTypeCreate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var BaseStringL11nType $driver */ + $driver = $this->createDriverInspectionTypeFromRequest($request); + $this->createModel($request->header->account, $driver, DriverInspectionTypeMapper::class, 'inspection_type', $request->getOrigin()); + + $this->fillJsonResponse( + $request, + $response, + NotificationLevel::OK, + '', + $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), + $driver + ); + } + + /** + * Method to create driver from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11nType Returns the created driver from the request + * + * @since 1.0.0 + */ + public function createDriverInspectionTypeFromRequest(RequestAbstract $request) : BaseStringL11nType + { + $type = new BaseStringL11nType(); + $type->title = $request->getDataString('name') ?? ''; + $type->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + + return $type; + } + + /** + * Validate driver create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateDriverInspectionTypeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['name'] = !$request->hasData('name')) + || ($val['title'] = !$request->hasData('title')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create driver attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateDriverInspectionTypeL11nCreate($request))) { + $response->data['inspection_type_l11n_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $typeL11n = $this->createDriverInspectionTypeL11nFromRequest($request); + $this->createModel($request->header->account, $typeL11n, DriverInspectionTypeL11nMapper::class, 'inspection_type_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + } + + /** + * Method to create driver attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createDriverInspectionTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $typeL11n = new BaseStringL11n(); + $typeL11n->ref = $request->getDataInt('type') ?? 0; + $typeL11n->setLanguage( + $request->getDataString('language') ?? $request->header->l11n->language + ); + $typeL11n->content = $request->getDataString('title') ?? ''; + + return $typeL11n; + } + + /** + * Validate driver attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateDriverInspectionTypeL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['type'] = !$request->hasData('type')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create item files + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateNoteCreate($request))) { + $response->data['driver_note_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $request->setData('virtualpath', '/Modules/FleetManagement/Items/' . $request->getData('id'), true); + $this->app->moduleManager->get('Editor', 'Api')->apiEditorCreate($request, $response, $data); + + if ($response->header->status !== RequestStatusCode::R_200) { + return; + } + + $responseData = $response->get($request->uri->__toString()); + if (!\is_array($responseData)) { + return; + } + + $model = $responseData['response']; + $this->createModelRelation($request->header->account, (int) $request->getData('id'), $model->id, DriverMapper::class, 'notes', '', $request->getOrigin()); + } + + /** + * Validate item note create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateNoteCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + ) { + return $val; + } + + return []; + } +} diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php new file mode 100644 index 0000000..841f726 --- /dev/null +++ b/Controller/ApiVehicleAttributeController.php @@ -0,0 +1,534 @@ +validateVehicleAttributeCreate($request))) { + $response->data['attribute_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attribute = $this->createVehicleAttributeFromRequest($request); + $this->createModel($request->header->account, $attribute, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully created', $attribute); + } + + /** + * Method to create vehicle attribute from request. + * + * @param RequestAbstract $request Request + * + * @return Attribute + * + * @since 1.0.0 + */ + private function createVehicleAttributeFromRequest(RequestAbstract $request) : Attribute + { + $attribute = new Attribute(); + $attribute->ref = (int) $request->getData('vehicle'); + $attribute->type = new NullAttributeType((int) $request->getData('type')); + + if ($request->hasData('value')) { + $attribute->value = new NullAttributeValue((int) $request->getData('value')); + } else { + $newRequest = clone $request; + $newRequest->setData('value', $request->getData('custom'), true); + + $value = $this->createAttributeValueFromRequest($newRequest); + + $attribute->value = $value; + } + + return $attribute; + } + + /** + * Validate vehicle attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['type'] = !$request->hasData('type')) + || ($val['value'] = (!$request->hasData('value') && !$request->hasData('custom'))) + || ($val['vehicle'] = !$request->hasData('vehicle')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeUpdate($request))) { + $response->data['attribute_update'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $old = VehicleAttributeMapper::get() + ->with('type') + ->with('type/defaults') + ->with('value') + ->where('id', (int) $request->getData('id')) + ->execute(); + + $new = $this->updateVehicleAttributeFromRequest($request, $old->deepClone()); + $this->updateModel($request->header->account, $old, $new, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); + + if ($new->value->getValue() !== $old->value->getValue()) { + $this->updateModel($request->header->account, $old->value, $new->value, VehicleAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully updated', $new); + } + + /** + * Method to create vehicle attribute from request. + * + * @param RequestAbstract $request Request + * + * @return Attribute + * + * @since 1.0.0 + */ + private function updateVehicleAttributeFromRequest(RequestAbstract $request, Attribute $attribute) : Attribute + { + if ($attribute->type->custom) { + if ($request->hasData('value')) { + // @question: we are overwriting the old value, could there be a use case where we want to create a new value and keep the old one? + $attribute->value->setValue($request->getData('value'), $attribute->type->datatype); + } + } else { + if ($request->hasData('value')) { + // @todo: fix by only accepting the value id to be used + // this is a workaround for now because the front end doesn't allow to dynamically show default values. + $value = $attribute->type->getDefaultByValue($request->getData('value')); + + if ($value->id !== 0) { + $attribute->value = $attribute->type->getDefaultByValue($request->getData('value')); + } + } + } + + return $attribute; + } + + /** + * Validate vehicle attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeTypeL11nCreate($request))) { + $response->data['attr_type_l11n_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createVehicleAttributeTypeL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, VehicleAttributeTypeL11nMapper::class, 'attr_type_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } + + /** + * Method to create vehicle attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createVehicleAttributeTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $attrL11n = new BaseStringL11n(); + $attrL11n->ref = $request->getDataInt('type') ?? 0; + $attrL11n->setLanguage( + $request->getDataString('language') ?? $request->header->l11n->language + ); + $attrL11n->content = $request->getDataString('title') ?? ''; + + return $attrL11n; + } + + /** + * Validate vehicle attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeTypeL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['type'] = !$request->hasData('type')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute type + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeTypeCreate($request))) { + $response->data['attr_type_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrType = $this->createAttributeTypeFromRequest($request); + $this->createModel($request->header->account, $attrType, VehicleAttributeTypeMapper::class, 'attr_type', $request->getOrigin()); + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute type', 'Attribute type successfully created', $attrType); + } + + /** + * Method to create vehicle attribute from request. + * + * @param RequestAbstract $request Request + * + * @return AttributeType + * + * @since 1.0.0 + */ + private function createAttributeTypeFromRequest(RequestAbstract $request) : AttributeType + { + $attrType = new AttributeType($request->getDataString('name') ?? ''); + $attrType->datatype = $request->getDataInt('datatype') ?? 0; + $attrType->custom = $request->getDataBool('custom') ?? false; + $attrType->isRequired = (bool) ($request->getData('is_required') ?? false); + $attrType->validationPattern = $request->getDataString('validation_pattern') ?? ''; + $attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + $attrType->setFields($request->getDataInt('fields') ?? 0); + + return $attrType; + } + + /** + * Validate vehicle attribute create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeTypeCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['name'] = !$request->hasData('name')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute value + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeValueCreate($request))) { + $response->data['attr_value_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrValue = $this->createAttributeValueFromRequest($request); + $this->createModel($request->header->account, $attrValue, VehicleAttributeValueMapper::class, 'attr_value', $request->getOrigin()); + + if ($attrValue->isDefault) { + $this->createModelRelation( + $request->header->account, + (int) $request->getData('type'), + $attrValue->id, + VehicleAttributeTypeMapper::class, 'defaults', '', $request->getOrigin() + ); + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute value', 'Attribute value successfully created', $attrValue); + } + + /** + * Method to create vehicle attribute value from request. + * + * @param RequestAbstract $request Request + * + * @return AttributeValue + * + * @since 1.0.0 + */ + private function createAttributeValueFromRequest(RequestAbstract $request) : AttributeValue + { + /** @var AttributeType $type */ + $type = VehicleAttributeTypeMapper::get() + ->where('id', $request->getDataInt('type') ?? 0) + ->execute(); + + $attrValue = new AttributeValue(); + $attrValue->isDefault = $request->getDataBool('default') ?? false; + $attrValue->setValue($request->getData('value'), $type->datatype); + + if ($request->hasData('title')) { + $attrValue->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + } + + return $attrValue; + } + + /** + * Validate vehicle attribute value create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeValueCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['type'] = !$request->hasData('type')) + || ($val['value'] = !$request->hasData('value')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create vehicle attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { + $response->data['attr_value_l11n_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createAttributeValueL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } + + /** + * Method to create vehicle attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createAttributeValueL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $attrL11n = new BaseStringL11n(); + $attrL11n->ref = $request->getDataInt('value') ?? 0; + $attrL11n->setLanguage( + $request->getDataString('language') ?? $request->header->l11n->language + ); + $attrL11n->content = $request->getDataString('title') ?? ''; + + return $attrL11n; + } + + /** + * Validate vehicle attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateVehicleAttributeValueL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['title'] = !$request->hasData('title')) + || ($val['value'] = !$request->hasData('value')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to handle api vehicle attributes + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttribute(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { + $response->data['attr_value_l11n_create'] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $attrL11n = $this->createAttributeValueL11nFromRequest($request); + $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + } +} diff --git a/Controller/ApiController.php b/Controller/ApiVehicleController.php similarity index 61% rename from Controller/ApiController.php rename to Controller/ApiVehicleController.php index b52eeb4..59c45d3 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiVehicleController.php @@ -15,21 +15,11 @@ declare(strict_types=1); namespace Modules\FleetManagement\Controller; use Modules\Admin\Models\NullAccount; -use Modules\Attribute\Models\Attribute; -use Modules\Attribute\Models\AttributeType; -use Modules\Attribute\Models\AttributeValue; -use Modules\Attribute\Models\NullAttributeType; -use Modules\Attribute\Models\NullAttributeValue; use Modules\FleetManagement\Models\FuelTypeL11nMapper; use Modules\FleetManagement\Models\FuelTypeMapper; use Modules\FleetManagement\Models\InspectionTypeL11nMapper; use Modules\FleetManagement\Models\InspectionTypeMapper; use Modules\FleetManagement\Models\Vehicle; -use Modules\FleetManagement\Models\VehicleAttributeMapper; -use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; -use Modules\FleetManagement\Models\VehicleAttributeTypeMapper; -use Modules\FleetManagement\Models\VehicleAttributeValueL11nMapper; -use Modules\FleetManagement\Models\VehicleAttributeValueMapper; use Modules\FleetManagement\Models\VehicleMapper; use Modules\FleetManagement\Models\VehicleStatus; use Modules\FleetManagement\Models\VehicleTypeL11nMapper; @@ -39,6 +29,7 @@ use Modules\Media\Models\MediaMapper; use Modules\Media\Models\NullMedia; use Modules\Media\Models\PathSettings; use Modules\Media\Models\Reference; +use Modules\Media\Models\ReferenceMapper; use phpOMS\Localization\BaseStringL11n; use phpOMS\Localization\BaseStringL11nType; use phpOMS\Localization\ISO639x1Enum; @@ -57,7 +48,7 @@ use phpOMS\Model\Message\FormValidation; * @link https://jingga.app * @since 1.0.0 */ -final class ApiController extends Controller +final class ApiVehicleController extends Controller { /** * Api method to create a vehicle @@ -449,7 +440,7 @@ final class ApiController extends Controller ); if ($collection === null) { - /** @var \Modules\Media\Models\Media $media */ + /** @var \Modules\Media\Models\Collection $collection */ $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); if ($collection->id === 0) { @@ -499,7 +490,7 @@ final class ApiController extends Controller $this->createModel($request->header->account, $ref, ReferenceMapper::class, 'media_reference', $request->getOrigin()); if ($collection === null) { - /** @var \Modules\Media\Models\Media $media */ + /** @var \Modules\Media\Models\Collection $collection */ $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); if ($collection->id === 0) { @@ -545,496 +536,6 @@ final class ApiController extends Controller return []; } - /** - * Api method to create vehicle attribute - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttributeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeCreate($request))) { - $response->data['attribute_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $attribute = $this->createVehicleAttributeFromRequest($request); - $this->createModel($request->header->account, $attribute, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully created', $attribute); - } - - /** - * Method to create vehicle attribute from request. - * - * @param RequestAbstract $request Request - * - * @return Attribute - * - * @since 1.0.0 - */ - private function createVehicleAttributeFromRequest(RequestAbstract $request) : Attribute - { - $attribute = new Attribute(); - $attribute->ref = (int) $request->getData('vehicle'); - $attribute->type = new NullAttributeType((int) $request->getData('type')); - - if ($request->hasData('value')) { - $attribute->value = new NullAttributeValue((int) $request->getData('value')); - } else { - $newRequest = clone $request; - $newRequest->setData('value', $request->getData('custom'), true); - - $value = $this->createAttributeValueFromRequest($newRequest); - - $attribute->value = $value; - } - - return $attribute; - } - - /** - * Validate vehicle attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['type'] = !$request->hasData('type')) - || ($val['value'] = (!$request->hasData('value') && !$request->hasData('custom'))) - || ($val['vehicle'] = !$request->hasData('vehicle')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to create vehicle attribute - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeUpdate($request))) { - $response->data['attribute_update'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $old = VehicleAttributeMapper::get() - ->with('type') - ->with('type/defaults') - ->with('value') - ->where('id', (int) $request->getData('id')) - ->execute(); - - $new = $this->updateVehicleAttributeFromRequest($request, $old->deepClone()); - $this->updateModel($request->header->account, $old, $new, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); - - if ($new->value->getValue() !== $old->value->getValue()) { - $this->updateModel($request->header->account, $old->value, $new->value, VehicleAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); - } - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully updated', $new); - } - - /** - * Method to create vehicle attribute from request. - * - * @param RequestAbstract $request Request - * - * @return Attribute - * - * @since 1.0.0 - */ - private function updateVehicleAttributeFromRequest(RequestAbstract $request, Attribute $attribute) : Attribute - { - if ($attribute->type->custom) { - if ($request->hasData('value')) { - // @question: we are overwriting the old value, could there be a use case where we want to create a new value and keep the old one? - $attribute->value->setValue($request->getData('value'), $attribute->type->datatype); - } - } else { - if ($request->hasData('value')) { - // @todo: fix by only accepting the value id to be used - // this is a workaround for now because the front end doesn't allow to dynamically show default values. - $value = $attribute->type->getDefaultByValue($request->getData('value')); - - if ($value->id !== 0) { - $attribute->value = $attribute->type->getDefaultByValue($request->getData('value')); - } - } - } - - return $attribute; - } - - /** - * Validate vehicle attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeUpdate(RequestAbstract $request) : array - { - $val = []; - if (($val['id'] = !$request->hasData('id')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to create vehicle attribute l11n - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeTypeL11nCreate($request))) { - $response->data['attr_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $attrL11n = $this->createVehicleAttributeTypeL11nFromRequest($request); - $this->createModel($request->header->account, $attrL11n, VehicleAttributeTypeL11nMapper::class, 'attr_type_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); - } - - /** - * Method to create vehicle attribute l11n from request. - * - * @param RequestAbstract $request Request - * - * @return BaseStringL11n - * - * @since 1.0.0 - */ - private function createVehicleAttributeTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n - { - $attrL11n = new BaseStringL11n(); - $attrL11n->ref = $request->getDataInt('type') ?? 0; - $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $attrL11n->content = $request->getDataString('title') ?? ''; - - return $attrL11n; - } - - /** - * Validate vehicle attribute l11n create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeTypeL11nCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['type'] = !$request->hasData('type')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to create vehicle attribute type - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeTypeCreate($request))) { - $response->data['attr_type_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $attrType = $this->createAttributeTypeFromRequest($request); - $this->createModel($request->header->account, $attrType, VehicleAttributeTypeMapper::class, 'attr_type', $request->getOrigin()); - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute type', 'Attribute type successfully created', $attrType); - } - - /** - * Method to create vehicle attribute from request. - * - * @param RequestAbstract $request Request - * - * @return AttributeType - * - * @since 1.0.0 - */ - private function createAttributeTypeFromRequest(RequestAbstract $request) : AttributeType - { - $attrType = new AttributeType($request->getDataString('name') ?? ''); - $attrType->datatype = $request->getDataInt('datatype') ?? 0; - $attrType->custom = $request->getDataBool('custom') ?? false; - $attrType->isRequired = (bool) ($request->getData('is_required') ?? false); - $attrType->validationPattern = $request->getDataString('validation_pattern') ?? ''; - $attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); - $attrType->setFields($request->getDataInt('fields') ?? 0); - - return $attrType; - } - - /** - * Validate vehicle attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeTypeCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['name'] = !$request->hasData('name')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to create vehicle attribute value - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeValueCreate($request))) { - $response->data['attr_value_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $attrValue = $this->createAttributeValueFromRequest($request); - $this->createModel($request->header->account, $attrValue, VehicleAttributeValueMapper::class, 'attr_value', $request->getOrigin()); - - if ($attrValue->isDefault) { - $this->createModelRelation( - $request->header->account, - (int) $request->getData('type'), - $attrValue->id, - VehicleAttributeTypeMapper::class, 'defaults', '', $request->getOrigin() - ); - } - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute value', 'Attribute value successfully created', $attrValue); - } - - /** - * Method to create vehicle attribute value from request. - * - * @param RequestAbstract $request Request - * - * @return AttributeValue - * - * @since 1.0.0 - */ - private function createAttributeValueFromRequest(RequestAbstract $request) : AttributeValue - { - /** @var AttributeType $type */ - $type = VehicleAttributeTypeMapper::get() - ->where('id', $request->getDataInt('type') ?? 0) - ->execute(); - - $attrValue = new AttributeValue(); - $attrValue->isDefault = $request->getDataBool('default') ?? false; - $attrValue->setValue($request->getData('value'), $type->datatype); - - if ($request->hasData('title')) { - $attrValue->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); - } - - return $attrValue; - } - - /** - * Validate vehicle attribute value create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeValueCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['type'] = !$request->hasData('type')) - || ($val['value'] = !$request->hasData('value')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to create vehicle attribute l11n - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { - $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $attrL11n = $this->createAttributeValueL11nFromRequest($request); - $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); - } - - /** - * Method to create vehicle attribute l11n from request. - * - * @param RequestAbstract $request Request - * - * @return BaseStringL11n - * - * @since 1.0.0 - */ - private function createAttributeValueL11nFromRequest(RequestAbstract $request) : BaseStringL11n - { - $attrL11n = new BaseStringL11n(); - $attrL11n->ref = $request->getDataInt('value') ?? 0; - $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $attrL11n->content = $request->getDataString('title') ?? ''; - - return $attrL11n; - } - - /** - * Validate vehicle attribute l11n create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeValueL11nCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['value'] = !$request->hasData('value')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to handle api vehicle attributes - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttribute(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { - $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $attrL11n = $this->createAttributeValueL11nFromRequest($request); - $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); - } - /** * Api method to create a bill * @@ -1100,6 +601,7 @@ final class ApiController extends Controller } if ($collection === null) { + /** @var \Modules\Media\Models\Collection $collection */ $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); if ($collection->id === 0) { @@ -1202,9 +704,9 @@ final class ApiController extends Controller return; } - /** @var BaseStringL11nType $vehicle */ - $vehicle = $this->createInspectionTypeFromRequest($request); - $this->createModel($request->header->account, $vehicle, InspectionTypeMapper::class, 'inspection_type', $request->getOrigin()); + /** @var BaseStringL11nType $inspection */ + $inspection = $this->createInspectionTypeFromRequest($request); + $this->createModel($request->header->account, $inspection, InspectionTypeMapper::class, 'inspection_type', $request->getOrigin()); $this->fillJsonResponse( $request, @@ -1212,7 +714,7 @@ final class ApiController extends Controller NotificationLevel::OK, '', $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), - $vehicle + $inspection ); } @@ -1341,7 +843,7 @@ final class ApiController extends Controller { if (!empty($val = $this->validateNoteCreate($request))) { $response->data['vehicle_note_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; return; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 3baac73..809ba4f 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -159,10 +159,10 @@ final class BackendController extends Controller SettingsEnum::DEFAULT_LOCALIZATION, ]); - $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); - $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); $view->data['vehicle-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); return $view; @@ -193,6 +193,8 @@ final class BackendController extends Controller ->with('attributes/type') ->with('attributes/value') ->with('attributes/type/l11n') + ->with('files') + ->with('files/types') ->with('type') ->with('type/l11n') ->with('fuelType') @@ -236,6 +238,7 @@ final class BackendController extends Controller $units = UnitMapper::getAll() ->execute(); + $view->data['units'] = $units; /** @var \Model\Setting $settings */ @@ -243,10 +246,10 @@ final class BackendController extends Controller SettingsEnum::DEFAULT_LOCALIZATION, ]); - $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); - $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); $view->data['vehicle-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); return $view; diff --git a/Models/Driver/Driver.php b/Models/Driver/Driver.php new file mode 100644 index 0000000..c08ddab --- /dev/null +++ b/Models/Driver/Driver.php @@ -0,0 +1,79 @@ + $this->id, + 'status' => $this->status, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } + + use \Modules\Media\Models\MediaListTrait; + use \Modules\Editor\Models\EditorDocListTrait; + use \Modules\Attribute\Models\AttributeHolderTrait; +} diff --git a/Models/Driver/DriverAttributeMapper.php b/Models/Driver/DriverAttributeMapper.php new file mode 100644 index 0000000..d60bc02 --- /dev/null +++ b/Models/Driver/DriverAttributeMapper.php @@ -0,0 +1,86 @@ + + */ +final class DriverAttributeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_attr_id' => ['name' => 'fleetmgmt_driver_attr_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_attr_item' => ['name' => 'fleetmgmt_driver_attr_item', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_driver_attr_type' => ['name' => 'fleetmgmt_driver_attr_type', 'type' => 'int', 'internal' => 'type'], + 'fleetmgmt_driver_attr_value' => ['name' => 'fleetmgmt_driver_attr_value', 'type' => 'int', 'internal' => 'value'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'type' => [ + 'mapper' => DriverAttributeTypeMapper::class, + 'external' => 'fleetmgmt_driver_attr_type', + ], + 'value' => [ + 'mapper' => DriverAttributeValueMapper::class, + 'external' => 'fleetmgmt_driver_attr_value', + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = Attribute::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_attr'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_attr_id'; +} diff --git a/Models/Driver/DriverAttributeTypeL11nMapper.php b/Models/Driver/DriverAttributeTypeL11nMapper.php new file mode 100644 index 0000000..2ef0efc --- /dev/null +++ b/Models/Driver/DriverAttributeTypeL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class DriverAttributeTypeL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_attr_type_l11n_id' => ['name' => 'fleetmgmt_driver_attr_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_attr_type_l11n_title' => ['name' => 'fleetmgmt_driver_attr_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_driver_attr_type_l11n_type' => ['name' => 'fleetmgmt_driver_attr_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_driver_attr_type_l11n_lang' => ['name' => 'fleetmgmt_driver_attr_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_attr_type_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_attr_type_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/Driver/DriverAttributeTypeMapper.php b/Models/Driver/DriverAttributeTypeMapper.php new file mode 100644 index 0000000..a3fba64 --- /dev/null +++ b/Models/Driver/DriverAttributeTypeMapper.php @@ -0,0 +1,94 @@ + + */ +final class DriverAttributeTypeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_attr_type_id' => ['name' => 'fleetmgmt_driver_attr_type_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_attr_type_name' => ['name' => 'fleetmgmt_driver_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'fleetmgmt_driver_attr_type_datatype' => ['name' => 'fleetmgmt_driver_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'], + 'fleetmgmt_driver_attr_type_fields' => ['name' => 'fleetmgmt_driver_attr_type_fields', 'type' => 'int', 'internal' => 'fields'], + 'fleetmgmt_driver_attr_type_custom' => ['name' => 'fleetmgmt_driver_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'], + 'fleetmgmt_driver_attr_type_pattern' => ['name' => 'fleetmgmt_driver_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'], + 'fleetmgmt_driver_attr_type_required' => ['name' => 'fleetmgmt_driver_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => DriverAttributeTypeL11nMapper::class, + 'table' => 'fleetmgmt_driver_attr_type_l11n', + 'self' => 'fleetmgmt_driver_attr_type_l11n_type', + 'column' => 'content', + 'external' => null, + ], + 'defaults' => [ + 'mapper' => DriverAttributeValueMapper::class, + 'table' => 'fleetmgmt_driver_attr_default', + 'self' => 'fleetmgmt_driver_attr_default_type', + 'external' => 'fleetmgmt_driver_attr_default_value', + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = AttributeType::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_attr_type'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_attr_type_id'; +} diff --git a/Models/Driver/DriverAttributeValueL11nMapper.php b/Models/Driver/DriverAttributeValueL11nMapper.php new file mode 100644 index 0000000..abd11de --- /dev/null +++ b/Models/Driver/DriverAttributeValueL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class DriverAttributeValueL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_attr_value_l11n_id' => ['name' => 'fleetmgmt_driver_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_attr_value_l11n_title' => ['name' => 'fleetmgmt_driver_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_driver_attr_value_l11n_value' => ['name' => 'fleetmgmt_driver_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_driver_attr_value_l11n_lang' => ['name' => 'fleetmgmt_driver_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_attr_value_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_attr_value_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/Driver/DriverAttributeValueMapper.php b/Models/Driver/DriverAttributeValueMapper.php new file mode 100644 index 0000000..08df185 --- /dev/null +++ b/Models/Driver/DriverAttributeValueMapper.php @@ -0,0 +1,89 @@ + + */ +final class DriverAttributeValueMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_attr_value_id' => ['name' => 'fleetmgmt_driver_attr_value_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_attr_value_default' => ['name' => 'fleetmgmt_driver_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], + 'fleetmgmt_driver_attr_value_valueStr' => ['name' => 'fleetmgmt_driver_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], + 'fleetmgmt_driver_attr_value_valueInt' => ['name' => 'fleetmgmt_driver_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], + 'fleetmgmt_driver_attr_value_valueDec' => ['name' => 'fleetmgmt_driver_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], + 'fleetmgmt_driver_attr_value_valueDat' => ['name' => 'fleetmgmt_driver_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], + 'fleetmgmt_driver_attr_value_unit' => ['name' => 'fleetmgmt_driver_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], + 'fleetmgmt_driver_attr_value_deptype' => ['name' => 'fleetmgmt_driver_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], + 'fleetmgmt_driver_attr_value_depvalue' => ['name' => 'fleetmgmt_driver_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => DriverAttributeValueL11nMapper::class, + 'table' => 'fleetmgmt_driver_attr_value_l11n', + 'self' => 'fleetmgmt_driver_attr_value_l11n_value', + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = AttributeValue::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_attr_value'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_attr_value_id'; +} diff --git a/Models/Driver/DriverInspection.php b/Models/Driver/DriverInspection.php new file mode 100644 index 0000000..d3212bf --- /dev/null +++ b/Models/Driver/DriverInspection.php @@ -0,0 +1,78 @@ +type = new BaseStringL11nType(); + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } + + use \Modules\Media\Models\MediaListTrait; +} diff --git a/Models/Driver/DriverInspectionMapper.php b/Models/Driver/DriverInspectionMapper.php new file mode 100644 index 0000000..2803632 --- /dev/null +++ b/Models/Driver/DriverInspectionMapper.php @@ -0,0 +1,84 @@ + + */ +final class DriverInspectionMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_inspection_id' => ['name' => 'fleetmgmt_driver_inspection_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_inspection_description' => ['name' => 'fleetmgmt_driver_inspection_description', 'type' => 'string', 'internal' => 'description'], + 'fleetmgmt_driver_inspection_status' => ['name' => 'fleetmgmt_driver_inspection_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_driver_inspection_interval' => ['name' => 'fleetmgmt_driver_inspection_interval', 'type' => 'int', 'internal' => 'interval'], + 'fleetmgmt_driver_inspection_next' => ['name' => 'fleetmgmt_driver_inspection_next', 'type' => 'DateTime', 'internal' => 'next'], + 'fleetmgmt_driver_inspection_type' => ['name' => 'fleetmgmt_driver_inspection_type', 'type' => 'int', 'internal' => 'type'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'type' => [ + 'mapper' => DriverInspectionTypeMapper::class, + 'external' => 'fleetmgmt_driver_inspection_type', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_inspection'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_inspection_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = DriverInspection::class; +} diff --git a/Models/Driver/DriverInspectionStatus.php b/Models/Driver/DriverInspectionStatus.php new file mode 100644 index 0000000..d5b0364 --- /dev/null +++ b/Models/Driver/DriverInspectionStatus.php @@ -0,0 +1,36 @@ + + */ +final class DriverInspectionTypeL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_inspection_type_l11n_id' => ['name' => 'fleetmgmt_driver_inspection_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_inspection_type_l11n_title' => ['name' => 'fleetmgmt_driver_inspection_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'fleetmgmt_driver_inspection_type_l11n_type' => ['name' => 'fleetmgmt_driver_inspection_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_driver_inspection_type_l11n_lang' => ['name' => 'fleetmgmt_driver_inspection_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_inspection_type_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_inspection_type_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/Driver/DriverInspectionTypeMapper.php b/Models/Driver/DriverInspectionTypeMapper.php new file mode 100644 index 0000000..3a21278 --- /dev/null +++ b/Models/Driver/DriverInspectionTypeMapper.php @@ -0,0 +1,83 @@ + + */ +final class DriverInspectionTypeMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_inspection_type_id' => ['name' => 'fleetmgmt_driver_inspection_type_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_inspection_type_name' => ['name' => 'fleetmgmt_driver_inspection_type_name', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => DriverInspectionTypeL11nMapper::class, + 'table' => 'fleetmgmt_driver_inspection_type_l11n', + 'self' => 'fleetmgmt_driver_inspection_type_l11n_type', + 'column' => 'content', + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11nType::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver_inspection_type'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_inspection_type_id'; +} diff --git a/Models/Driver/DriverMapper.php b/Models/Driver/DriverMapper.php new file mode 100644 index 0000000..bc3ff1f --- /dev/null +++ b/Models/Driver/DriverMapper.php @@ -0,0 +1,102 @@ + + */ +final class DriverMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_driver_id' => ['name' => 'fleetmgmt_driver_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_status' => ['name' => 'fleetmgmt_driver_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_driver_account' => ['name' => 'fleetmgmt_driver_account', 'type' => 'int', 'internal' => 'account'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'files' => [ + 'mapper' => MediaMapper::class, + 'table' => 'fleetmgmt_driver_media', + 'external' => 'fleetmgmt_driver_media_media', + 'self' => 'fleetmgmt_driver_media_vehicle', + ], + 'attributes' => [ + 'mapper' => DriverAttributeMapper::class, + 'table' => 'fleetmgmt_driver_attr', + 'self' => 'fleetmgmt_driver_attr_item', + 'external' => null, + ], + 'notes' => [ + 'mapper' => EditorDocMapper::class, /* mapper of the related object */ + 'table' => 'fleetmgmt_driver_note', /* table of the related object, null if no relation table is used (many->1) */ + 'external' => 'fleetmgmt_driver_note_doc', + 'self' => 'fleetmgmt_driver_note_driver', + ], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'account' => [ + 'mapper' => AccountMapper::class, + 'external' => 'fleetmgmt_driver_account', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_driver'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_driver_id'; +} diff --git a/Models/Driver/DriverStatus.php b/Models/Driver/DriverStatus.php new file mode 100644 index 0000000..2a18e6b --- /dev/null +++ b/Models/Driver/DriverStatus.php @@ -0,0 +1,34 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/Driver/NullDriverInspection.php b/Models/Driver/NullDriverInspection.php new file mode 100644 index 0000000..746820f --- /dev/null +++ b/Models/Driver/NullDriverInspection.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/Inspection.php b/Models/Inspection.php index be899ab..c22e632 100644 --- a/Models/Inspection.php +++ b/Models/Inspection.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; +use phpOMS\Localization\BaseStringL11nType; + /** * Inspection class. * @@ -38,16 +40,39 @@ class Inspection implements \JsonSerializable /** * Inspectio interval in months - * + * * @var int * @since 1.0.0 */ public int $interval = 0; + /** + * Constructor + * + * @since 1.0.0 + */ public function __construct() { $this->type = new BaseStringL11nType(); } + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } + use \Modules\Media\Models\MediaListTrait; } diff --git a/Models/InspectionTypeMapper.php b/Models/InspectionTypeMapper.php index f7df79f..36d02cc 100644 --- a/Models/InspectionTypeMapper.php +++ b/Models/InspectionTypeMapper.php @@ -38,7 +38,7 @@ final class InspectionTypeMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_inspection_type_id' => ['name' => 'fleetmgmt_inspection_type_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_inspection_type_name' => ['name' => 'fleetmgmt_inspection_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'fleetmgmt_inspection_type_name' => ['name' => 'fleetmgmt_inspection_type_name', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], ]; /** diff --git a/Models/License.php b/Models/License.php new file mode 100644 index 0000000..e69de29 diff --git a/Models/LicenseType.php b/Models/LicenseType.php new file mode 100644 index 0000000..e69de29 diff --git a/Models/NullInspection.php b/Models/NullInspection.php index e69de29..2b55a97 100644 --- a/Models/NullInspection.php +++ b/Models/NullInspection.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/Vehicle.php b/Models/Vehicle.php index 80f67a0..35f5c17 100644 --- a/Models/Vehicle.php +++ b/Models/Vehicle.php @@ -50,6 +50,11 @@ class Vehicle implements \JsonSerializable public \DateTimeImmutable $createdAt; + /** + * Constructor. + * + * @since 1.0.0 + */ public function __construct() { $this->createdAt = new \DateTimeImmutable('now'); @@ -74,7 +79,7 @@ class Vehicle implements \JsonSerializable { return $this->toArray(); } - + use \Modules\Media\Models\MediaListTrait; use \Modules\Editor\Models\EditorDocListTrait; use \Modules\Attribute\Models\AttributeHolderTrait; diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php index 6c2659f..4b46bab 100644 --- a/Models/VehicleMapper.php +++ b/Models/VehicleMapper.php @@ -70,9 +70,9 @@ final class VehicleMapper extends DataMapperFactory ], 'notes' => [ 'mapper' => EditorDocMapper::class, /* mapper of the related object */ - 'table' => 'bizexpenses_expense_note', /* table of the related object, null if no relation table is used (many->1) */ - 'external' => 'bizexpenses_expense_note_doc', - 'self' => 'bizexpenses_expense_note_expense', + 'table' => 'fleetmgmt_vehicle_note', /* table of the related object, null if no relation table is used (many->1) */ + 'external' => 'fleetmgmt_vehicle_note_doc', + 'self' => 'fleetmgmt_vehicle_note_vehicle', ], ]; From 8517c6a051a30df8b6178755886b4a16afe64e19 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Thu, 15 Jun 2023 01:53:26 +0200 Subject: [PATCH 32/89] Continue implementation. --- Admin/Install/Navigation.install.json | 23 +- Admin/Install/db.json | 12 +- Admin/Install/driverinspectiontype.json | 9 + Admin/Installer.php | 71 +++++ Admin/Routes/Web/Api.php | 44 ++- Controller/ApiDriverController.php | 41 ++- Controller/ApiVehicleController.php | 35 ++- Controller/BackendController.php | 98 +++++++ Models/Driver/DriverAttributeMapper.php | 2 +- Models/Driver/DriverMapper.php | 2 +- Models/PermissionCategory.php | 14 +- Models/VehicleAttributeMapper.php | 2 +- Theme/Backend/Lang/Navigation.en.lang.php | 7 +- Theme/Backend/Lang/en.lang.php | 4 + Theme/Backend/driver-list.tpl.php | 100 +++++++ Theme/Backend/driver-profile.tpl.php | 318 ++++++++++++++++++++++ Theme/Backend/vehicle-profile.tpl.php | 18 +- 17 files changed, 762 insertions(+), 38 deletions(-) create mode 100644 Admin/Install/driverinspectiontype.json create mode 100644 Theme/Backend/driver-list.tpl.php create mode 100644 Theme/Backend/driver-profile.tpl.php diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 12ec25e..bb2027b 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -110,7 +110,7 @@ "pid": "/", "type": 2, "subtype": 1, - "name": "Inspection", + "name": "Inspections", "uri": "{/base}/fleet/inspection/list", "target": "self", "icon": null, @@ -139,11 +139,26 @@ "pid": "/fleet/inspection", "type": 3, "subtype": 1, - "name": "Create", - "uri": "{/base}/fleet/inspection/create?{?}", + "name": "VehicleInspectionTypes", + "uri": "{/base}/fleet/vehicle/inspection/type/list?{?}", "target": "self", "icon": null, - "order": 1, + "order": 5, + "from": "FleetManagement", + "permission": { "permission": 4, "category": null, "element": null }, + "parent": 1003504001, + "children": [] + }, + { + "id": 1003504301, + "pid": "/fleet/inspection", + "type": 3, + "subtype": 1, + "name": "DriverInspectionTypes", + "uri": "{/base}/fleet/driver/inspection/type/list?{?}", + "target": "self", + "icon": null, + "order": 10, "from": "FleetManagement", "permission": { "permission": 4, "category": null, "element": null }, "parent": 1003504001, diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 1bc0a61..e89eecf 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -428,7 +428,7 @@ "null": false }, "fleetmgmt_attr_type_required": { - "description": "Every item must have this attribute type if set to true.", + "description": "Every vehicle must have this attribute type if set to true.", "name": "fleetmgmt_attr_type_required", "type": "TINYINT(1)", "null": false @@ -601,8 +601,8 @@ "primary": true, "autoincrement": true }, - "fleetmgmt_vehicle_attr_item": { - "name": "fleetmgmt_vehicle_attr_item", + "fleetmgmt_vehicle_attr_vehicle": { + "name": "fleetmgmt_vehicle_attr_vehicle", "type": "INT(11)", "null": false, "foreignTable": "fleetmgmt_vehicle", @@ -709,7 +709,7 @@ "null": false }, "fleetmgmt_driver_attr_type_required": { - "description": "Every item must have this attribute type if set to true.", + "description": "Every driver must have this attribute type if set to true.", "name": "fleetmgmt_driver_attr_type_required", "type": "TINYINT(1)", "null": false @@ -882,8 +882,8 @@ "primary": true, "autoincrement": true }, - "fleetmgmt_driver_attr_item": { - "name": "fleetmgmt_driver_attr_item", + "fleetmgmt_driver_attr_driver": { + "name": "fleetmgmt_driver_attr_driver", "type": "INT(11)", "null": false, "foreignTable": "fleetmgmt_driver", diff --git a/Admin/Install/driverinspectiontype.json b/Admin/Install/driverinspectiontype.json new file mode 100644 index 0000000..a9a1672 --- /dev/null +++ b/Admin/Install/driverinspectiontype.json @@ -0,0 +1,9 @@ +[ + { + "name": "license", + "l11n": { + "en": "License", + "de": "Führerschein" + } + } +] \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php index 7ada66c..0a2de51 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -87,6 +87,16 @@ final class Installer extends InstallerAbstract /** @var array $types */ $types = \json_decode($fileContent, true); $inspectionTypes = self::createInspectionTypes($app, $types); + + /* Inspection types */ + $fileContent = \file_get_contents(__DIR__ . '/Install/driverinspectiontype.json'); + if ($fileContent === false) { + return; + } + + /** @var array $types */ + $types = \json_decode($fileContent, true); + $inspectionTypes = self::createDriverInspectionTypes($app, $types); } /** @@ -272,6 +282,67 @@ final class Installer extends InstallerAbstract return $inspectionTypes; } + /** + * Install inspection type + * + * @param ApplicationAbstract $app Application + * @param array $types Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createDriverInspectionTypes(ApplicationAbstract $app, array $types) : array + { + /** @var array $inspectionTypes */ + $inspectionTypes = []; + + /** @var \Modules\FleetManagement\Controller\ApiVehicleController $module */ + $module = $app->moduleManager->getModuleInstance('FleetManagement', 'ApiDriver'); + + /** @var array $type */ + foreach ($types as $type) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('name', $type['name'] ?? ''); + $request->setData('title', \reset($type['l11n'])); + $request->setData('language', \array_keys($type['l11n'])[0] ?? 'en'); + + $module->apiDriverInspectionTypeCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $inspectionTypes[$type['name']] = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $isFirst = true; + foreach ($type['l11n'] as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('type', $inspectionTypes[$type['name']]['id']); + + $module->apiDriverInspectionTypeL11nCreate($request, $response); + } + } + + return $inspectionTypes; + } + /** * Install default attribute types * diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index 614fe96..95a61a8 100644 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -58,12 +58,33 @@ return [ 'permission' => [ 'module' => Controller::NAME, 'type' => PermissionType::READ, - 'state' => PermissionCategory::VEHICLE, + 'state' => PermissionCategory::DRIVER, ], ], [ 'dest' => '\Modules\FleetManagement\Controller\ApiDriverAttributeController:apiDriverAttributeUpdate', 'verb' => RouteVerb::SET, + 'permission' => [ + 'module' => Controller::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::DRIVER, + ], + ], + ], + + '^.*/fleet/vehicle/note.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleAttributeController:apiNoteCreate', + 'verb' => RouteVerb::PUT, + 'permission' => [ + 'module' => Controller::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleAttributeController:apiNoteEdit', + 'verb' => RouteVerb::SET, 'permission' => [ 'module' => Controller::NAME, 'type' => PermissionType::READ, @@ -71,4 +92,25 @@ return [ ], ], ], + + '^.*/fleet/driver/note.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiDriverAttributeController:apiNoteCreate', + 'verb' => RouteVerb::PUT, + 'permission' => [ + 'module' => Controller::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::DRIVER, + ], + ], + [ + 'dest' => '\Modules\FleetManagement\Controller\ApiDriverAttributeController:apiNoteEdit', + 'verb' => RouteVerb::SET, + 'permission' => [ + 'module' => Controller::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::DRIVER, + ], + ], + ], ]; diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php index a955901..b8ffd60 100644 --- a/Controller/ApiDriverController.php +++ b/Controller/ApiDriverController.php @@ -137,7 +137,7 @@ final class ApiDriverController extends Controller $driver->id, $media->id, DriverMapper::class, - 'media', + 'files', '', $request->getOrigin() ); @@ -179,7 +179,7 @@ final class ApiDriverController extends Controller $driver->id, $media->id, DriverMapper::class, - 'media', + 'files', '', $request->getOrigin() ); @@ -408,7 +408,7 @@ final class ApiDriverController extends Controller /** @var BaseStringL11nType $driver */ $driver = $this->createDriverInspectionTypeFromRequest($request); - $this->createModel($request->header->account, $driver, DriverInspectionTypeMapper::class, 'inspection_type', $request->getOrigin()); + $this->createModel($request->header->account, $driver, DriverInspectionTypeMapper::class, 'driver_inspection_type', $request->getOrigin()); $this->fillJsonResponse( $request, @@ -475,14 +475,14 @@ final class ApiDriverController extends Controller public function apiDriverInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateDriverInspectionTypeL11nCreate($request))) { - $response->data['inspection_type_l11n_create'] = new FormValidation($val); + $response->data['driver_inspection_type_l11n_create'] = new FormValidation($val); $response->header->status = RequestStatusCode::R_400; return; } $typeL11n = $this->createDriverInspectionTypeL11nFromRequest($request); - $this->createModel($request->header->account, $typeL11n, DriverInspectionTypeL11nMapper::class, 'inspection_type_l11n', $request->getOrigin()); + $this->createModel($request->header->account, $typeL11n, DriverInspectionTypeL11nMapper::class, 'driver_inspection_type_l11n', $request->getOrigin()); $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); } @@ -529,7 +529,7 @@ final class ApiDriverController extends Controller } /** - * Api method to create item files + * Api method to create notes * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -550,7 +550,7 @@ final class ApiDriverController extends Controller return; } - $request->setData('virtualpath', '/Modules/FleetManagement/Items/' . $request->getData('id'), true); + $request->setData('virtualpath', '/Modules/FleetManagement/Driver/' . $request->getData('id'), true); $this->app->moduleManager->get('Editor', 'Api')->apiEditorCreate($request, $response, $data); if ($response->header->status !== RequestStatusCode::R_200) { @@ -585,4 +585,31 @@ final class ApiDriverController extends Controller return []; } + + /** + * Api method to update note + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteEdit(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + $this->app->moduleManager->get('Editor', 'Api')->apiEditorUpdate($request, $response, $data); + + if ($response->header->status !== RequestStatusCode::R_200) { + return; + } + + $responseData = $response->get($request->uri->__toString()); + if (!\is_array($responseData)) { + return; + } + } } diff --git a/Controller/ApiVehicleController.php b/Controller/ApiVehicleController.php index 59c45d3..b7dc084 100755 --- a/Controller/ApiVehicleController.php +++ b/Controller/ApiVehicleController.php @@ -434,7 +434,7 @@ final class ApiVehicleController extends Controller $vehicle->id, $media->id, VehicleMapper::class, - 'media', + 'files', '', $request->getOrigin() ); @@ -476,7 +476,7 @@ final class ApiVehicleController extends Controller $vehicle->id, $media->id, VehicleMapper::class, - 'media', + 'files', '', $request->getOrigin() ); @@ -827,7 +827,7 @@ final class ApiVehicleController extends Controller } /** - * Api method to create item files + * Api method to create notes * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -848,7 +848,7 @@ final class ApiVehicleController extends Controller return; } - $request->setData('virtualpath', '/Modules/FleetManagement/Items/' . $request->getData('id'), true); + $request->setData('virtualpath', '/Modules/FleetManagement/Vehicle/' . $request->getData('id'), true); $this->app->moduleManager->get('Editor', 'Api')->apiEditorCreate($request, $response, $data); if ($response->header->status !== RequestStatusCode::R_200) { @@ -883,4 +883,31 @@ final class ApiVehicleController extends Controller return []; } + + /** + * Api method to update note + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteEdit(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + $this->app->moduleManager->get('Editor', 'Api')->apiEditorUpdate($request, $response, $data); + + if ($response->header->status !== RequestStatusCode::R_200) { + return; + } + + $responseData = $response->get($request->uri->__toString()); + if (!\is_array($responseData)) { + return; + } + } } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 809ba4f..eb28661 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -100,6 +100,35 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementDriverList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/driver-list'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + $list = DriverMapper::getAll() + ->with('account') + ->sort('id', 'DESC') + ->execute(); + + $view->data['drivers'] = $list; + + return $view; + } + /** * Routing end-point for application behaviour. * @@ -254,4 +283,73 @@ final class BackendController extends Controller return $view; } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementDriverProfile(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/driver-profile'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + // @todo: This langauge filtering doesn't work. But it was working with the old mappers. Maybe there is a bug in the where() definition. Need to inspect the actual query. + $driver = DriverMapper::get() + ->with('attributes') + ->with('attributes/type') + ->with('attributes/value') + ->with('attributes/type/l11n') + ->with('files') + ->with('files/types') + ->where('id', (int) $request->getData('id')) + ->where('attributes/type/l11n/language', $response->header->l11n->language) + ->execute(); + + $view->data['driver'] = $driver; + + $query = new Builder($this->app->dbPool->get()); + $results = $query->selectAs(DriverMapper::HAS_MANY['files']['external'], 'file') + ->from(DriverMapper::TABLE) + ->leftJoin(DriverMapper::HAS_MANY['files']['table']) + ->on(DriverMapper::HAS_MANY['files']['table'] . '.' . DriverMapper::HAS_MANY['files']['self'], '=', DriverMapper::TABLE . '.' . DriverMapper::PRIMARYFIELD) + ->leftJoin(MediaMapper::TABLE) + ->on(DriverMapper::HAS_MANY['files']['table'] . '.' . DriverMapper::HAS_MANY['files']['external'], '=', MediaMapper::TABLE . '.' . MediaMapper::PRIMARYFIELD) + ->leftJoin(MediaMapper::HAS_MANY['types']['table']) + ->on(MediaMapper::TABLE . '.' . MediaMapper::PRIMARYFIELD, '=', MediaMapper::HAS_MANY['types']['table'] . '.' . MediaMapper::HAS_MANY['types']['self']) + ->leftJoin(MediaTypeMapper::TABLE) + ->on(MediaMapper::HAS_MANY['types']['table'] . '.' . MediaMapper::HAS_MANY['types']['external'], '=', MediaTypeMapper::TABLE . '.' . MediaTypeMapper::PRIMARYFIELD) + ->where(DriverMapper::HAS_MANY['files']['self'], '=', $driver->id) + ->where(MediaTypeMapper::TABLE . '.' . MediaTypeMapper::getColumnByMember('name'), '=', 'driver_profile_image'); + + $driverImage = MediaMapper::get() + ->with('types') + ->where('id', $results) + ->limit(1) + ->execute(); + + $view->data['driverImage'] = $driverImage; + + /** @var \Model\Setting $settings */ + $settings = $this->app->appSettings->get(null, [ + SettingsEnum::DEFAULT_LOCALIZATION, + ]); + + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); + + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['driver-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); + + return $view; + } } diff --git a/Models/Driver/DriverAttributeMapper.php b/Models/Driver/DriverAttributeMapper.php index d60bc02..3b44abc 100644 --- a/Models/Driver/DriverAttributeMapper.php +++ b/Models/Driver/DriverAttributeMapper.php @@ -38,7 +38,7 @@ final class DriverAttributeMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_driver_attr_id' => ['name' => 'fleetmgmt_driver_attr_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_driver_attr_item' => ['name' => 'fleetmgmt_driver_attr_item', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_driver_attr_driver' => ['name' => 'fleetmgmt_driver_attr_driver', 'type' => 'int', 'internal' => 'ref'], 'fleetmgmt_driver_attr_type' => ['name' => 'fleetmgmt_driver_attr_type', 'type' => 'int', 'internal' => 'type'], 'fleetmgmt_driver_attr_value' => ['name' => 'fleetmgmt_driver_attr_value', 'type' => 'int', 'internal' => 'value'], ]; diff --git a/Models/Driver/DriverMapper.php b/Models/Driver/DriverMapper.php index bc3ff1f..4a389e3 100644 --- a/Models/Driver/DriverMapper.php +++ b/Models/Driver/DriverMapper.php @@ -60,7 +60,7 @@ final class DriverMapper extends DataMapperFactory 'attributes' => [ 'mapper' => DriverAttributeMapper::class, 'table' => 'fleetmgmt_driver_attr', - 'self' => 'fleetmgmt_driver_attr_item', + 'self' => 'fleetmgmt_driver_attr_driver', 'external' => null, ], 'notes' => [ diff --git a/Models/PermissionCategory.php b/Models/PermissionCategory.php index f13ab8f..bc7b523 100755 --- a/Models/PermissionCategory.php +++ b/Models/PermissionCategory.php @@ -32,9 +32,17 @@ abstract class PermissionCategory extends Enum public const VEHICLE_TYPE = 3; - public const INSPECTION_TYPE = 4; + public const VEHICLE_INSPECTION_TYPE = 4; - public const INSPECTION = 5; + public const VEHICLE_INSPECTION = 5; - public const ATTRIBUTE_TYPE = 6; + public const VEHICLE_ATTRIBUTE_TYPE = 6; + + public const DRIVER = 7; + + public const DRIVER_INSPECTION_TYPE = 8; + + public const DRIVER_INSPECTION = 9; + + public const DRIVER_ATTRIBUTE_TYPE = 10; } diff --git a/Models/VehicleAttributeMapper.php b/Models/VehicleAttributeMapper.php index fe17883..e4f889c 100644 --- a/Models/VehicleAttributeMapper.php +++ b/Models/VehicleAttributeMapper.php @@ -38,7 +38,7 @@ final class VehicleAttributeMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_vehicle_attr_id' => ['name' => 'fleetmgmt_vehicle_attr_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_vehicle_attr_item' => ['name' => 'fleetmgmt_vehicle_attr_item', 'type' => 'int', 'internal' => 'ref'], + 'fleetmgmt_vehicle_attr_vehicle' => ['name' => 'fleetmgmt_vehicle_attr_vehicle', 'type' => 'int', 'internal' => 'ref'], 'fleetmgmt_vehicle_attr_type' => ['name' => 'fleetmgmt_vehicle_attr_type', 'type' => 'int', 'internal' => 'type'], 'fleetmgmt_vehicle_attr_value' => ['name' => 'fleetmgmt_vehicle_attr_value', 'type' => 'int', 'internal' => 'value'], ]; diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index e7ff236..b05f8d6 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -15,5 +15,10 @@ declare(strict_types=1); return ['Navigation' => [ 'FleetManagement' => 'Fleet Management', 'Vehicles' => 'Vehicles', - 'Drivers' => 'Drivers', + 'Drivers' => 'Drivers', + 'Inspections' => 'Inspections', + 'VehicleInspectionTypes' => 'Vehicle Inspection Types', + 'DriverInspectionTypes' => 'Driver Inspection Types', + 'VehicleAttributes' => 'Vehicle Attributes', + 'DriverAttributes' => 'Driver Attributes', ]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 054fdc4..56b6929 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -32,6 +32,10 @@ return ['FleetManagement' => [ 'Milage' => 'Milage', 'Driver' => 'Driver', 'Vin' => 'Vin', + 'History' => 'History', + 'Upcoming' => 'Upcoming', + 'Responsible' => 'Responsible', + 'Date' => 'Date', 'PurchasePrice' => 'Purchase Price', 'LeasingFee' => 'Leasing Fee', ':status1' => 'Active', diff --git a/Theme/Backend/driver-list.tpl.php b/Theme/Backend/driver-list.tpl.php new file mode 100644 index 0000000..d099d55 --- /dev/null +++ b/Theme/Backend/driver-list.tpl.php @@ -0,0 +1,100 @@ +data['drivers'] ?? []; + +echo $this->data['nav']->render(); ?> +
+
+
+
getHtml('Vehicles'); ?>
+
+ + + + + $value) : + ++$count; + $url = UriFactory::build('{/base}/fleet/driver/profile?{?}&id=' . $value->id); + ?> + +
+ getHtml('ID', '0', '0'); ?> + + + + getHtml('Status'); ?> + + + + getHtml('Name'); ?> + + + + getHtml('Type'); ?> + + + +
+ printHtml((string) $value->id); ?> + getHtml(':status' . $value->status); ?> + printHtml($value->name); ?> + printHtml($value->type->getL11n()); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
+
diff --git a/Theme/Backend/driver-profile.tpl.php b/Theme/Backend/driver-profile.tpl.php new file mode 100644 index 0000000..caa5dac --- /dev/null +++ b/Theme/Backend/driver-profile.tpl.php @@ -0,0 +1,318 @@ +data['driver'] ?? new NullDriver(); +$files = $driver->files; +$driverImage = $this->data['driverImage'] ?? new NullMedia(); +$attributeView = $this->data['attributeView']; + +/** + * @var \phpOMS\Views\View $this + */ +echo $this->data['nav']->render(); +?> +
+
+ +
+
+ request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>> +
+
+
+
+
getHtml('Profile'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ id === 0) : ?> + + + + +
+
+
+ +
+
+
+ +
+
+
+
+
+ + request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> +
+
+ render( + $driver->attributes, + $this->data['attributeTypes'] ?? [], + [], + '{/api}fleet/driver/attribute' + ); + ?> +
+
+ + request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+ data['media-upload']->render('driver-file', 'files', '', $driver->files); ?> +
+ + request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>> +
+ data['driver-notes']->render('driver-notes', '', $driver->notes); ?> +
+ + request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> +
+ +
+
+
+
getHtml('Upcoming'); ?>
+ + + + + +
getHtml('Date'); ?> + getHtml('Type'); ?> + getHtml('Responsible'); ?> +
+ + +
+
+
+ +
+
+
getHtml('History'); ?>
+ + + + + +
getHtml('Date'); ?> + getHtml('Type'); ?> + getHtml('Responsible'); ?> +
+ + +
+
+
+
+
+ + request->uri->fragment === 'c-tab-7' ? ' checked' : ''; ?>> +
+
+
+
+
+
getHtml('Milage'); ?>
+
+
+ + +
+ +
+ +
+
+ + + + +
+ 0) : ?> + + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +

+                                
+
+
+ + + +
+
+
+
+ +
+
+
getHtml('Milage'); ?>
+
+ + + + + + $value) : ++$c; ?> + + +
+ getHtml('ID', '0', '0'); ?> + getHtml('Driver'); ?> + getHtml('Milage'); ?> + getHtml('Start'); ?> + getHtml('End'); ?> +
+ + type->isRequired) : ?> + + + + + + + + id; ?> + printHtml($value->type->getL11n()); ?> + value->getValue() instanceof \DateTime ? $value->value->getValue()->format('Y-m-d') : $this->printHtml((string) $value->value->getValue()); ?> + printHtml($value->value->unit); ?> + printHtml($value->value->unit); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
+
+
+ + request->uri->fragment === 'c-tab-8' ? ' checked' : ''; ?>> +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 5195d70..bf5f5f9 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -24,10 +24,10 @@ $vehicleStatus = VehicleStatus::getConstants(); /** * @var \Modules\FleetManagement\Models\Vehicle $vehicle */ -$vehicle = $this->data['vehicle'] ?? new NullVehicle(); -$files = $vehicle->files; -$vehicleImage = $this->data['vehicleImage'] ?? new NullMedia(); -$vehicleTypes = $this->data['types'] ?? []; +$vehicle = $this->data['vehicle'] ?? new NullVehicle(); +$files = $vehicle->files; +$vehicleImage = $this->data['vehicleImage'] ?? new NullMedia(); +$vehicleTypes = $this->data['types'] ?? []; $attributeView = $this->data['attributeView']; /** @@ -144,7 +144,7 @@ echo $this->data['nav']->render();
render( - $vehicle->getAttributes(), + $vehicle->attributes, $this->data['attributeTypes'] ?? [], $this->data['units'] ?? [], '{/api}fleet/vehicle/attribute' @@ -212,10 +212,10 @@ echo $this->data['nav']->render();
-
+
getHtml('Milage'); ?>
From 9178a6db004dca580b5088ec2a859ff5809bc121 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 17 Jun 2023 03:13:25 +0200 Subject: [PATCH 33/89] Fix file header --- Admin/Install/Media.php | 2 +- Admin/Install/Navigation.php | 2 +- Admin/Installer.php | 2 +- Admin/Routes/Web/Api.php | 2 +- Admin/Routes/Web/Backend.php | 2 +- Admin/Status.php | 2 +- Admin/Uninstaller.php | 2 +- Admin/Updater.php | 2 +- Controller/ApiDriverAttributeController.php | 2 +- Controller/ApiDriverController.php | 2 +- Controller/ApiVehicleAttributeController.php | 2 +- Controller/ApiVehicleController.php | 2 +- Controller/BackendController.php | 2 +- Controller/Controller.php | 2 +- Models/Cost.php | 2 +- Models/CostType.php | 2 +- Models/Driver/Driver.php | 2 +- Models/Driver/DriverAttributeMapper.php | 2 +- Models/Driver/DriverAttributeTypeL11nMapper.php | 2 +- Models/Driver/DriverAttributeTypeMapper.php | 2 +- Models/Driver/DriverAttributeValueL11nMapper.php | 2 +- Models/Driver/DriverAttributeValueMapper.php | 2 +- Models/Driver/DriverInspection.php | 2 +- Models/Driver/DriverInspectionMapper.php | 2 +- Models/Driver/DriverInspectionStatus.php | 2 +- Models/Driver/DriverInspectionTypeL11nMapper.php | 2 +- Models/Driver/DriverInspectionTypeMapper.php | 2 +- Models/Driver/DriverMapper.php | 2 +- Models/Driver/DriverStatus.php | 2 +- Models/Driver/NullDriver.php | 2 +- Models/Driver/NullDriverInspection.php | 2 +- Models/FuelTypeL11nMapper.php | 2 +- Models/FuelTypeMapper.php | 2 +- Models/Inspection.php | 2 +- Models/InspectionMapper.php | 2 +- Models/InspectionStatus.php | 2 +- Models/InspectionTypeL11nMapper.php | 2 +- Models/InspectionTypeMapper.php | 2 +- Models/NullInspection.php | 2 +- Models/NullVehicle.php | 2 +- Models/PermissionCategory.php | 2 +- Models/Vehicle.php | 2 +- Models/VehicleAttributeMapper.php | 2 +- Models/VehicleAttributeTypeL11nMapper.php | 2 +- Models/VehicleAttributeTypeMapper.php | 2 +- Models/VehicleAttributeValueL11nMapper.php | 2 +- Models/VehicleAttributeValueMapper.php | 2 +- Models/VehicleMapper.php | 2 +- Models/VehicleStatus.php | 2 +- Models/VehicleTypeL11nMapper.php | 2 +- Models/VehicleTypeMapper.php | 2 +- Theme/Backend/Lang/Navigation.ar.lang.php | 2 +- Theme/Backend/Lang/Navigation.cs.lang.php | 2 +- Theme/Backend/Lang/Navigation.da.lang.php | 2 +- Theme/Backend/Lang/Navigation.de.lang.php | 2 +- Theme/Backend/Lang/Navigation.el.lang.php | 2 +- Theme/Backend/Lang/Navigation.en.lang.php | 2 +- Theme/Backend/Lang/Navigation.es.lang.php | 2 +- Theme/Backend/Lang/Navigation.fi.lang.php | 2 +- Theme/Backend/Lang/Navigation.fr.lang.php | 2 +- Theme/Backend/Lang/Navigation.hu.lang.php | 2 +- Theme/Backend/Lang/Navigation.it.lang.php | 2 +- Theme/Backend/Lang/Navigation.ja.lang.php | 2 +- Theme/Backend/Lang/Navigation.ko.lang.php | 2 +- Theme/Backend/Lang/Navigation.no.lang.php | 2 +- Theme/Backend/Lang/Navigation.pl.lang.php | 2 +- Theme/Backend/Lang/Navigation.pt.lang.php | 2 +- Theme/Backend/Lang/Navigation.ru.lang.php | 2 +- Theme/Backend/Lang/Navigation.sv.lang.php | 2 +- Theme/Backend/Lang/Navigation.th.lang.php | 2 +- Theme/Backend/Lang/Navigation.tr.lang.php | 2 +- Theme/Backend/Lang/Navigation.uk.lang.php | 2 +- Theme/Backend/Lang/Navigation.zh.lang.php | 2 +- Theme/Backend/Lang/ar.lang.php | 2 +- Theme/Backend/Lang/cs.lang.php | 2 +- Theme/Backend/Lang/da.lang.php | 2 +- Theme/Backend/Lang/de.lang.php | 2 +- Theme/Backend/Lang/el.lang.php | 2 +- Theme/Backend/Lang/en.lang.php | 2 +- Theme/Backend/Lang/es.lang.php | 2 +- Theme/Backend/Lang/fi.lang.php | 2 +- Theme/Backend/Lang/fr.lang.php | 2 +- Theme/Backend/Lang/hu.lang.php | 2 +- Theme/Backend/Lang/it.lang.php | 2 +- Theme/Backend/Lang/ja.lang.php | 2 +- Theme/Backend/Lang/ko.lang.php | 2 +- Theme/Backend/Lang/no.lang.php | 2 +- Theme/Backend/Lang/pl.lang.php | 2 +- Theme/Backend/Lang/pt.lang.php | 2 +- Theme/Backend/Lang/ru.lang.php | 2 +- Theme/Backend/Lang/sv.lang.php | 2 +- Theme/Backend/Lang/th.lang.php | 2 +- Theme/Backend/Lang/tr.lang.php | 2 +- Theme/Backend/Lang/uk.lang.php | 2 +- Theme/Backend/Lang/zh.lang.php | 2 +- Theme/Backend/attribute-type-list.tpl.php | 2 +- Theme/Backend/attribute-type.tpl.php | 2 +- Theme/Backend/driver-list.tpl.php | 2 +- Theme/Backend/driver-profile.tpl.php | 2 +- Theme/Backend/vehicle-list.tpl.php | 2 +- Theme/Backend/vehicle-profile.tpl.php | 2 +- tests/Admin/AdminTest.php | 2 +- tests/Autoloader.php | 2 +- tests/Controller/ApiControllerTest.php | 2 +- tests/Models/Vehicle.php | 2 +- 105 files changed, 105 insertions(+), 105 deletions(-) diff --git a/Admin/Install/Media.php b/Admin/Install/Media.php index 006b8a3..5cb9e50 100755 --- a/Admin/Install/Media.php +++ b/Admin/Install/Media.php @@ -1,6 +1,6 @@ Date: Tue, 20 Jun 2023 22:10:23 +0000 Subject: [PATCH 34/89] update --- Models/VehicleMapper.php | 2 +- Theme/Backend/vehicle-profile.tpl.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php index 785e5bb..bf821ba 100644 --- a/Models/VehicleMapper.php +++ b/Models/VehicleMapper.php @@ -65,7 +65,7 @@ final class VehicleMapper extends DataMapperFactory 'attributes' => [ 'mapper' => VehicleAttributeMapper::class, 'table' => 'fleetmgmt_vehicle_attr', - 'self' => 'fleetmgmt_vehicle_attr_item', + 'self' => 'fleetmgmt_vehicle_attr_vehicle', 'external' => null, ], 'notes' => [ diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 10fa725..fe4bf8a 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -128,7 +128,7 @@ echo $this->data['nav']->render();
-
+
- +
From d7d1dce38046efc8b33c798014b9c2d734a05529 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 9 Jul 2023 02:32:01 +0000 Subject: [PATCH 36/89] backup --- tests/Bootstrap.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index b5d36a8..4d624b6 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -302,7 +302,7 @@ if (\defined('RESET') && RESET === '1') { $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['masters']['admin']['database']); $db->exec('CREATE DATABASE IF NOT EXISTS ' . $CONFIG['db']['core']['masters']['admin']['database']); $db = null; - } catch (\Throwable $t) { + } catch (\Throwable $_) { echo "\nCouldn't connect to MYSQL DB\n"; } } @@ -317,7 +317,7 @@ if (\defined('RESET') && RESET === '1') { $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['postgresql']['admin']['database']); $db->exec('CREATE DATABASE ' . $CONFIG['db']['core']['postgresql']['admin']['database']); $db = null; - } catch (\Throwable $t) { + } catch (\Throwable $_) { echo "\nCouldn't connect to POSTGRESQL DB\n"; } } @@ -332,7 +332,7 @@ if (\defined('RESET') && RESET === '1') { $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['mssql']['admin']['database']); $db->exec('CREATE DATABASE ' . $CONFIG['db']['core']['mssql']['admin']['database']); $db = null; - } catch (\Throwable $t) { + } catch (\Throwable $_) { echo "\nCouldn't connect to MSSQL DB\n"; } } From c655c739b198345187b889c71b81d3d53e1b9b04 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 26 Jul 2023 09:18:05 +0000 Subject: [PATCH 37/89] fix default respone generation --- Admin/Installer.php | 2 +- Controller/ApiDriverAttributeController.php | 709 +++++++++--------- Controller/ApiDriverController.php | 48 +- Controller/ApiVehicleAttributeController.php | 709 +++++++++--------- Controller/ApiVehicleController.php | 82 +- .../DriverAttributeMapper.php | 6 +- .../DriverAttributeTypeL11nMapper.php | 6 +- .../DriverAttributeTypeMapper.php | 6 +- .../DriverAttributeValueL11nMapper.php | 6 +- .../DriverAttributeValueMapper.php | 6 +- .../VehicleAttributeMapper.php | 6 +- .../VehicleAttributeTypeL11nMapper.php | 6 +- .../VehicleAttributeTypeMapper.php | 6 +- .../VehicleAttributeValueL11nMapper.php | 6 +- .../VehicleAttributeValueMapper.php | 6 +- Models/VehicleMapper.php | 1 + 16 files changed, 771 insertions(+), 840 deletions(-) rename Models/{Driver => Attribute}/DriverAttributeMapper.php (93%) rename Models/{Driver => Attribute}/DriverAttributeTypeL11nMapper.php (92%) rename Models/{Driver => Attribute}/DriverAttributeTypeMapper.php (95%) rename Models/{Driver => Attribute}/DriverAttributeValueL11nMapper.php (92%) rename Models/{Driver => Attribute}/DriverAttributeValueMapper.php (95%) rename Models/{ => Attribute}/VehicleAttributeMapper.php (93%) rename Models/{ => Attribute}/VehicleAttributeTypeL11nMapper.php (91%) rename Models/{ => Attribute}/VehicleAttributeTypeMapper.php (94%) rename Models/{ => Attribute}/VehicleAttributeValueL11nMapper.php (91%) rename Models/{ => Attribute}/VehicleAttributeValueMapper.php (94%) diff --git a/Admin/Installer.php b/Admin/Installer.php index dd2e8a3..b5e7345 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -297,7 +297,7 @@ final class Installer extends InstallerAbstract /** @var array $inspectionTypes */ $inspectionTypes = []; - /** @var \Modules\FleetManagement\Controller\ApiVehicleController $module */ + /** @var \Modules\FleetManagement\Controller\ApiDriverController $module */ $module = $app->moduleManager->getModuleInstance('FleetManagement', 'ApiDriver'); /** @var array $type */ diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php index b002abd..e4d479e 100644 --- a/Controller/ApiDriverAttributeController.php +++ b/Controller/ApiDriverAttributeController.php @@ -17,20 +17,15 @@ namespace Modules\FleetManagement\Controller; use Modules\Attribute\Models\Attribute; use Modules\Attribute\Models\AttributeType; use Modules\Attribute\Models\AttributeValue; -use Modules\Attribute\Models\NullAttributeType; -use Modules\Attribute\Models\NullAttributeValue; -use Modules\FleetManagement\Models\Driver\DriverAttributeMapper; -use Modules\FleetManagement\Models\Driver\DriverAttributeTypeL11nMapper; -use Modules\FleetManagement\Models\Driver\DriverAttributeTypeMapper; -use Modules\FleetManagement\Models\Driver\DriverAttributeValueL11nMapper; -use Modules\FleetManagement\Models\Driver\DriverAttributeValueMapper; +use Modules\FleetManagement\Models\Attribute\DriverAttributeMapper; +use Modules\FleetManagement\Models\Attribute\DriverAttributeTypeL11nMapper; +use Modules\FleetManagement\Models\Attribute\DriverAttributeTypeMapper; +use Modules\FleetManagement\Models\Attribute\DriverAttributeValueL11nMapper; +use Modules\FleetManagement\Models\Attribute\DriverAttributeValueMapper; use phpOMS\Localization\BaseStringL11n; -use phpOMS\Localization\ISO639x1Enum; use phpOMS\Message\Http\RequestStatusCode; -use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; -use phpOMS\Model\Message\FormValidation; /** * FleetManagement class. @@ -42,8 +37,10 @@ use phpOMS\Model\Message\FormValidation; */ final class ApiDriverAttributeController extends Controller { + use \Modules\Attribute\Controller\ApiAttributeTraitController; + /** - * Api method to create driver attribute + * Api method to create item attribute * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -57,158 +54,16 @@ final class ApiDriverAttributeController extends Controller */ public function apiDriverAttributeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateDriverAttributeCreate($request))) { - $response->data['attribute_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } - $attribute = $this->createDriverAttributeFromRequest($request); + $attribute = $this->createAttributeFromRequest($request); $this->createModel($request->header->account, $attribute, DriverAttributeMapper::class, 'attribute', $request->getOrigin()); - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully created', $attribute); - } - - /** - * Method to create driver attribute from request. - * - * @param RequestAbstract $request Request - * - * @return Attribute - * - * @since 1.0.0 - */ - private function createDriverAttributeFromRequest(RequestAbstract $request) : Attribute - { - $attribute = new Attribute(); - $attribute->ref = (int) $request->getData('driver'); - $attribute->type = new NullAttributeType((int) $request->getData('type')); - - if ($request->hasData('value')) { - $attribute->value = new NullAttributeValue((int) $request->getData('value')); - } else { - $newRequest = clone $request; - $newRequest->setData('value', $request->getData('custom'), true); - - $value = $this->createAttributeValueFromRequest($newRequest); - - $attribute->value = $value; - } - - return $attribute; - } - - /** - * Validate driver attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateDriverAttributeCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['type'] = !$request->hasData('type')) - || ($val['value'] = (!$request->hasData('value') && !$request->hasData('custom'))) - || ($val['driver'] = !$request->hasData('driver')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to create driver attribute - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiDriverAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateDriverAttributeUpdate($request))) { - $response->data['attribute_update'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $old = DriverAttributeMapper::get() - ->with('type') - ->with('type/defaults') - ->with('value') - ->where('id', (int) $request->getData('id')) - ->execute(); - - $new = $this->updateDriverAttributeFromRequest($request, $old->deepClone()); - $this->updateModel($request->header->account, $old, $new, DriverAttributeMapper::class, 'attribute', $request->getOrigin()); - - if ($new->value->getValue() !== $old->value->getValue()) { - $this->updateModel($request->header->account, $old->value, $new->value, DriverAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); - } - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully updated', $new); - } - - /** - * Method to create driver attribute from request. - * - * @param RequestAbstract $request Request - * - * @return Attribute - * - * @since 1.0.0 - */ - private function updateDriverAttributeFromRequest(RequestAbstract $request, Attribute $attribute) : Attribute - { - if ($attribute->type->custom) { - if ($request->hasData('value')) { - // @question: we are overwriting the old value, could there be a use case where we want to create a new value and keep the old one? - $attribute->value->setValue($request->getData('value'), $attribute->type->datatype); - } - } else { - if ($request->hasData('value')) { - // @todo: fix by only accepting the value id to be used - // this is a workaround for now because the front end doesn't allow to dynamically show default values. - $value = $attribute->type->getDefaultByValue($request->getData('value')); - - if ($value->id !== 0) { - $attribute->value = $attribute->type->getDefaultByValue($request->getData('value')); - } - } - } - - return $attribute; - } - - /** - * Validate driver attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateDriverAttributeUpdate(RequestAbstract $request) : array - { - $val = []; - if (($val['id'] = !$request->hasData('id')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attribute); } /** @@ -226,58 +81,16 @@ final class ApiDriverAttributeController extends Controller */ public function apiDriverAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateDriverAttributeTypeL11nCreate($request))) { - $response->data['attr_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeTypeL11nCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } - $attrL11n = $this->createDriverAttributeTypeL11nFromRequest($request); + $attrL11n = $this->createAttributeTypeL11nFromRequest($request); $this->createModel($request->header->account, $attrL11n, DriverAttributeTypeL11nMapper::class, 'attr_type_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); - } - - /** - * Method to create driver attribute l11n from request. - * - * @param RequestAbstract $request Request - * - * @return BaseStringL11n - * - * @since 1.0.0 - */ - private function createDriverAttributeTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n - { - $attrL11n = new BaseStringL11n(); - $attrL11n->ref = $request->getDataInt('type') ?? 0; - $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $attrL11n->content = $request->getDataString('title') ?? ''; - - return $attrL11n; - } - - /** - * Validate driver attribute l11n create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateDriverAttributeTypeL11nCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['type'] = !$request->hasData('type')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attrL11n); } /** @@ -295,60 +108,16 @@ final class ApiDriverAttributeController extends Controller */ public function apiDriverAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateDriverAttributeTypeCreate($request))) { - $response->data['attr_type_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeTypeCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $attrType = $this->createAttributeTypeFromRequest($request); $this->createModel($request->header->account, $attrType, DriverAttributeTypeMapper::class, 'attr_type', $request->getOrigin()); - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute type', 'Attribute type successfully created', $attrType); - } - - /** - * Method to create driver attribute from request. - * - * @param RequestAbstract $request Request - * - * @return AttributeType - * - * @since 1.0.0 - */ - private function createAttributeTypeFromRequest(RequestAbstract $request) : AttributeType - { - $attrType = new AttributeType($request->getDataString('name') ?? ''); - $attrType->datatype = $request->getDataInt('datatype') ?? 0; - $attrType->custom = $request->getDataBool('custom') ?? false; - $attrType->isRequired = (bool) ($request->getData('is_required') ?? false); - $attrType->validationPattern = $request->getDataString('validation_pattern') ?? ''; - $attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); - $attrType->setFields($request->getDataInt('fields') ?? 0); - - return $attrType; - } - - /** - * Validate driver attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateDriverAttributeTypeCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['name'] = !$request->hasData('name')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attrType); } /** @@ -366,14 +135,19 @@ final class ApiDriverAttributeController extends Controller */ public function apiDriverAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateDriverAttributeValueCreate($request))) { - $response->data['attr_value_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeValueCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } - $attrValue = $this->createAttributeValueFromRequest($request); + /** @var \Modules\Attribute\Models\AttributeType $type */ + $type = DriverAttributeTypeMapper::get() + ->where('id', $request->getDataInt('type') ?? 0) + ->execute(); + + $attrValue = $this->createAttributeValueFromRequest($request, $type); $this->createModel($request->header->account, $attrValue, DriverAttributeValueMapper::class, 'attr_value', $request->getOrigin()); if ($attrValue->isDefault) { @@ -385,55 +159,7 @@ final class ApiDriverAttributeController extends Controller ); } - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute value', 'Attribute value successfully created', $attrValue); - } - - /** - * Method to create driver attribute value from request. - * - * @param RequestAbstract $request Request - * - * @return AttributeValue - * - * @since 1.0.0 - */ - private function createAttributeValueFromRequest(RequestAbstract $request) : AttributeValue - { - /** @var AttributeType $type */ - $type = DriverAttributeTypeMapper::get() - ->where('id', $request->getDataInt('type') ?? 0) - ->execute(); - - $attrValue = new AttributeValue(); - $attrValue->isDefault = $request->getDataBool('default') ?? false; - $attrValue->setValue($request->getData('value'), $type->datatype); - - if ($request->hasData('title')) { - $attrValue->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); - } - - return $attrValue; - } - - /** - * Validate driver attribute value create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateDriverAttributeValueCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['type'] = !$request->hasData('type')) - || ($val['value'] = !$request->hasData('value')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attrValue); } /** @@ -451,62 +177,20 @@ final class ApiDriverAttributeController extends Controller */ public function apiDriverAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateDriverAttributeValueL11nCreate($request))) { - $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeValueL11nCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $attrL11n = $this->createAttributeValueL11nFromRequest($request); $this->createModel($request->header->account, $attrL11n, DriverAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + $this->createStandardCreateResponse($request, $response, $attrL11n); } /** - * Method to create driver attribute l11n from request. - * - * @param RequestAbstract $request Request - * - * @return BaseStringL11n - * - * @since 1.0.0 - */ - private function createAttributeValueL11nFromRequest(RequestAbstract $request) : BaseStringL11n - { - $attrL11n = new BaseStringL11n(); - $attrL11n->ref = $request->getDataInt('value') ?? 0; - $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $attrL11n->content = $request->getDataString('title') ?? ''; - - return $attrL11n; - } - - /** - * Validate driver attribute l11n create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateDriverAttributeValueL11nCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['value'] = !$request->hasData('value')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to handle api driver attributes + * Api method to update DriverAttribute * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -518,17 +202,322 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttribute(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateDriverAttributeValueL11nCreate($request))) { - $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); return; } - $attrL11n = $this->createAttributeValueL11nFromRequest($request); - $this->createModel($request->header->account, $attrL11n, DriverAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + /** @var Attribute $old */ + $old = DriverAttributeMapper::get() + ->with('type') + ->with('type/defaults') + ->with('value') + ->where('id', (int) $request->getData('id')) + ->execute(); + + $new = $this->updateAttributeFromRequest($request, clone $old); + + if ($new->id === 0) { + // Set response header to invalid request because of invalid data + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $new); + + return; + } + + $this->updateModel($request->header->account, $old, $new, DriverAttributeMapper::class, 'driver_attribute', $request->getOrigin()); + + if ($new->value->getValue() !== $old->value->getValue()) { + $this->updateModel($request->header->account, $old->value, $new->value, DriverAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); + } + + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete DriverAttribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + $driverAttribute = DriverAttributeMapper::get() + ->with('type') + ->where('id', (int) $request->getData('id')) + ->execute(); + + if ($driverAttribute->type->isRequired) { + $this->createInvalidDeleteResponse($request, $response, []); + + return; + } + + $this->deleteModel($request->header->account, $driverAttribute, DriverAttributeMapper::class, 'driver_attribute', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $driverAttribute); + } + + /** + * Api method to update DriverAttributeTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeL11nUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var BaseStringL11n $old */ + $old = DriverAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateAttributeTypeL11nFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, DriverAttributeTypeL11nMapper::class, 'driver_attribute_type_l11n', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete DriverAttributeTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeL11nDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\DriverAttributeTypeL11n $driverAttributeTypeL11n */ + $driverAttributeTypeL11n = DriverAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $driverAttributeTypeL11n, DriverAttributeTypeL11nMapper::class, 'driver_attribute_type_l11n', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $driverAttributeTypeL11n); + } + + /** + * Api method to update DriverAttributeType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var AttributeType $old */ + $old = DriverAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateAttributeTypeFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, DriverAttributeTypeMapper::class, 'driver_attribute_type', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete DriverAttributeType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @todo: implement + * + * @since 1.0.0 + */ + public function apiDriverAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\DriverAttributeType $driverAttributeType */ + $driverAttributeType = DriverAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $driverAttributeType, DriverAttributeTypeMapper::class, 'driver_attribute_type', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $driverAttributeType); + } + + /** + * Api method to update DriverAttributeValue + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeValueUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var AttributeValue $old */ + $old = DriverAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + + /** @var \Modules\Attribute\Models\Attribute $type */ + $attr = DriverAttributeMapper::get() + ->with('type') + ->where('id', $request->getDataInt('attribute') ?? 0) + ->execute(); + + $new = $this->updateAttributeValueFromRequest($request, clone $old, $attr); + + $this->updateModel($request->header->account, $old, $new, DriverAttributeValueMapper::class, 'driver_attribute_value', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete DriverAttributeValue + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + return; + + // @todo: I don't think values can be deleted? Only Attributes + // However, It should be possible to remove UNUSED default values + // either here or other function? + if (!empty($val = $this->validateAttributeValueDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\DriverAttributeValue $driverAttributeValue */ + $driverAttributeValue = DriverAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $driverAttributeValue, DriverAttributeValueMapper::class, 'driver_attribute_value', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $driverAttributeValue); + } + + /** + * Api method to update DriverAttributeValueL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeValueL11nUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var BaseStringL11n $old */ + $old = DriverAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id')); + $new = $this->updateAttributeValueL11nFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, DriverAttributeValueL11nMapper::class, 'driver_attribute_value_l11n', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete DriverAttributeValueL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDriverAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeValueL11nDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\DriverAttributeValueL11n $driverAttributeValueL11n */ + $driverAttributeValueL11n = DriverAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $driverAttributeValueL11n, DriverAttributeValueL11nMapper::class, 'driver_attribute_value_l11n', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $driverAttributeValueL11n); } } diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php index 6eec99f..c7cf6dd 100644 --- a/Controller/ApiDriverController.php +++ b/Controller/ApiDriverController.php @@ -33,7 +33,6 @@ use phpOMS\Message\Http\RequestStatusCode; use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; -use phpOMS\Model\Message\FormValidation; /** * FleetManagement class. @@ -61,8 +60,8 @@ final class ApiDriverController extends Controller public function apiDriverCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateDriverCreate($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } @@ -77,14 +76,7 @@ final class ApiDriverController extends Controller $this->createDriverMedia($driver, $request); } - $this->fillJsonResponse( - $request, - $response, - NotificationLevel::OK, - '', - $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), - $driver - ); + $this->createStandardCreateResponse($request, $response, $driver); } /** @@ -254,8 +246,8 @@ final class ApiDriverController extends Controller public function apiMediaAddToDriver(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateMediaAddToDriver($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidAddResponse($request, $response, $val); return; } @@ -400,24 +392,16 @@ final class ApiDriverController extends Controller public function apiDriverInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateDriverInspectionTypeCreate($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } - /** @var BaseStringL11nType $driver */ - $driver = $this->createDriverInspectionTypeFromRequest($request); - $this->createModel($request->header->account, $driver, DriverInspectionTypeMapper::class, 'driver_inspection_type', $request->getOrigin()); - - $this->fillJsonResponse( - $request, - $response, - NotificationLevel::OK, - '', - $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), - $driver - ); + /** @var BaseStringL11nType $inspection */ + $inspection = $this->createDriverInspectionTypeFromRequest($request); + $this->createModel($request->header->account, $inspection, DriverInspectionTypeMapper::class, 'driver_inspection_type', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $inspection); } /** @@ -475,15 +459,15 @@ final class ApiDriverController extends Controller public function apiDriverInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateDriverInspectionTypeL11nCreate($request))) { - $response->data['driver_inspection_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $typeL11n = $this->createDriverInspectionTypeL11nFromRequest($request); $this->createModel($request->header->account, $typeL11n, DriverInspectionTypeL11nMapper::class, 'driver_inspection_type_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + $this->createStandardCreateResponse($request, $response, $typeL11n); } /** @@ -544,8 +528,8 @@ final class ApiDriverController extends Controller public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateNoteCreate($request))) { - $response->data['driver_note_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php index 739a828..c40475d 100644 --- a/Controller/ApiVehicleAttributeController.php +++ b/Controller/ApiVehicleAttributeController.php @@ -17,20 +17,15 @@ namespace Modules\FleetManagement\Controller; use Modules\Attribute\Models\Attribute; use Modules\Attribute\Models\AttributeType; use Modules\Attribute\Models\AttributeValue; -use Modules\Attribute\Models\NullAttributeType; -use Modules\Attribute\Models\NullAttributeValue; -use Modules\FleetManagement\Models\VehicleAttributeMapper; -use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; -use Modules\FleetManagement\Models\VehicleAttributeTypeMapper; -use Modules\FleetManagement\Models\VehicleAttributeValueL11nMapper; -use Modules\FleetManagement\Models\VehicleAttributeValueMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeTypeL11nMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeTypeMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeValueL11nMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeValueMapper; use phpOMS\Localization\BaseStringL11n; -use phpOMS\Localization\ISO639x1Enum; use phpOMS\Message\Http\RequestStatusCode; -use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; -use phpOMS\Model\Message\FormValidation; /** * FleetManagement class. @@ -42,8 +37,10 @@ use phpOMS\Model\Message\FormValidation; */ final class ApiVehicleAttributeController extends Controller { + use \Modules\Attribute\Controller\ApiAttributeTraitController; + /** - * Api method to create vehicle attribute + * Api method to create item attribute * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -57,158 +54,16 @@ final class ApiVehicleAttributeController extends Controller */ public function apiVehicleAttributeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateVehicleAttributeCreate($request))) { - $response->data['attribute_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } - $attribute = $this->createVehicleAttributeFromRequest($request); + $attribute = $this->createAttributeFromRequest($request); $this->createModel($request->header->account, $attribute, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully created', $attribute); - } - - /** - * Method to create vehicle attribute from request. - * - * @param RequestAbstract $request Request - * - * @return Attribute - * - * @since 1.0.0 - */ - private function createVehicleAttributeFromRequest(RequestAbstract $request) : Attribute - { - $attribute = new Attribute(); - $attribute->ref = (int) $request->getData('vehicle'); - $attribute->type = new NullAttributeType((int) $request->getData('type')); - - if ($request->hasData('value')) { - $attribute->value = new NullAttributeValue((int) $request->getData('value')); - } else { - $newRequest = clone $request; - $newRequest->setData('value', $request->getData('custom'), true); - - $value = $this->createAttributeValueFromRequest($newRequest); - - $attribute->value = $value; - } - - return $attribute; - } - - /** - * Validate vehicle attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['type'] = !$request->hasData('type')) - || ($val['value'] = (!$request->hasData('value') && !$request->hasData('custom'))) - || ($val['vehicle'] = !$request->hasData('vehicle')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to create vehicle attribute - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void - { - if (!empty($val = $this->validateVehicleAttributeUpdate($request))) { - $response->data['attribute_update'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; - - return; - } - - $old = VehicleAttributeMapper::get() - ->with('type') - ->with('type/defaults') - ->with('value') - ->where('id', (int) $request->getData('id')) - ->execute(); - - $new = $this->updateVehicleAttributeFromRequest($request, $old->deepClone()); - $this->updateModel($request->header->account, $old, $new, VehicleAttributeMapper::class, 'attribute', $request->getOrigin()); - - if ($new->value->getValue() !== $old->value->getValue()) { - $this->updateModel($request->header->account, $old->value, $new->value, VehicleAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); - } - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute', 'Attribute successfully updated', $new); - } - - /** - * Method to create vehicle attribute from request. - * - * @param RequestAbstract $request Request - * - * @return Attribute - * - * @since 1.0.0 - */ - private function updateVehicleAttributeFromRequest(RequestAbstract $request, Attribute $attribute) : Attribute - { - if ($attribute->type->custom) { - if ($request->hasData('value')) { - // @question: we are overwriting the old value, could there be a use case where we want to create a new value and keep the old one? - $attribute->value->setValue($request->getData('value'), $attribute->type->datatype); - } - } else { - if ($request->hasData('value')) { - // @todo: fix by only accepting the value id to be used - // this is a workaround for now because the front end doesn't allow to dynamically show default values. - $value = $attribute->type->getDefaultByValue($request->getData('value')); - - if ($value->id !== 0) { - $attribute->value = $attribute->type->getDefaultByValue($request->getData('value')); - } - } - } - - return $attribute; - } - - /** - * Validate vehicle attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeUpdate(RequestAbstract $request) : array - { - $val = []; - if (($val['id'] = !$request->hasData('id')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attribute); } /** @@ -226,58 +81,16 @@ final class ApiVehicleAttributeController extends Controller */ public function apiVehicleAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateVehicleAttributeTypeL11nCreate($request))) { - $response->data['attr_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeTypeL11nCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } - $attrL11n = $this->createVehicleAttributeTypeL11nFromRequest($request); + $attrL11n = $this->createAttributeTypeL11nFromRequest($request); $this->createModel($request->header->account, $attrL11n, VehicleAttributeTypeL11nMapper::class, 'attr_type_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); - } - - /** - * Method to create vehicle attribute l11n from request. - * - * @param RequestAbstract $request Request - * - * @return BaseStringL11n - * - * @since 1.0.0 - */ - private function createVehicleAttributeTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n - { - $attrL11n = new BaseStringL11n(); - $attrL11n->ref = $request->getDataInt('type') ?? 0; - $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $attrL11n->content = $request->getDataString('title') ?? ''; - - return $attrL11n; - } - - /** - * Validate vehicle attribute l11n create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeTypeL11nCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['type'] = !$request->hasData('type')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attrL11n); } /** @@ -295,60 +108,16 @@ final class ApiVehicleAttributeController extends Controller */ public function apiVehicleAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateVehicleAttributeTypeCreate($request))) { - $response->data['attr_type_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeTypeCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $attrType = $this->createAttributeTypeFromRequest($request); $this->createModel($request->header->account, $attrType, VehicleAttributeTypeMapper::class, 'attr_type', $request->getOrigin()); - - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute type', 'Attribute type successfully created', $attrType); - } - - /** - * Method to create vehicle attribute from request. - * - * @param RequestAbstract $request Request - * - * @return AttributeType - * - * @since 1.0.0 - */ - private function createAttributeTypeFromRequest(RequestAbstract $request) : AttributeType - { - $attrType = new AttributeType($request->getDataString('name') ?? ''); - $attrType->datatype = $request->getDataInt('datatype') ?? 0; - $attrType->custom = $request->getDataBool('custom') ?? false; - $attrType->isRequired = (bool) ($request->getData('is_required') ?? false); - $attrType->validationPattern = $request->getDataString('validation_pattern') ?? ''; - $attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); - $attrType->setFields($request->getDataInt('fields') ?? 0); - - return $attrType; - } - - /** - * Validate vehicle attribute create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeTypeCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['name'] = !$request->hasData('name')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attrType); } /** @@ -366,14 +135,19 @@ final class ApiVehicleAttributeController extends Controller */ public function apiVehicleAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateVehicleAttributeValueCreate($request))) { - $response->data['attr_value_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeValueCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } - $attrValue = $this->createAttributeValueFromRequest($request); + /** @var \Modules\Attribute\Models\AttributeType $type */ + $type = VehicleAttributeTypeMapper::get() + ->where('id', $request->getDataInt('type') ?? 0) + ->execute(); + + $attrValue = $this->createAttributeValueFromRequest($request, $type); $this->createModel($request->header->account, $attrValue, VehicleAttributeValueMapper::class, 'attr_value', $request->getOrigin()); if ($attrValue->isDefault) { @@ -385,55 +159,7 @@ final class ApiVehicleAttributeController extends Controller ); } - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Attribute value', 'Attribute value successfully created', $attrValue); - } - - /** - * Method to create vehicle attribute value from request. - * - * @param RequestAbstract $request Request - * - * @return AttributeValue - * - * @since 1.0.0 - */ - private function createAttributeValueFromRequest(RequestAbstract $request) : AttributeValue - { - /** @var AttributeType $type */ - $type = VehicleAttributeTypeMapper::get() - ->where('id', $request->getDataInt('type') ?? 0) - ->execute(); - - $attrValue = new AttributeValue(); - $attrValue->isDefault = $request->getDataBool('default') ?? false; - $attrValue->setValue($request->getData('value'), $type->datatype); - - if ($request->hasData('title')) { - $attrValue->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); - } - - return $attrValue; - } - - /** - * Validate vehicle attribute value create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeValueCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['type'] = !$request->hasData('type')) - || ($val['value'] = !$request->hasData('value')) - ) { - return $val; - } - - return []; + $this->createStandardCreateResponse($request, $response, $attrValue); } /** @@ -451,62 +177,20 @@ final class ApiVehicleAttributeController extends Controller */ public function apiVehicleAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { - $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeValueL11nCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $attrL11n = $this->createAttributeValueL11nFromRequest($request); $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + $this->createStandardCreateResponse($request, $response, $attrL11n); } /** - * Method to create vehicle attribute l11n from request. - * - * @param RequestAbstract $request Request - * - * @return BaseStringL11n - * - * @since 1.0.0 - */ - private function createAttributeValueL11nFromRequest(RequestAbstract $request) : BaseStringL11n - { - $attrL11n = new BaseStringL11n(); - $attrL11n->ref = $request->getDataInt('value') ?? 0; - $attrL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $attrL11n->content = $request->getDataString('title') ?? ''; - - return $attrL11n; - } - - /** - * Validate vehicle attribute l11n create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateVehicleAttributeValueL11nCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['title'] = !$request->hasData('title')) - || ($val['value'] = !$request->hasData('value')) - ) { - return $val; - } - - return []; - } - - /** - * Api method to handle api vehicle attributes + * Api method to update VehicleAttribute * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -518,17 +202,322 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttribute(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - if (!empty($val = $this->validateVehicleAttributeValueL11nCreate($request))) { - $response->data['attr_value_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + if (!empty($val = $this->validateAttributeUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); return; } - $attrL11n = $this->createAttributeValueL11nFromRequest($request); - $this->createModel($request->header->account, $attrL11n, VehicleAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $attrL11n); + /** @var Attribute $old */ + $old = VehicleAttributeMapper::get() + ->with('type') + ->with('type/defaults') + ->with('value') + ->where('id', (int) $request->getData('id')) + ->execute(); + + $new = $this->updateAttributeFromRequest($request, clone $old); + + if ($new->id === 0) { + // Set response header to invalid request because of invalid data + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $new); + + return; + } + + $this->updateModel($request->header->account, $old, $new, VehicleAttributeMapper::class, 'vehicle_attribute', $request->getOrigin()); + + if ($new->value->getValue() !== $old->value->getValue()) { + $this->updateModel($request->header->account, $old->value, $new->value, VehicleAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); + } + + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete VehicleAttribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + $vehicleAttribute = VehicleAttributeMapper::get() + ->with('type') + ->where('id', (int) $request->getData('id')) + ->execute(); + + if ($vehicleAttribute->type->isRequired) { + $this->createInvalidDeleteResponse($request, $response, []); + + return; + } + + $this->deleteModel($request->header->account, $vehicleAttribute, VehicleAttributeMapper::class, 'vehicle_attribute', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $vehicleAttribute); + } + + /** + * Api method to update VehicleAttributeTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeL11nUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var BaseStringL11n $old */ + $old = VehicleAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateAttributeTypeL11nFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, VehicleAttributeTypeL11nMapper::class, 'vehicle_attribute_type_l11n', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete VehicleAttributeTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeL11nDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\VehicleAttributeTypeL11n $vehicleAttributeTypeL11n */ + $vehicleAttributeTypeL11n = VehicleAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $vehicleAttributeTypeL11n, VehicleAttributeTypeL11nMapper::class, 'vehicle_attribute_type_l11n', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $vehicleAttributeTypeL11n); + } + + /** + * Api method to update VehicleAttributeType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var AttributeType $old */ + $old = VehicleAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateAttributeTypeFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, VehicleAttributeTypeMapper::class, 'vehicle_attribute_type', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete VehicleAttributeType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @todo: implement + * + * @since 1.0.0 + */ + public function apiVehicleAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeTypeDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\VehicleAttributeType $vehicleAttributeType */ + $vehicleAttributeType = VehicleAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $vehicleAttributeType, VehicleAttributeTypeMapper::class, 'vehicle_attribute_type', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $vehicleAttributeType); + } + + /** + * Api method to update VehicleAttributeValue + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeValueUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var AttributeValue $old */ + $old = VehicleAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + + /** @var \Modules\Attribute\Models\Attribute $type */ + $attr = VehicleAttributeMapper::get() + ->with('type') + ->where('id', $request->getDataInt('attribute') ?? 0) + ->execute(); + + $new = $this->updateAttributeValueFromRequest($request, clone $old, $attr); + + $this->updateModel($request->header->account, $old, $new, VehicleAttributeValueMapper::class, 'vehicle_attribute_value', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete VehicleAttributeValue + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + return; + + // @todo: I don't think values can be deleted? Only Attributes + // However, It should be possible to remove UNUSED default values + // either here or other function? + if (!empty($val = $this->validateAttributeValueDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\VehicleAttributeValue $vehicleAttributeValue */ + $vehicleAttributeValue = VehicleAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $vehicleAttributeValue, VehicleAttributeValueMapper::class, 'vehicle_attribute_value', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $vehicleAttributeValue); + } + + /** + * Api method to update VehicleAttributeValueL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeValueL11nUpdate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidUpdateResponse($request, $response, $val); + + return; + } + + /** @var BaseStringL11n $old */ + $old = VehicleAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id')); + $new = $this->updateAttributeValueL11nFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, VehicleAttributeValueL11nMapper::class, 'vehicle_attribute_value_l11n', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Api method to delete VehicleAttributeValueL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateAttributeValueL11nDelete($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidDeleteResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\VehicleAttributeValueL11n $vehicleAttributeValueL11n */ + $vehicleAttributeValueL11n = VehicleAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $vehicleAttributeValueL11n, VehicleAttributeValueL11nMapper::class, 'vehicle_attribute_value_l11n', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $vehicleAttributeValueL11n); } } diff --git a/Controller/ApiVehicleController.php b/Controller/ApiVehicleController.php index c77a232..411dc17 100755 --- a/Controller/ApiVehicleController.php +++ b/Controller/ApiVehicleController.php @@ -38,7 +38,6 @@ use phpOMS\Message\Http\RequestStatusCode; use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; -use phpOMS\Model\Message\FormValidation; /** * FleetManagement class. @@ -66,8 +65,8 @@ final class ApiVehicleController extends Controller public function apiVehicleTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleTypeCreate($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } @@ -75,15 +74,7 @@ final class ApiVehicleController extends Controller /** @var BaseStringL11nType $vehicle */ $vehicle = $this->createVehicleTypeFromRequest($request); $this->createModel($request->header->account, $vehicle, VehicleTypeMapper::class, 'vehicle_type', $request->getOrigin()); - - $this->fillJsonResponse( - $request, - $response, - NotificationLevel::OK, - '', - $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), - $vehicle - ); + $this->createStandardCreateResponse($request, $response, $vehicle); } /** @@ -141,15 +132,15 @@ final class ApiVehicleController extends Controller public function apiVehicleTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleTypeL11nCreate($request))) { - $response->data['vehicle_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $typeL11n = $this->createVehicleTypeL11nFromRequest($request); $this->createModel($request->header->account, $typeL11n, VehicleTypeL11nMapper::class, 'vehicle_type_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + $this->createStandardCreateResponse($request, $response, $typeL11n); } /** @@ -210,8 +201,8 @@ final class ApiVehicleController extends Controller public function apiFuelTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateFuelTypeCreate($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } @@ -219,15 +210,7 @@ final class ApiVehicleController extends Controller /** @var BaseStringL11nType $vehicle */ $vehicle = $this->createFuelTypeFromRequest($request); $this->createModel($request->header->account, $vehicle, FuelTypeMapper::class, 'fuel_type', $request->getOrigin()); - - $this->fillJsonResponse( - $request, - $response, - NotificationLevel::OK, - '', - $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), - $vehicle - ); + $this->createStandardCreateResponse($request, $response, $vehicle); } /** @@ -285,15 +268,15 @@ final class ApiVehicleController extends Controller public function apiFuelTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateFuelTypeL11nCreate($request))) { - $response->data['fuel_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $typeL11n = $this->createFuelTypeL11nFromRequest($request); $this->createModel($request->header->account, $typeL11n, FuelTypeL11nMapper::class, 'fuel_type_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + $this->createStandardCreateResponse($request, $response, $typeL11n); } /** @@ -354,8 +337,8 @@ final class ApiVehicleController extends Controller public function apiVehicleCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateVehicleCreate($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } @@ -370,14 +353,7 @@ final class ApiVehicleController extends Controller $this->createVehicleMedia($vehicle, $request); } - $this->fillJsonResponse( - $request, - $response, - NotificationLevel::OK, - '', - $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), - $vehicle - ); + $this->createStandardCreateResponse($request, $response, $vehicle); } /** @@ -552,8 +528,8 @@ final class ApiVehicleController extends Controller public function apiMediaAddToVehicle(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateMediaAddToVehicle($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidAddResponse($request, $response, $val); return; } @@ -698,8 +674,8 @@ final class ApiVehicleController extends Controller public function apiInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateInspectionTypeCreate($request))) { - $response->data[$request->uri->__toString()] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } @@ -707,15 +683,7 @@ final class ApiVehicleController extends Controller /** @var BaseStringL11nType $inspection */ $inspection = $this->createInspectionTypeFromRequest($request); $this->createModel($request->header->account, $inspection, InspectionTypeMapper::class, 'inspection_type', $request->getOrigin()); - - $this->fillJsonResponse( - $request, - $response, - NotificationLevel::OK, - '', - $this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SucessfulCreate'), - $inspection - ); + $this->createStandardCreateResponse($request, $response, $inspection); } /** @@ -773,15 +741,15 @@ final class ApiVehicleController extends Controller public function apiInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateInspectionTypeL11nCreate($request))) { - $response->data['inspection_type_l11n_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } $typeL11n = $this->createInspectionTypeL11nFromRequest($request); $this->createModel($request->header->account, $typeL11n, InspectionTypeL11nMapper::class, 'inspection_type_l11n', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $typeL11n); + $this->createStandardCreateResponse($request, $response, $typeL11n); } /** @@ -842,8 +810,8 @@ final class ApiVehicleController extends Controller public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { if (!empty($val = $this->validateNoteCreate($request))) { - $response->data['vehicle_note_create'] = new FormValidation($val); - $response->header->status = RequestStatusCode::R_400; + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); return; } diff --git a/Models/Driver/DriverAttributeMapper.php b/Models/Attribute/DriverAttributeMapper.php similarity index 93% rename from Models/Driver/DriverAttributeMapper.php rename to Models/Attribute/DriverAttributeMapper.php index 6138f69..222fd09 100644 --- a/Models/Driver/DriverAttributeMapper.php +++ b/Models/Attribute/DriverAttributeMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models\Driver; +namespace Modules\FleetManagement\Models\Attribute; use Modules\Attribute\Models\Attribute; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -20,7 +20,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Fleet mapper class. * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/Driver/DriverAttributeTypeL11nMapper.php b/Models/Attribute/DriverAttributeTypeL11nMapper.php similarity index 92% rename from Models/Driver/DriverAttributeTypeL11nMapper.php rename to Models/Attribute/DriverAttributeTypeL11nMapper.php index 7439317..70b2653 100644 --- a/Models/Driver/DriverAttributeTypeL11nMapper.php +++ b/Models/Attribute/DriverAttributeTypeL11nMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models\Driver; +namespace Modules\FleetManagement\Models\Attribute; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use phpOMS\Localization\BaseStringL11n; @@ -20,7 +20,7 @@ use phpOMS\Localization\BaseStringL11n; /** * Driver mapper class. * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/Driver/DriverAttributeTypeMapper.php b/Models/Attribute/DriverAttributeTypeMapper.php similarity index 95% rename from Models/Driver/DriverAttributeTypeMapper.php rename to Models/Attribute/DriverAttributeTypeMapper.php index 544eaab..92fd7c5 100644 --- a/Models/Driver/DriverAttributeTypeMapper.php +++ b/Models/Attribute/DriverAttributeTypeMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models\Driver; +namespace Modules\FleetManagement\Models\Attribute; use Modules\Attribute\Models\AttributeType; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -20,7 +20,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Driver mapper class. * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/Driver/DriverAttributeValueL11nMapper.php b/Models/Attribute/DriverAttributeValueL11nMapper.php similarity index 92% rename from Models/Driver/DriverAttributeValueL11nMapper.php rename to Models/Attribute/DriverAttributeValueL11nMapper.php index cdb986d..a9ca0de 100644 --- a/Models/Driver/DriverAttributeValueL11nMapper.php +++ b/Models/Attribute/DriverAttributeValueL11nMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models\Driver; +namespace Modules\FleetManagement\Models\Attribute; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use phpOMS\Localization\BaseStringL11n; @@ -20,7 +20,7 @@ use phpOMS\Localization\BaseStringL11n; /** * Driver mapper class. * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/Driver/DriverAttributeValueMapper.php b/Models/Attribute/DriverAttributeValueMapper.php similarity index 95% rename from Models/Driver/DriverAttributeValueMapper.php rename to Models/Attribute/DriverAttributeValueMapper.php index 7b883b5..7f0b898 100644 --- a/Models/Driver/DriverAttributeValueMapper.php +++ b/Models/Attribute/DriverAttributeValueMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models\Driver; +namespace Modules\FleetManagement\Models\Attribute; use Modules\Attribute\Models\AttributeValue; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -20,7 +20,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Driver mapper class. * - * @package Modules\FleetManagement\Models\Driver + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/VehicleAttributeMapper.php b/Models/Attribute/VehicleAttributeMapper.php similarity index 93% rename from Models/VehicleAttributeMapper.php rename to Models/Attribute/VehicleAttributeMapper.php index 4cd22c9..c3c39f3 100644 --- a/Models/VehicleAttributeMapper.php +++ b/Models/Attribute/VehicleAttributeMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models; +namespace Modules\FleetManagement\Models\Attribute; use Modules\Attribute\Models\Attribute; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -20,7 +20,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Fleet mapper class. * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/VehicleAttributeTypeL11nMapper.php b/Models/Attribute/VehicleAttributeTypeL11nMapper.php similarity index 91% rename from Models/VehicleAttributeTypeL11nMapper.php rename to Models/Attribute/VehicleAttributeTypeL11nMapper.php index 3aaea51..9748327 100644 --- a/Models/VehicleAttributeTypeL11nMapper.php +++ b/Models/Attribute/VehicleAttributeTypeL11nMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models; +namespace Modules\FleetManagement\Models\Attribute; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use phpOMS\Localization\BaseStringL11n; @@ -20,7 +20,7 @@ use phpOMS\Localization\BaseStringL11n; /** * Vehicle mapper class. * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/VehicleAttributeTypeMapper.php b/Models/Attribute/VehicleAttributeTypeMapper.php similarity index 94% rename from Models/VehicleAttributeTypeMapper.php rename to Models/Attribute/VehicleAttributeTypeMapper.php index 314e148..63be3db 100644 --- a/Models/VehicleAttributeTypeMapper.php +++ b/Models/Attribute/VehicleAttributeTypeMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models; +namespace Modules\FleetManagement\Models\Attribute; use Modules\Attribute\Models\AttributeType; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -20,7 +20,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Vehicle mapper class. * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/VehicleAttributeValueL11nMapper.php b/Models/Attribute/VehicleAttributeValueL11nMapper.php similarity index 91% rename from Models/VehicleAttributeValueL11nMapper.php rename to Models/Attribute/VehicleAttributeValueL11nMapper.php index b96c4d4..dfee443 100644 --- a/Models/VehicleAttributeValueL11nMapper.php +++ b/Models/Attribute/VehicleAttributeValueL11nMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models; +namespace Modules\FleetManagement\Models\Attribute; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use phpOMS\Localization\BaseStringL11n; @@ -20,7 +20,7 @@ use phpOMS\Localization\BaseStringL11n; /** * Vehicle mapper class. * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/VehicleAttributeValueMapper.php b/Models/Attribute/VehicleAttributeValueMapper.php similarity index 94% rename from Models/VehicleAttributeValueMapper.php rename to Models/Attribute/VehicleAttributeValueMapper.php index 5e1cd12..2948e3f 100644 --- a/Models/VehicleAttributeValueMapper.php +++ b/Models/Attribute/VehicleAttributeValueMapper.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -12,7 +12,7 @@ */ declare(strict_types=1); -namespace Modules\FleetManagement\Models; +namespace Modules\FleetManagement\Models\Attribute; use Modules\Attribute\Models\AttributeValue; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -20,7 +20,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Vehicle mapper class. * - * @package Modules\FleetManagement\Models + * @package Modules\FleetManagement\Models\Attribute * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php index bf821ba..cb099e9 100644 --- a/Models/VehicleMapper.php +++ b/Models/VehicleMapper.php @@ -17,6 +17,7 @@ namespace Modules\FleetManagement\Models; use Modules\Media\Models\MediaMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use Modules\Editor\Models\EditorDocMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeMapper; /** * Mapper class. From 733386df2d4fb0ee840146e5f7a12ceaeaed2bbe Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 28 Aug 2023 22:06:34 +0000 Subject: [PATCH 38/89] update --- Admin/Install/Navigation.install.json | 17 +-- Admin/Install/db.json | 89 ++++++++++- Admin/Routes/Web/Backend.php | 15 +- Controller/ApiDriverController.php | 78 +++++++++- Controller/ApiVehicleController.php | 186 +++++++++++++++++++++-- Controller/BackendController.php | 43 +++++- Models/Driver/DriverInspection.php | 78 ---------- Models/Driver/DriverInspectionMapper.php | 8 +- Models/Driver/DriverInspectionStatus.php | 36 ----- Models/Driver/DriverMapper.php | 1 + Models/Inspection.php | 14 +- Models/InspectionMapper.php | 4 +- Models/Milage.php | 75 +++++++++ Models/MilageMapper.php | 91 +++++++++++ Theme/Backend/driver-list.tpl.php | 2 +- Theme/Backend/vehicle-profile.tpl.php | 6 +- tests/Autoloader.php | 4 +- 17 files changed, 585 insertions(+), 162 deletions(-) delete mode 100644 Models/Driver/DriverInspection.php delete mode 100644 Models/Driver/DriverInspectionStatus.php create mode 100644 Models/Milage.php create mode 100644 Models/MilageMapper.php diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index bb2027b..355e599 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -140,7 +140,7 @@ "type": 3, "subtype": 1, "name": "VehicleInspectionTypes", - "uri": "{/base}/fleet/vehicle/inspection/type/list?{?}", + "uri": "{/base}/fleet/inspection/type/list?{?}", "target": "self", "icon": null, "order": 5, @@ -148,21 +148,6 @@ "permission": { "permission": 4, "category": null, "element": null }, "parent": 1003504001, "children": [] - }, - { - "id": 1003504301, - "pid": "/fleet/inspection", - "type": 3, - "subtype": 1, - "name": "DriverInspectionTypes", - "uri": "{/base}/fleet/driver/inspection/type/list?{?}", - "target": "self", - "icon": null, - "order": 10, - "from": "FleetManagement", - "permission": { "permission": 4, "category": null, "element": null }, - "parent": 1003504001, - "children": [] } ] }, diff --git a/Admin/Install/db.json b/Admin/Install/db.json index e89eecf..25133e0 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -225,7 +225,7 @@ }, "fleetmgmt_vehicle_inspection_interval": { "name": "fleetmgmt_vehicle_inspection_interval", - "type": "TINYINT(3)", + "type": "INT", "null": false }, "fleetmgmt_vehicle_inspection_next": { @@ -234,12 +234,25 @@ "null": true, "default": null }, + "fleetmgmt_vehicle_inspection_date": { + "name": "fleetmgmt_vehicle_inspection_date", + "type": "DATETIME", + "null": true, + "default": null + }, "fleetmgmt_vehicle_inspection_type": { "name": "fleetmgmt_vehicle_inspection_type", "type": "INT", "null": false, "foreignTable": "fleetmgmt_inspection_type", "foreignKey": "fleetmgmt_inspection_type_id" + }, + "fleetmgmt_vehicle_inspection_vehicle": { + "name": "fleetmgmt_vehicle_inspection_vehicle", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_vehicle", + "foreignKey": "fleetmgmt_vehicle_id" } } }, @@ -338,7 +351,7 @@ }, "fleetmgmt_driver_inspection_interval": { "name": "fleetmgmt_driver_inspection_interval", - "type": "TINYINT(3)", + "type": "INT", "null": false }, "fleetmgmt_driver_inspection_next": { @@ -347,12 +360,25 @@ "null": true, "default": null }, + "fleetmgmt_driver_inspection_date": { + "name": "fleetmgmt_driver_inspection_date", + "type": "DATETIME", + "null": true, + "default": null + }, "fleetmgmt_driver_inspection_type": { "name": "fleetmgmt_driver_inspection_type", "type": "INT", "null": false, "foreignTable": "fleetmgmt_driver_inspection_type", "foreignKey": "fleetmgmt_driver_inspection_type_id" + }, + "fleetmgmt_driver_inspection_driver": { + "name": "fleetmgmt_driver_inspection_driver", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_driver", + "foreignKey": "fleetmgmt_driver_id" } } }, @@ -957,5 +983,64 @@ "foreignKey": "editor_doc_id" } } + }, + "fleetmgmt_milage": { + "name": "fleetmgmt_milage", + "fields": { + "fleetmgmt_milage_id": { + "name": "fleetmgmt_milage_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "fleetmgmt_milage_status": { + "name": "fleetmgmt_milage_status", + "type": "TINYINT(1)", + "null": false + }, + "fleetmgmt_milage_description": { + "name": "fleetmgmt_milage_description", + "type": "TEXT", + "null": false + }, + "fleetmgmt_milage_start": { + "name": "fleetmgmt_milage_start", + "type": "DATETIME", + "null": true, + "default": null + }, + "fleetmgmt_milage_end": { + "name": "fleetmgmt_milage_end", + "type": "DATETIME", + "null": true, + "default": null + }, + "fleetmgmt_milage_milage": { + "name": "fleetmgmt_milage_milage", + "type": "INT", + "null": false + }, + "fleetmgmt_milage_fuel": { + "name": "fleetmgmt_milage_fuel", + "type": "INT", + "null": false + }, + "fleetmgmt_milage_driver": { + "name": "fleetmgmt_milage_driver", + "type": "INT", + "null": true, + "default": null, + "foreignTable": "fleetmgmt_driver", + "foreignKey": "fleetmgmt_driver_id" + }, + "fleetmgmt_milage_vehicle": { + "name": "fleetmgmt_milage_vehicle", + "type": "INT", + "null": false, + "foreignTable": "fleetmgmt_vehicle", + "foreignKey": "fleetmgmt_vehicle_id" + } + } } } \ No newline at end of file diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 75728b0..50cca4e 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -134,7 +134,18 @@ return [ '^.*/fleet/inspection/list.*$' => [ [ - 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleList', + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementInspectionList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::VEHICLE, + ], + ], + ], + '^.*/fleet/inspection/type/list.*$' => [ + [ + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementInspectionTypeList', 'verb' => RouteVerb::GET, 'permission' => [ 'module' => BackendController::NAME, @@ -145,7 +156,7 @@ return [ ], '^.*/fleet/inspection/create.*$' => [ [ - 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleCreate', + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementInspectionCreate', 'verb' => RouteVerb::GET, 'permission' => [ 'module' => BackendController::NAME, diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php index c7cf6dd..12d97fa 100644 --- a/Controller/ApiDriverController.php +++ b/Controller/ApiDriverController.php @@ -18,8 +18,11 @@ use Modules\Admin\Models\NullAccount; use Modules\FleetManagement\Models\Driver\DriverInspectionTypeL11nMapper; use Modules\FleetManagement\Models\Driver\DriverInspectionTypeMapper; use Modules\FleetManagement\Models\Driver\Driver; +use Modules\FleetManagement\Models\Driver\DriverInspectionMapper; use Modules\FleetManagement\Models\Driver\DriverMapper; use Modules\FleetManagement\Models\Driver\DriverStatus; +use Modules\FleetManagement\Models\Inspection; +use Modules\FleetManagement\Models\InspectionStatus; use Modules\Media\Models\CollectionMapper; use Modules\Media\Models\MediaMapper; use Modules\Media\Models\NullMedia; @@ -29,6 +32,7 @@ use Modules\Media\Models\ReferenceMapper; use phpOMS\Localization\BaseStringL11n; use phpOMS\Localization\BaseStringL11nType; use phpOMS\Localization\ISO639x1Enum; +use phpOMS\Localization\NullBaseStringL11nType; use phpOMS\Message\Http\RequestStatusCode; use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; @@ -44,6 +48,76 @@ use phpOMS\Message\ResponseAbstract; */ final class ApiDriverController extends Controller { + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiInspectionCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateInspectionCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\DriverInspection $inspection */ + $inspection = $this->createInspectionFromRequest($request); + $this->createModel($request->header->account, $inspection, DriverInspectionMapper::class, 'inspection', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $inspection); + } + + /** + * Method to create vehicle from request. + * + * @param RequestAbstract $request Request + * + * @return Inspection Returns the created vehicle from the request + * + * @since 1.0.0 + */ + public function createInspectionFromRequest(RequestAbstract $request) : Inspection + { + $inspection = new Inspection(); + $inspection->reference = (int) $request->getData('ref'); + $inspection->description = $request->getDataString('description') ?? ''; + $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; + $inspection->next = $request->getDataDateTime('next') ?? null; + $inspection->date = $request->getDataDateTime('date') ?? null; + $inspection->interval = $request->getDataInt('interval') ?? 0; + $inspection->type = new NullBaseStringL11nType((int) $request->getData('type')); + + return $inspection; + } + + /** + * Validate vehicle create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateInspectionCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['ref'] = !$request->hasData('ref'))) { + return $val; + } + + return []; + } + /** * Api method to create a driver * @@ -92,7 +166,7 @@ final class ApiDriverController extends Controller { $driver = new Driver(); $driver->account = new NullAccount($request->getDataInt('account') ?? 1); - $driver->status = (int) ($request->getDataInt('status') ?? DriverStatus::INACTIVE); + $driver->status = $request->getDataInt('status') ?? DriverStatus::INACTIVE; return $driver; } @@ -267,7 +341,7 @@ final class ApiDriverController extends Controller virtualPath: $path, pathSettings: PathSettings::FILE_PATH, hasAccountRelation: false, - readContent: (bool) ($request->getData('parse_content') ?? false) + readContent: $request->getDataBool('parse_content') ?? false ); $collection = null; diff --git a/Controller/ApiVehicleController.php b/Controller/ApiVehicleController.php index 411dc17..54fc498 100755 --- a/Controller/ApiVehicleController.php +++ b/Controller/ApiVehicleController.php @@ -15,10 +15,16 @@ declare(strict_types=1); namespace Modules\FleetManagement\Controller; use Modules\Admin\Models\NullAccount; +use Modules\FleetManagement\Models\Driver\NullDriver; +use Modules\FleetManagement\Models\InspectionStatus; use Modules\FleetManagement\Models\FuelTypeL11nMapper; use Modules\FleetManagement\Models\FuelTypeMapper; +use Modules\FleetManagement\Models\Inspection; +use Modules\FleetManagement\Models\InspectionMapper; use Modules\FleetManagement\Models\InspectionTypeL11nMapper; use Modules\FleetManagement\Models\InspectionTypeMapper; +use Modules\FleetManagement\Models\Milage; +use Modules\FleetManagement\Models\MilageMapper; use Modules\FleetManagement\Models\Vehicle; use Modules\FleetManagement\Models\VehicleMapper; use Modules\FleetManagement\Models\VehicleStatus; @@ -49,6 +55,149 @@ use phpOMS\Message\ResponseAbstract; */ final class ApiVehicleController extends Controller { + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiMilageCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateMilageCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\Milage $milage */ + $milage = $this->createMilageFromRequest($request); + $this->createModel($request->header->account, $milage, MilageMapper::class, 'milage', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $milage); + } + + /** + * Method to create vehicle from request. + * + * @param RequestAbstract $request Request + * + * @return Milage Returns the created vehicle from the request + * + * @since 1.0.0 + */ + public function createMilageFromRequest(RequestAbstract $request) : Milage + { + $milage = new Milage(); + $milage->vehicle = (int) $request->getData('vehicle'); + $milage->driver = $request->hasData('driver') ? new NullDriver((int) $request->getData('driver')) : null; + $milage->milage = $request->getDataInt('milage') ?? 0; + $milage->status = $request->getDataInt('status') ?? 0; + $milage->fuelUsage = $request->getDataInt('fuel') ?? 0; + $milage->description = $request->getDataString('description') ?? ''; + $milage->from = $request->getDataString('from') ?? ''; + $milage->to = $request->getDataString('to') ?? ''; + $milage->start = $request->getDataDateTime('start'); + $milage->end = $request->getDataDateTime('end'); + + return $milage; + } + + /** + * Validate vehicle create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateMilageCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['vehicle'] = !$request->hasData('vehicle'))) { + return $val; + } + + return []; + } + + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiInspectionCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateInspectionCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + /** @var \Modules\FleetManagement\Models\Inspection $inspection */ + $inspection = $this->createInspectionFromRequest($request); + $this->createModel($request->header->account, $inspection, InspectionMapper::class, 'inspection', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $inspection); + } + + /** + * Method to create vehicle from request. + * + * @param RequestAbstract $request Request + * + * @return Inspection Returns the created vehicle from the request + * + * @since 1.0.0 + */ + public function createInspectionFromRequest(RequestAbstract $request) : Inspection + { + $inspection = new Inspection(); + $inspection->reference = (int) $request->getData('ref'); + $inspection->description = $request->getDataString('description') ?? ''; + $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; + $inspection->next = $request->getDataDateTime('next') ?? null; + $inspection->date = $request->getDataDateTime('date') ?? null; + $inspection->interval = $request->getDataInt('interval') ?? 0; + $inspection->type = new NullBaseStringL11nType((int) $request->getData('type')); + + return $inspection; + } + + /** + * Validate vehicle create request + * + * @param RequestAbstract $request Request + * + * @return array Returns the validation array of the request + * + * @since 1.0.0 + */ + private function validateInspectionCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['ref'] = !$request->hasData('ref'))) { + return $val; + } + + return []; + } + /** * Api method to create a vehicle * @@ -372,7 +521,7 @@ final class ApiVehicleController extends Controller $vehicle->info = $request->getDataString('info') ?? ''; $vehicle->type = new NullBaseStringL11nType((int) ($request->getDataInt('type') ?? 0)); $vehicle->fuelType = new NullBaseStringL11nType((int) ($request->getDataInt('fuel') ?? 0)); - $vehicle->status = (int) ($request->getDataInt('status') ?? VehicleStatus::INACTIVE); + $vehicle->status = $request->getDataInt('status') ?? VehicleStatus::INACTIVE; $vehicle->unit = $request->getDataInt('unit') ?? $this->app->unitId; return $vehicle; @@ -549,7 +698,7 @@ final class ApiVehicleController extends Controller virtualPath: $path, pathSettings: PathSettings::FILE_PATH, hasAccountRelation: false, - readContent: (bool) ($request->getData('parse_content') ?? false) + readContent: $request->getDataBool('parse_content') ?? false ); $collection = null; @@ -853,7 +1002,7 @@ final class ApiVehicleController extends Controller } /** - * Api method to update note + * Api method to update Note * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -865,17 +1014,28 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiNoteEdit(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - $this->app->moduleManager->get('Editor', 'Api')->apiEditorUpdate($request, $response, $data); + // @todo: check permissions + $this->app->moduleManager->get('Editor', 'Api')->apiEditorDocUpdate($request, $response, $data); + } - if ($response->header->status !== RequestStatusCode::R_200) { - return; - } - - $responseData = $response->get($request->uri->__toString()); - if (!\is_array($responseData)) { - return; - } + /** + * Api method to delete Note + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + // @todo: check permissions + $this->app->moduleManager->get('Editor', 'Api')->apiEditorDocDelete($request, $response, $data); } } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 30a5ab4..ab03c04 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -16,8 +16,10 @@ namespace Modules\FleetManagement\Controller; use Modules\Admin\Models\LocalizationMapper; use Modules\Admin\Models\SettingsEnum; -use Modules\FleetManagement\Models\VehicleAttributeTypeL11nMapper; -use Modules\FleetManagement\Models\VehicleAttributeTypeMapper; +use Modules\FleetManagement\Models\InspectionMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeTypeL11nMapper; +use Modules\FleetManagement\Models\Attribute\VehicleAttributeTypeMapper; +use Modules\FleetManagement\Models\Driver\DriverMapper; use Modules\FleetManagement\Models\VehicleMapper; use Modules\FleetManagement\Models\VehicleTypeMapper; use Modules\Media\Models\MediaMapper; @@ -129,6 +131,34 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementInspectionList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/inspection-list'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + $list = InspectionMapper::getAll() + ->sort('id', 'DESC') + ->execute(); + + $view->data['inspectionss'] = $list; + + return $view; + } + /** * Routing end-point for application behaviour. * @@ -236,6 +266,15 @@ final class BackendController extends Controller $view->data['vehicle'] = $vehicle; + $inspections = InspectionMapper::getAll() + ->with('type') + ->with('type/l11n') + ->where('reference', $vehicle->id) + ->where('type/l11n/language', $response->header->l11n->language) + ->execute(); + + $view->data['inspections'] = $inspections; + $query = new Builder($this->app->dbPool->get()); $results = $query->selectAs(VehicleMapper::HAS_MANY['files']['external'], 'file') ->from(VehicleMapper::TABLE) diff --git a/Models/Driver/DriverInspection.php b/Models/Driver/DriverInspection.php deleted file mode 100644 index 39e5d9a..0000000 --- a/Models/Driver/DriverInspection.php +++ /dev/null @@ -1,78 +0,0 @@ -type = new BaseStringL11nType(); - } - - /** - * {@inheritdoc} - */ - public function toArray() : array - { - return [ - 'id' => $this->id, - ]; - } - - /** - * {@inheritdoc} - */ - public function jsonSerialize() : mixed - { - return $this->toArray(); - } - - use \Modules\Media\Models\MediaListTrait; -} diff --git a/Models/Driver/DriverInspectionMapper.php b/Models/Driver/DriverInspectionMapper.php index b7a04ba..5b7ef65 100644 --- a/Models/Driver/DriverInspectionMapper.php +++ b/Models/Driver/DriverInspectionMapper.php @@ -14,8 +14,8 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models\Driver; +use Modules\FleetManagement\Models\Inspection; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; -use phpOMS\Localization\BaseStringL11n; /** * mapper class. @@ -25,7 +25,7 @@ use phpOMS\Localization\BaseStringL11n; * @link https://jingga.app * @since 1.0.0 * - * @template T of DriverInspection + * @template T of Inspection * @extends DataMapperFactory */ final class DriverInspectionMapper extends DataMapperFactory @@ -38,10 +38,12 @@ final class DriverInspectionMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_driver_inspection_id' => ['name' => 'fleetmgmt_driver_inspection_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_inspection_driver' => ['name' => 'fleetmgmt_driver_inspection_driver', 'type' => 'int', 'internal' => 'reference'], 'fleetmgmt_driver_inspection_description' => ['name' => 'fleetmgmt_driver_inspection_description', 'type' => 'string', 'internal' => 'description'], 'fleetmgmt_driver_inspection_status' => ['name' => 'fleetmgmt_driver_inspection_status', 'type' => 'int', 'internal' => 'status'], 'fleetmgmt_driver_inspection_interval' => ['name' => 'fleetmgmt_driver_inspection_interval', 'type' => 'int', 'internal' => 'interval'], 'fleetmgmt_driver_inspection_next' => ['name' => 'fleetmgmt_driver_inspection_next', 'type' => 'DateTime', 'internal' => 'next'], + 'fleetmgmt_driver_inspection_date' => ['name' => 'fleetmgmt_driver_inspection_date', 'type' => 'DateTime', 'internal' => 'date'], 'fleetmgmt_driver_inspection_type' => ['name' => 'fleetmgmt_driver_inspection_type', 'type' => 'int', 'internal' => 'type'], ]; @@ -80,5 +82,5 @@ final class DriverInspectionMapper extends DataMapperFactory * @var class-string * @since 1.0.0 */ - public const MODEL = DriverInspection::class; + public const MODEL = Inspection::class; } diff --git a/Models/Driver/DriverInspectionStatus.php b/Models/Driver/DriverInspectionStatus.php deleted file mode 100644 index 78b7e58..0000000 --- a/Models/Driver/DriverInspectionStatus.php +++ /dev/null @@ -1,36 +0,0 @@ - */ final class InspectionMapper extends DataMapperFactory @@ -38,10 +38,12 @@ final class InspectionMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_vehicle_inspection_id' => ['name' => 'fleetmgmt_vehicle_inspection_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_inspection_vehicle' => ['name' => 'fleetmgmt_vehicle_inspection_vehicle', 'type' => 'int', 'internal' => 'reference'], 'fleetmgmt_vehicle_inspection_description' => ['name' => 'fleetmgmt_vehicle_inspection_description', 'type' => 'string', 'internal' => 'description'], 'fleetmgmt_vehicle_inspection_status' => ['name' => 'fleetmgmt_vehicle_inspection_status', 'type' => 'int', 'internal' => 'status'], 'fleetmgmt_vehicle_inspection_interval' => ['name' => 'fleetmgmt_vehicle_inspection_interval', 'type' => 'int', 'internal' => 'interval'], 'fleetmgmt_vehicle_inspection_next' => ['name' => 'fleetmgmt_vehicle_inspection_next', 'type' => 'DateTime', 'internal' => 'next'], + 'fleetmgmt_vehicle_inspection_date' => ['name' => 'fleetmgmt_vehicle_inspection_date', 'type' => 'DateTime', 'internal' => 'date'], 'fleetmgmt_vehicle_inspection_type' => ['name' => 'fleetmgmt_vehicle_inspection_type', 'type' => 'int', 'internal' => 'type'], ]; diff --git a/Models/Milage.php b/Models/Milage.php new file mode 100644 index 0000000..889aa71 --- /dev/null +++ b/Models/Milage.php @@ -0,0 +1,75 @@ + $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/MilageMapper.php b/Models/MilageMapper.php new file mode 100644 index 0000000..361b740 --- /dev/null +++ b/Models/MilageMapper.php @@ -0,0 +1,91 @@ + + */ +final class MilageMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'fleetmgmt_milage_id' => ['name' => 'fleetmgmt_milage_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_milage_description' => ['name' => 'fleetmgmt_milage_description', 'type' => 'string', 'internal' => 'description'], + 'fleetmgmt_milage_status' => ['name' => 'fleetmgmt_milage_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_milage_driver' => ['name' => 'fleetmgmt_milage_driver', 'type' => 'int', 'internal' => 'driver'], + 'fleetmgmt_milage_vehicle' => ['name' => 'fleetmgmt_milage_vehicle', 'type' => 'int', 'internal' => 'vehicle'], + 'fleetmgmt_milage_start' => ['name' => 'fleetmgmt_milage_start', 'type' => 'DateTime', 'internal' => 'start'], + 'fleetmgmt_milage_end' => ['name' => 'fleetmgmt_milage_end', 'type' => 'DateTime', 'internal' => 'end'], + 'fleetmgmt_milage_milage' => ['name' => 'fleetmgmt_milage_milage', 'type' => 'int', 'internal' => 'milage'], + 'fleetmgmt_milage_fuel' => ['name' => 'fleetmgmt_milage_fuel', 'type' => 'int', 'internal' => 'fuelUsage'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'driver' => [ + 'mapper' => DriverMapper::class, + 'external' => 'fleetmgmt_milage_driver', + ], + 'vehicle' => [ + 'mapper' => VehicleMapper::class, + 'external' => 'fleetmgmt_milage_vehicle', + ], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'fleetmgmt_milage'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'fleetmgmt_milage_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = Milage::class; +} diff --git a/Theme/Backend/driver-list.tpl.php b/Theme/Backend/driver-list.tpl.php index 99d4394..feafd15 100644 --- a/Theme/Backend/driver-list.tpl.php +++ b/Theme/Backend/driver-list.tpl.php @@ -22,7 +22,7 @@ echo $this->data['nav']->render(); ?>
-
getHtml('Vehicles'); ?>
+
getHtml('Drivers'); ?>
diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 79dd3d5..015d005 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -179,10 +179,12 @@ echo $this->data['nav']->render(); + data['inspections'] as $inspection) : ?> +
getHtml('Type'); ?> getHtml('Responsible'); ?>
next?->format('Y-m-d H:i') ?> + printHtml($inspection->type->getL11n()); ?> - - +
diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 80a0a1e..d2d0080 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -71,14 +71,12 @@ final class Autoloader * * @return void * - * @throws AutoloadException Throws this exception if the class to autoload doesn't exist. This could also be related to a wrong namespace/file path correlation. - * * @since 1.0.0 */ public static function defaultAutoloader(string $class) : void { $class = \ltrim($class, '\\'); - $class = \str_replace(['_', '\\'], '/', $class); + $class = \strtr($class, '_\\', '//'); foreach (self::$paths as $path) { $file = $path . $class . '.php'; From d0a2677634acf03b8eb0202a4d9f0e6635661b14 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 30 Aug 2023 12:08:09 +0000 Subject: [PATCH 39/89] autofixes --- Controller/ApiDriverAttributeController.php | 1 - Controller/ApiDriverController.php | 18 +++---- Controller/ApiVehicleAttributeController.php | 1 - Controller/ApiVehicleController.php | 36 ++++++------- Controller/BackendController.php | 4 +- Models/Attribute/DriverAttributeMapper.php | 6 +-- Models/Attribute/VehicleAttributeMapper.php | 6 +-- Models/Driver/DriverInspectionMapper.php | 2 +- Models/Driver/DriverMapper.php | 6 +-- Models/InspectionMapper.php | 3 +- Models/Milage.php | 3 ++ Models/MilageMapper.php | 16 +++--- Models/VehicleMapper.php | 4 +- Theme/Backend/Lang/Navigation.en.lang.php | 12 ++--- Theme/Backend/Lang/en.lang.php | 56 ++++++++++---------- Theme/Backend/driver-profile.tpl.php | 8 +-- Theme/Backend/vehicle-profile.tpl.php | 6 +-- 17 files changed, 94 insertions(+), 94 deletions(-) diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php index e4d479e..f256ae5 100644 --- a/Controller/ApiDriverAttributeController.php +++ b/Controller/ApiDriverAttributeController.php @@ -446,7 +446,6 @@ final class ApiDriverAttributeController extends Controller public function apiDriverAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { return; - // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values // either here or other function? diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php index 12d97fa..06285ab 100644 --- a/Controller/ApiDriverController.php +++ b/Controller/ApiDriverController.php @@ -15,10 +15,10 @@ declare(strict_types=1); namespace Modules\FleetManagement\Controller; use Modules\Admin\Models\NullAccount; -use Modules\FleetManagement\Models\Driver\DriverInspectionTypeL11nMapper; -use Modules\FleetManagement\Models\Driver\DriverInspectionTypeMapper; use Modules\FleetManagement\Models\Driver\Driver; use Modules\FleetManagement\Models\Driver\DriverInspectionMapper; +use Modules\FleetManagement\Models\Driver\DriverInspectionTypeL11nMapper; +use Modules\FleetManagement\Models\Driver\DriverInspectionTypeMapper; use Modules\FleetManagement\Models\Driver\DriverMapper; use Modules\FleetManagement\Models\Driver\DriverStatus; use Modules\FleetManagement\Models\Inspection; @@ -87,14 +87,14 @@ final class ApiDriverController extends Controller */ public function createInspectionFromRequest(RequestAbstract $request) : Inspection { - $inspection = new Inspection(); - $inspection->reference = (int) $request->getData('ref'); + $inspection = new Inspection(); + $inspection->reference = (int) $request->getData('ref'); $inspection->description = $request->getDataString('description') ?? ''; - $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; - $inspection->next = $request->getDataDateTime('next') ?? null; - $inspection->date = $request->getDataDateTime('date') ?? null; - $inspection->interval = $request->getDataInt('interval') ?? 0; - $inspection->type = new NullBaseStringL11nType((int) $request->getData('type')); + $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; + $inspection->next = $request->getDataDateTime('next') ?? null; + $inspection->date = $request->getDataDateTime('date') ?? null; + $inspection->interval = $request->getDataInt('interval') ?? 0; + $inspection->type = new NullBaseStringL11nType((int) $request->getData('type')); return $inspection; } diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php index c40475d..773d641 100644 --- a/Controller/ApiVehicleAttributeController.php +++ b/Controller/ApiVehicleAttributeController.php @@ -446,7 +446,6 @@ final class ApiVehicleAttributeController extends Controller public function apiVehicleAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { return; - // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values // either here or other function? diff --git a/Controller/ApiVehicleController.php b/Controller/ApiVehicleController.php index 54fc498..489c24e 100755 --- a/Controller/ApiVehicleController.php +++ b/Controller/ApiVehicleController.php @@ -16,11 +16,11 @@ namespace Modules\FleetManagement\Controller; use Modules\Admin\Models\NullAccount; use Modules\FleetManagement\Models\Driver\NullDriver; -use Modules\FleetManagement\Models\InspectionStatus; use Modules\FleetManagement\Models\FuelTypeL11nMapper; use Modules\FleetManagement\Models\FuelTypeMapper; use Modules\FleetManagement\Models\Inspection; use Modules\FleetManagement\Models\InspectionMapper; +use Modules\FleetManagement\Models\InspectionStatus; use Modules\FleetManagement\Models\InspectionTypeL11nMapper; use Modules\FleetManagement\Models\InspectionTypeMapper; use Modules\FleetManagement\Models\Milage; @@ -94,17 +94,17 @@ final class ApiVehicleController extends Controller */ public function createMilageFromRequest(RequestAbstract $request) : Milage { - $milage = new Milage(); - $milage->vehicle = (int) $request->getData('vehicle'); - $milage->driver = $request->hasData('driver') ? new NullDriver((int) $request->getData('driver')) : null; - $milage->milage = $request->getDataInt('milage') ?? 0; - $milage->status = $request->getDataInt('status') ?? 0; - $milage->fuelUsage = $request->getDataInt('fuel') ?? 0; + $milage = new Milage(); + $milage->vehicle = (int) $request->getData('vehicle'); + $milage->driver = $request->hasData('driver') ? new NullDriver((int) $request->getData('driver')) : null; + $milage->milage = $request->getDataInt('milage') ?? 0; + $milage->status = $request->getDataInt('status') ?? 0; + $milage->fuelUsage = $request->getDataInt('fuel') ?? 0; $milage->description = $request->getDataString('description') ?? ''; - $milage->from = $request->getDataString('from') ?? ''; - $milage->to = $request->getDataString('to') ?? ''; - $milage->start = $request->getDataDateTime('start'); - $milage->end = $request->getDataDateTime('end'); + $milage->from = $request->getDataString('from') ?? ''; + $milage->to = $request->getDataString('to') ?? ''; + $milage->start = $request->getDataDateTime('start'); + $milage->end = $request->getDataDateTime('end'); return $milage; } @@ -167,14 +167,14 @@ final class ApiVehicleController extends Controller */ public function createInspectionFromRequest(RequestAbstract $request) : Inspection { - $inspection = new Inspection(); - $inspection->reference = (int) $request->getData('ref'); + $inspection = new Inspection(); + $inspection->reference = (int) $request->getData('ref'); $inspection->description = $request->getDataString('description') ?? ''; - $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; - $inspection->next = $request->getDataDateTime('next') ?? null; - $inspection->date = $request->getDataDateTime('date') ?? null; - $inspection->interval = $request->getDataInt('interval') ?? 0; - $inspection->type = new NullBaseStringL11nType((int) $request->getData('type')); + $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; + $inspection->next = $request->getDataDateTime('next') ?? null; + $inspection->date = $request->getDataDateTime('date') ?? null; + $inspection->interval = $request->getDataInt('interval') ?? 0; + $inspection->type = new NullBaseStringL11nType((int) $request->getData('type')); return $inspection; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index ab03c04..82adfb0 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -16,10 +16,10 @@ namespace Modules\FleetManagement\Controller; use Modules\Admin\Models\LocalizationMapper; use Modules\Admin\Models\SettingsEnum; -use Modules\FleetManagement\Models\InspectionMapper; use Modules\FleetManagement\Models\Attribute\VehicleAttributeTypeL11nMapper; use Modules\FleetManagement\Models\Attribute\VehicleAttributeTypeMapper; use Modules\FleetManagement\Models\Driver\DriverMapper; +use Modules\FleetManagement\Models\InspectionMapper; use Modules\FleetManagement\Models\VehicleMapper; use Modules\FleetManagement\Models\VehicleTypeMapper; use Modules\Media\Models\MediaMapper; @@ -387,7 +387,7 @@ final class BackendController extends Controller $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); - $view->data['driver-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); + $view->data['driver-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); return $view; } diff --git a/Models/Attribute/DriverAttributeMapper.php b/Models/Attribute/DriverAttributeMapper.php index 222fd09..3443ea3 100644 --- a/Models/Attribute/DriverAttributeMapper.php +++ b/Models/Attribute/DriverAttributeMapper.php @@ -37,10 +37,10 @@ final class DriverAttributeMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'fleetmgmt_driver_attr_id' => ['name' => 'fleetmgmt_driver_attr_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_driver_attr_id' => ['name' => 'fleetmgmt_driver_attr_id', 'type' => 'int', 'internal' => 'id'], 'fleetmgmt_driver_attr_driver' => ['name' => 'fleetmgmt_driver_attr_driver', 'type' => 'int', 'internal' => 'ref'], - 'fleetmgmt_driver_attr_type' => ['name' => 'fleetmgmt_driver_attr_type', 'type' => 'int', 'internal' => 'type'], - 'fleetmgmt_driver_attr_value' => ['name' => 'fleetmgmt_driver_attr_value', 'type' => 'int', 'internal' => 'value'], + 'fleetmgmt_driver_attr_type' => ['name' => 'fleetmgmt_driver_attr_type', 'type' => 'int', 'internal' => 'type'], + 'fleetmgmt_driver_attr_value' => ['name' => 'fleetmgmt_driver_attr_value', 'type' => 'int', 'internal' => 'value'], ]; /** diff --git a/Models/Attribute/VehicleAttributeMapper.php b/Models/Attribute/VehicleAttributeMapper.php index c3c39f3..ea68063 100644 --- a/Models/Attribute/VehicleAttributeMapper.php +++ b/Models/Attribute/VehicleAttributeMapper.php @@ -37,10 +37,10 @@ final class VehicleAttributeMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'fleetmgmt_vehicle_attr_id' => ['name' => 'fleetmgmt_vehicle_attr_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_vehicle_attr_id' => ['name' => 'fleetmgmt_vehicle_attr_id', 'type' => 'int', 'internal' => 'id'], 'fleetmgmt_vehicle_attr_vehicle' => ['name' => 'fleetmgmt_vehicle_attr_vehicle', 'type' => 'int', 'internal' => 'ref'], - 'fleetmgmt_vehicle_attr_type' => ['name' => 'fleetmgmt_vehicle_attr_type', 'type' => 'int', 'internal' => 'type'], - 'fleetmgmt_vehicle_attr_value' => ['name' => 'fleetmgmt_vehicle_attr_value', 'type' => 'int', 'internal' => 'value'], + 'fleetmgmt_vehicle_attr_type' => ['name' => 'fleetmgmt_vehicle_attr_type', 'type' => 'int', 'internal' => 'type'], + 'fleetmgmt_vehicle_attr_value' => ['name' => 'fleetmgmt_vehicle_attr_value', 'type' => 'int', 'internal' => 'value'], ]; /** diff --git a/Models/Driver/DriverInspectionMapper.php b/Models/Driver/DriverInspectionMapper.php index 5b7ef65..f7be7bd 100644 --- a/Models/Driver/DriverInspectionMapper.php +++ b/Models/Driver/DriverInspectionMapper.php @@ -38,7 +38,7 @@ final class DriverInspectionMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_driver_inspection_id' => ['name' => 'fleetmgmt_driver_inspection_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_driver_inspection_driver' => ['name' => 'fleetmgmt_driver_inspection_driver', 'type' => 'int', 'internal' => 'reference'], + 'fleetmgmt_driver_inspection_driver' => ['name' => 'fleetmgmt_driver_inspection_driver', 'type' => 'int', 'internal' => 'reference'], 'fleetmgmt_driver_inspection_description' => ['name' => 'fleetmgmt_driver_inspection_description', 'type' => 'string', 'internal' => 'description'], 'fleetmgmt_driver_inspection_status' => ['name' => 'fleetmgmt_driver_inspection_status', 'type' => 'int', 'internal' => 'status'], 'fleetmgmt_driver_inspection_interval' => ['name' => 'fleetmgmt_driver_inspection_interval', 'type' => 'int', 'internal' => 'interval'], diff --git a/Models/Driver/DriverMapper.php b/Models/Driver/DriverMapper.php index dc6d888..9994024 100644 --- a/Models/Driver/DriverMapper.php +++ b/Models/Driver/DriverMapper.php @@ -15,10 +15,10 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models\Driver; use Modules\Admin\Models\AccountMapper; -use Modules\Media\Models\MediaMapper; -use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use Modules\Editor\Models\EditorDocMapper; use Modules\FleetManagement\Models\Attribute\DriverAttributeMapper; +use Modules\Media\Models\MediaMapper; +use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Mapper class. @@ -42,7 +42,7 @@ final class DriverMapper extends DataMapperFactory public const COLUMNS = [ 'fleetmgmt_driver_id' => ['name' => 'fleetmgmt_driver_id', 'type' => 'int', 'internal' => 'id'], 'fleetmgmt_driver_status' => ['name' => 'fleetmgmt_driver_status', 'type' => 'int', 'internal' => 'status'], - 'fleetmgmt_driver_account' => ['name' => 'fleetmgmt_driver_account', 'type' => 'int', 'internal' => 'account'], + 'fleetmgmt_driver_account' => ['name' => 'fleetmgmt_driver_account', 'type' => 'int', 'internal' => 'account'], ]; /** diff --git a/Models/InspectionMapper.php b/Models/InspectionMapper.php index a087540..d6af791 100644 --- a/Models/InspectionMapper.php +++ b/Models/InspectionMapper.php @@ -15,7 +15,6 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; -use phpOMS\Localization\BaseStringL11n; /** * mapper class. @@ -38,7 +37,7 @@ final class InspectionMapper extends DataMapperFactory */ public const COLUMNS = [ 'fleetmgmt_vehicle_inspection_id' => ['name' => 'fleetmgmt_vehicle_inspection_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_vehicle_inspection_vehicle' => ['name' => 'fleetmgmt_vehicle_inspection_vehicle', 'type' => 'int', 'internal' => 'reference'], + 'fleetmgmt_vehicle_inspection_vehicle' => ['name' => 'fleetmgmt_vehicle_inspection_vehicle', 'type' => 'int', 'internal' => 'reference'], 'fleetmgmt_vehicle_inspection_description' => ['name' => 'fleetmgmt_vehicle_inspection_description', 'type' => 'string', 'internal' => 'description'], 'fleetmgmt_vehicle_inspection_status' => ['name' => 'fleetmgmt_vehicle_inspection_status', 'type' => 'int', 'internal' => 'status'], 'fleetmgmt_vehicle_inspection_interval' => ['name' => 'fleetmgmt_vehicle_inspection_interval', 'type' => 'int', 'internal' => 'interval'], diff --git a/Models/Milage.php b/Models/Milage.php index 889aa71..4874b71 100644 --- a/Models/Milage.php +++ b/Models/Milage.php @@ -29,12 +29,15 @@ class Milage implements \JsonSerializable public int $id = 0; public int $vehicle = 0; + public ?Driver $driver = null; public ?\DateTime $start = null; + public ?\DateTime $end = null; public string $from = ''; + public string $to = ''; /** diff --git a/Models/MilageMapper.php b/Models/MilageMapper.php index 361b740..69d8163 100644 --- a/Models/MilageMapper.php +++ b/Models/MilageMapper.php @@ -37,15 +37,15 @@ final class MilageMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'fleetmgmt_milage_id' => ['name' => 'fleetmgmt_milage_id', 'type' => 'int', 'internal' => 'id'], - 'fleetmgmt_milage_description' => ['name' => 'fleetmgmt_milage_description', 'type' => 'string', 'internal' => 'description'], - 'fleetmgmt_milage_status' => ['name' => 'fleetmgmt_milage_status', 'type' => 'int', 'internal' => 'status'], - 'fleetmgmt_milage_driver' => ['name' => 'fleetmgmt_milage_driver', 'type' => 'int', 'internal' => 'driver'], - 'fleetmgmt_milage_vehicle' => ['name' => 'fleetmgmt_milage_vehicle', 'type' => 'int', 'internal' => 'vehicle'], - 'fleetmgmt_milage_start' => ['name' => 'fleetmgmt_milage_start', 'type' => 'DateTime', 'internal' => 'start'], - 'fleetmgmt_milage_end' => ['name' => 'fleetmgmt_milage_end', 'type' => 'DateTime', 'internal' => 'end'], + 'fleetmgmt_milage_id' => ['name' => 'fleetmgmt_milage_id', 'type' => 'int', 'internal' => 'id'], + 'fleetmgmt_milage_description' => ['name' => 'fleetmgmt_milage_description', 'type' => 'string', 'internal' => 'description'], + 'fleetmgmt_milage_status' => ['name' => 'fleetmgmt_milage_status', 'type' => 'int', 'internal' => 'status'], + 'fleetmgmt_milage_driver' => ['name' => 'fleetmgmt_milage_driver', 'type' => 'int', 'internal' => 'driver'], + 'fleetmgmt_milage_vehicle' => ['name' => 'fleetmgmt_milage_vehicle', 'type' => 'int', 'internal' => 'vehicle'], + 'fleetmgmt_milage_start' => ['name' => 'fleetmgmt_milage_start', 'type' => 'DateTime', 'internal' => 'start'], + 'fleetmgmt_milage_end' => ['name' => 'fleetmgmt_milage_end', 'type' => 'DateTime', 'internal' => 'end'], 'fleetmgmt_milage_milage' => ['name' => 'fleetmgmt_milage_milage', 'type' => 'int', 'internal' => 'milage'], - 'fleetmgmt_milage_fuel' => ['name' => 'fleetmgmt_milage_fuel', 'type' => 'int', 'internal' => 'fuelUsage'], + 'fleetmgmt_milage_fuel' => ['name' => 'fleetmgmt_milage_fuel', 'type' => 'int', 'internal' => 'fuelUsage'], ]; /** diff --git a/Models/VehicleMapper.php b/Models/VehicleMapper.php index cb099e9..d0c9b36 100644 --- a/Models/VehicleMapper.php +++ b/Models/VehicleMapper.php @@ -14,10 +14,10 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models; -use Modules\Media\Models\MediaMapper; -use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use Modules\Editor\Models\EditorDocMapper; use Modules\FleetManagement\Models\Attribute\VehicleAttributeMapper; +use Modules\Media\Models\MediaMapper; +use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** * Mapper class. diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index 138fd60..adab256 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -13,12 +13,12 @@ declare(strict_types=1); return ['Navigation' => [ - 'FleetManagement' => 'Fleet Management', - 'Vehicles' => 'Vehicles', - 'Drivers' => 'Drivers', - 'Inspections' => 'Inspections', + 'FleetManagement' => 'Fleet Management', + 'Vehicles' => 'Vehicles', + 'Drivers' => 'Drivers', + 'Inspections' => 'Inspections', 'VehicleInspectionTypes' => 'Vehicle Inspection Types', 'DriverInspectionTypes' => 'Driver Inspection Types', - 'VehicleAttributes' => 'Vehicle Attributes', - 'DriverAttributes' => 'Driver Attributes', + 'VehicleAttributes' => 'Vehicle Attributes', + 'DriverAttributes' => 'Driver Attributes', ]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index d644579..889cdf7 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -13,33 +13,33 @@ declare(strict_types=1); return ['FleetManagement' => [ - 'Vehicle' => 'Vehicle', - 'Vehicles' => 'Vehicles', - 'Status' => 'Status', - 'Name' => 'Name', - 'Type' => 'Type', - 'Make' => 'Make', - 'Model' => 'Model', - 'Start' => 'Start', - 'End' => 'End', - 'Profile' => 'Profile', - 'Attributes' => 'Attributes', - 'Files' => 'Files', - 'Notes' => 'Notes', - 'Costs' => 'Costs', - 'Inspections' => 'Inspections', - 'Drivers' => 'Drivers', - 'Milage' => 'Milage', - 'Driver' => 'Driver', - 'Vin' => 'Vin', - 'History' => 'History', - 'Upcoming' => 'Upcoming', + 'Vehicle' => 'Vehicle', + 'Vehicles' => 'Vehicles', + 'Status' => 'Status', + 'Name' => 'Name', + 'Type' => 'Type', + 'Make' => 'Make', + 'Model' => 'Model', + 'Start' => 'Start', + 'End' => 'End', + 'Profile' => 'Profile', + 'Attributes' => 'Attributes', + 'Files' => 'Files', + 'Notes' => 'Notes', + 'Costs' => 'Costs', + 'Inspections' => 'Inspections', + 'Drivers' => 'Drivers', + 'Milage' => 'Milage', + 'Driver' => 'Driver', + 'Vin' => 'Vin', + 'History' => 'History', + 'Upcoming' => 'Upcoming', 'Responsible' => 'Responsible', - 'Date' => 'Date', - 'PurchasePrice' => 'Purchase Price', - 'LeasingFee' => 'Leasing Fee', - ':status1' => 'Active', - ':status2' => 'Inactive', - ':status3' => 'Damaged', - ':status4' => 'Out of order', + 'Date' => 'Date', + 'PurchasePrice' => 'Purchase Price', + 'LeasingFee' => 'Leasing Fee', + ':status1' => 'Active', + ':status2' => 'Inactive', + ':status3' => 'Damaged', + ':status4' => 'Out of order', ]]; diff --git a/Theme/Backend/driver-profile.tpl.php b/Theme/Backend/driver-profile.tpl.php index 62569c0..ac5c914 100644 --- a/Theme/Backend/driver-profile.tpl.php +++ b/Theme/Backend/driver-profile.tpl.php @@ -12,14 +12,14 @@ */ declare(strict_types=1); -use Modules\FleetManagement\Models\NullDriver; use Modules\FleetManagement\Models\DriverStatus; +use Modules\FleetManagement\Models\NullDriver; use Modules\Media\Models\NullMedia; use phpOMS\Uri\UriFactory; $countryCodes = \phpOMS\Localization\ISO3166TwoEnum::getConstants(); $countries = \phpOMS\Localization\ISO3166NameEnum::getConstants(); -$driverStatus = DriverStatus::getConstants(); +$driverStatus = DriverStatus::getConstants(); /** * @var \Modules\FleetManagement\Models\Driver $driver @@ -121,7 +121,7 @@ echo $this->data['nav']->render(); request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>>
@@ -277,7 +277,7 @@ echo $this->data['nav']->render();
diff --git a/Theme/Backend/vehicle-profile.tpl.php b/Theme/Backend/vehicle-profile.tpl.php index 015d005..58c288c 100755 --- a/Theme/Backend/vehicle-profile.tpl.php +++ b/Theme/Backend/vehicle-profile.tpl.php @@ -166,7 +166,7 @@ echo $this->data['nav']->render(); request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>>
@@ -181,7 +181,7 @@ echo $this->data['nav']->render();
next?->format('Y-m-d H:i') ?> + next?->format('Y-m-d H:i'); ?> printHtml($inspection->type->getL11n()); ?> @@ -324,7 +324,7 @@ echo $this->data['nav']->render();
From 48b371ee9e343e9cb6a8d85bca4f1483615007a5 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 10 Sep 2023 18:58:34 +0000 Subject: [PATCH 40/89] update --- Controller/ApiDriverAttributeController.php | 8 ++++---- Controller/ApiDriverController.php | 4 ++-- Controller/ApiVehicleAttributeController.php | 8 ++++---- Controller/ApiVehicleController.php | 2 +- Controller/BackendController.php | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php index f256ae5..959bd56 100644 --- a/Controller/ApiDriverAttributeController.php +++ b/Controller/ApiDriverAttributeController.php @@ -327,7 +327,7 @@ final class ApiDriverAttributeController extends Controller return; } - /** @var \Modules\FleetManagement\Models\DriverAttributeTypeL11n $driverAttributeTypeL11n */ + /** @var BaseStringL11n $driverAttributeTypeL11n */ $driverAttributeTypeL11n = DriverAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); $this->deleteModel($request->header->account, $driverAttributeTypeL11n, DriverAttributeTypeL11nMapper::class, 'driver_attribute_type_l11n', $request->getOrigin()); $this->createStandardDeleteResponse($request, $response, $driverAttributeTypeL11n); @@ -387,7 +387,7 @@ final class ApiDriverAttributeController extends Controller return; } - /** @var \Modules\FleetManagement\Models\DriverAttributeType $driverAttributeType */ + /** @var AttributeType $driverAttributeType */ $driverAttributeType = DriverAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); $this->deleteModel($request->header->account, $driverAttributeType, DriverAttributeTypeMapper::class, 'driver_attribute_type', $request->getOrigin()); $this->createStandardDeleteResponse($request, $response, $driverAttributeType); @@ -418,7 +418,7 @@ final class ApiDriverAttributeController extends Controller /** @var AttributeValue $old */ $old = DriverAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); - /** @var \Modules\Attribute\Models\Attribute $type */ + /** @var \Modules\Attribute\Models\Attribute $attr */ $attr = DriverAttributeMapper::get() ->with('type') ->where('id', $request->getDataInt('attribute') ?? 0) @@ -514,7 +514,7 @@ final class ApiDriverAttributeController extends Controller return; } - /** @var \Modules\FleetManagement\Models\DriverAttributeValueL11n $driverAttributeValueL11n */ + /** @var BaseStringL11n $driverAttributeValueL11n */ $driverAttributeValueL11n = DriverAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); $this->deleteModel($request->header->account, $driverAttributeValueL11n, DriverAttributeValueL11nMapper::class, 'driver_attribute_value_l11n', $request->getOrigin()); $this->createStandardDeleteResponse($request, $response, $driverAttributeValueL11n); diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php index 06285ab..bb9249f 100644 --- a/Controller/ApiDriverController.php +++ b/Controller/ApiDriverController.php @@ -70,7 +70,7 @@ final class ApiDriverController extends Controller return; } - /** @var \Modules\FleetManagement\Models\DriverInspection $inspection */ + /** @var Inspection $inspection */ $inspection = $this->createInspectionFromRequest($request); $this->createModel($request->header->account, $inspection, DriverInspectionMapper::class, 'inspection', $request->getOrigin()); $this->createStandardCreateResponse($request, $response, $inspection); @@ -90,7 +90,7 @@ final class ApiDriverController extends Controller $inspection = new Inspection(); $inspection->reference = (int) $request->getData('ref'); $inspection->description = $request->getDataString('description') ?? ''; - $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; + $inspection->status = $request->getDataInt('status') ?? InspectionStatus::TODO; $inspection->next = $request->getDataDateTime('next') ?? null; $inspection->date = $request->getDataDateTime('date') ?? null; $inspection->interval = $request->getDataInt('interval') ?? 0; diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php index 773d641..d8871c7 100644 --- a/Controller/ApiVehicleAttributeController.php +++ b/Controller/ApiVehicleAttributeController.php @@ -327,7 +327,7 @@ final class ApiVehicleAttributeController extends Controller return; } - /** @var \Modules\FleetManagement\Models\VehicleAttributeTypeL11n $vehicleAttributeTypeL11n */ + /** @var BaseStringL11n $vehicleAttributeTypeL11n */ $vehicleAttributeTypeL11n = VehicleAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); $this->deleteModel($request->header->account, $vehicleAttributeTypeL11n, VehicleAttributeTypeL11nMapper::class, 'vehicle_attribute_type_l11n', $request->getOrigin()); $this->createStandardDeleteResponse($request, $response, $vehicleAttributeTypeL11n); @@ -387,7 +387,7 @@ final class ApiVehicleAttributeController extends Controller return; } - /** @var \Modules\FleetManagement\Models\VehicleAttributeType $vehicleAttributeType */ + /** @var AttributeType $vehicleAttributeType */ $vehicleAttributeType = VehicleAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); $this->deleteModel($request->header->account, $vehicleAttributeType, VehicleAttributeTypeMapper::class, 'vehicle_attribute_type', $request->getOrigin()); $this->createStandardDeleteResponse($request, $response, $vehicleAttributeType); @@ -418,7 +418,7 @@ final class ApiVehicleAttributeController extends Controller /** @var AttributeValue $old */ $old = VehicleAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); - /** @var \Modules\Attribute\Models\Attribute $type */ + /** @var \Modules\Attribute\Models\Attribute $attr */ $attr = VehicleAttributeMapper::get() ->with('type') ->where('id', $request->getDataInt('attribute') ?? 0) @@ -514,7 +514,7 @@ final class ApiVehicleAttributeController extends Controller return; } - /** @var \Modules\FleetManagement\Models\VehicleAttributeValueL11n $vehicleAttributeValueL11n */ + /** @var BaseStringL11n $vehicleAttributeValueL11n */ $vehicleAttributeValueL11n = VehicleAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); $this->deleteModel($request->header->account, $vehicleAttributeValueL11n, VehicleAttributeValueL11nMapper::class, 'vehicle_attribute_value_l11n', $request->getOrigin()); $this->createStandardDeleteResponse($request, $response, $vehicleAttributeValueL11n); diff --git a/Controller/ApiVehicleController.php b/Controller/ApiVehicleController.php index 489c24e..5fc3fe4 100755 --- a/Controller/ApiVehicleController.php +++ b/Controller/ApiVehicleController.php @@ -170,7 +170,7 @@ final class ApiVehicleController extends Controller $inspection = new Inspection(); $inspection->reference = (int) $request->getData('ref'); $inspection->description = $request->getDataString('description') ?? ''; - $inspection->status = (int) $request->getDataInt('status') ?? InspectionStatus::TODO; + $inspection->status = $request->getDataInt('status') ?? InspectionStatus::TODO; $inspection->next = $request->getDataDateTime('next') ?? null; $inspection->date = $request->getDataDateTime('date') ?? null; $inspection->interval = $request->getDataInt('interval') ?? 0; diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 82adfb0..0ea4d5e 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -386,8 +386,8 @@ final class BackendController extends Controller $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); - $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); - $view->data['driver-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['driver-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); return $view; } From c1b60fda880db305d60a8ee2377ae4cf012dfcd8 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 19 Sep 2023 17:16:01 +0000 Subject: [PATCH 41/89] fix value change log --- Controller/ApiDriverAttributeController.php | 4 +++- Controller/ApiVehicleAttributeController.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php index 959bd56..0831e78 100644 --- a/Controller/ApiDriverAttributeController.php +++ b/Controller/ApiDriverAttributeController.php @@ -231,7 +231,9 @@ final class ApiDriverAttributeController extends Controller $this->updateModel($request->header->account, $old, $new, DriverAttributeMapper::class, 'driver_attribute', $request->getOrigin()); - if ($new->value->getValue() !== $old->value->getValue()) { + if ($new->value->getValue() !== $old->value->getValue() + && $new->type->custom + ) { $this->updateModel($request->header->account, $old->value, $new->value, DriverAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); } diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php index d8871c7..1046c5b 100644 --- a/Controller/ApiVehicleAttributeController.php +++ b/Controller/ApiVehicleAttributeController.php @@ -231,7 +231,9 @@ final class ApiVehicleAttributeController extends Controller $this->updateModel($request->header->account, $old, $new, VehicleAttributeMapper::class, 'vehicle_attribute', $request->getOrigin()); - if ($new->value->getValue() !== $old->value->getValue()) { + if ($new->value->getValue() !== $old->value->getValue() + && $new->type->custom + ) { $this->updateModel($request->header->account, $old->value, $new->value, VehicleAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); } From f87aeb4aa9e9e67aa96f0b1bf02f01af4f3cf5f3 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 22 Sep 2023 13:56:28 +0000 Subject: [PATCH 42/89] fix tests --- .github/workflows/main.yml | 81 ++++++++++++++++++++------------------ tests/Bootstrap.php | 9 ++++- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7db49b1..e12c33f 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,49 +9,52 @@ jobs: strategy: fail-fast: false max-parallel: 3 + matrix: + php-versions: ['8.1'] steps: - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - name: Setup Composer - run: composer install - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - - name: Checkout Build Repository - uses: actions/checkout@main - with: + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + - name: Checkout Build Repository + uses: actions/checkout@main + with: fetch-depth: 1 ref: develop repository: Karaka-Management/Build path: Build - - name: Autoformat - run: | - 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes' - php vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ - vendor/bin/rector process --config Build/Config/rector.php ./ - - name: Check for modified files - id: git-check - run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) - - name: Push changes - if: steps.git-check.outputs.modified == 'true' - run: | - git config --global user.name 'Formatter Bot' - git config --global user.email 'formatter.bot@karaka.app' - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} - git commit -am "Automated formatting changes" - git push + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, bcmath, redis, memcached + ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 + - name: Get Composer Cache Directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + - name: Setup Composer + run: composer install + - name: Autoformat + run: | + vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes + vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ + - name: Check for modified files + id: git-check + run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) + - name: Push changes + if: steps.git-check.outputs.modified == 'true' + run: | + git config --global user.name 'Formatter Bot' + git config --global user.email 'formatter.bot@karaka.app' + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} + git commit -am "Automated formatting changes" + git push code-tests: runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'NO_CI')" @@ -232,6 +235,8 @@ jobs: run: composer install - name: phpcs run: vendor/bin/phpcs --severity=1 ./ --standard="Build/Config/phpcs.xml" -s --report=full + - name: rector + run: vendor/bin/rector process --dry-run --config Build/Config/rector.php ./ - name: Install NPM uses: actions/setup-node@v3 with: diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index 4d624b6..5193c0e 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -344,11 +344,18 @@ $GLOBALS['session'] = $httpSession; $GLOBALS['dbpool'] = new DatabasePool(); $GLOBALS['dbpool']->create('admin', $CONFIG['db']['core']['masters']['admin']); $GLOBALS['dbpool']->create('select', $CONFIG['db']['core']['masters']['select']); +$GLOBALS['dbpool']->create('insert', $CONFIG['db']['core']['masters']['insert']); $GLOBALS['dbpool']->create('update', $CONFIG['db']['core']['masters']['update']); $GLOBALS['dbpool']->create('delete', $CONFIG['db']['core']['masters']['delete']); -$GLOBALS['dbpool']->create('insert', $CONFIG['db']['core']['masters']['insert']); $GLOBALS['dbpool']->create('schema', $CONFIG['db']['core']['masters']['schema']); +$GLOBALS['dbpool']->get('admin')->connect(); +$GLOBALS['dbpool']->get('select')->connect(); +$GLOBALS['dbpool']->get('insert')->connect(); +$GLOBALS['dbpool']->get('update')->connect(); +$GLOBALS['dbpool']->get('delete')->connect(); +$GLOBALS['dbpool']->get('schema')->connect(); + DataMapperFactory::db($GLOBALS['dbpool']->get()); $GLOBALS['frameworkpath'] = '/phpOMS/'; From 3b5dbfb453f58d2b22eda1b284b8b01dba7905e1 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 22 Sep 2023 23:25:20 +0000 Subject: [PATCH 43/89] fix tests --- Models/Driver/NullDriverInspection.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Models/Driver/NullDriverInspection.php b/Models/Driver/NullDriverInspection.php index 2bd03e5..bda51a0 100644 --- a/Models/Driver/NullDriverInspection.php +++ b/Models/Driver/NullDriverInspection.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace Modules\FleetManagement\Models\Driver; +use Modules\FleetManagement\Models\Inspection; + /** * Null model * @@ -22,7 +24,7 @@ namespace Modules\FleetManagement\Models\Driver; * @link https://jingga.app * @since 1.0.0 */ -final class NullDriverInspection extends DriverInspection +final class NullDriverInspection extends Inspection { /** * Constructor From 412450a4e7e29ae4acbcd93952b27e3c7e617bfe Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 23 Sep 2023 00:56:21 +0000 Subject: [PATCH 44/89] fix permission interface changes --- tests/Controller/ApiControllerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index ab64e9a..ce5c095 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -68,8 +68,8 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase TestUtils::setMember($account, 'id', 1); $permission = new AccountPermission(); - $permission->setUnit(1); - $permission->setApp(2); + $permission->unit = 1; + $permission->app = 2; $permission->setPermission( PermissionType::READ | PermissionType::CREATE From d8efc9b1abdfb429d68e9ae2c6c9845907527774 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 23 Sep 2023 15:51:58 +0000 Subject: [PATCH 45/89] test fixes --- Theme/Backend/Lang/de.lang.php | 141 +++++++-------------------------- 1 file changed, 30 insertions(+), 111 deletions(-) diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php index 663897b..efece01 100755 --- a/Theme/Backend/Lang/de.lang.php +++ b/Theme/Backend/Lang/de.lang.php @@ -12,115 +12,34 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ - 'Accounting' => 'Buchhaltung', - 'Addition' => 'Zusatz', - 'Address' => 'Adresse', - 'Addresses' => 'Adressen', - 'Africa' => '#VALUE!', - 'AllCustomers' => '#VALUE!', - 'America' => '#VALUE!', - 'Analyse' => '#VALUE!', - 'AreaManager' => 'Bereichsleiter', - 'Articlegroup' => 'ArtikelGroup.', - 'Articles' => 'Artikel', - 'Asia' => '#VALUE!', - 'Attribute' => '#VALUE!', - 'Attributes' => '#VALUE!', - 'Balance' => 'Gleichgewicht', - 'BaseTime' => '#VALUE!', - 'Bills' => '#VALUE!', - 'Bonus' => 'Bonus', - 'Business' => 'Geschäft', - 'CIS' => '#VALUE!', - 'CLV' => 'CLV', - 'Calendar' => 'Kalender', - 'City' => 'Stadt', - 'Client' => 'Klient', - 'ClientID' => '#VALUE!', - 'Clients' => 'Kunden', - 'ComparisonTime' => '#VALUE!', - 'Contact' => 'Kontakt', - 'Country' => 'Land', - 'Created' => 'Erstellt', - 'CreatedAt' => '#VALUE!', - 'CreditRating' => 'Kreditbeurteilung', - 'Creditcard' => 'Kreditkarte', - 'Customers' => '#VALUE!', - 'DSO' => 'DSO.', - 'Date' => 'Datum', - 'Default' => 'Standard', - 'Delivery' => 'Die Zustellung', - 'Discount' => 'Rabatt', - 'DiscountBonus' => '#VALUE!', - 'DiscountP' => 'Rabatt %', - 'Documents' => 'Unterlagen', - 'Due' => 'Fällig', - 'Email' => 'Email', - 'Europe' => '#VALUE!', - 'Fax' => 'Fax', - 'Files' => 'Dateien', - 'Filter' => 'Filter', - 'Freightage' => 'Fracht', - 'Group' => 'Gruppe', - 'ID' => 'ICH WÜRDE', - 'Info' => 'Die Info', - 'Invoice' => 'Rechnung', - 'Invoices' => 'Rechnungen', - 'IsDefault' => 'Ist standardmäßig?', - 'Items' => '#VALUE!', - 'LastContact' => 'Letzter Kontakt', - 'LastOrder' => 'Letzte Bestellung', - 'Log' => 'Protokoll', - 'Logs' => 'Protokoll', - 'LostCustomers' => '#VALUE!', - 'MRR' => 'Mrr.', - 'MTDSales' => 'MTD-Verkäufe.', - 'Margin' => 'Rand', - 'Messages' => 'Mitteilungen', - 'Modified' => 'Geändert', - 'Modules' => 'Module', - 'Name' => 'Name', - 'Name1' => 'Name1.', - 'Name2' => 'Name2.', - 'Name3' => 'Name3.', - 'Net' => 'Netz', - 'NewCustomers' => '#VALUE!', - 'Notes' => 'Anmerkungen', - 'Number' => 'Nummer', - 'Office' => 'Sekretariat', - 'Other' => '#VALUE!', - 'Payment' => 'Zahlung', - 'PaymentTerm' => 'Zahlungsbezeichnung', - 'Permission' => 'Erlaubnis', - 'Phone' => 'Telefon', - 'Postal' => 'Post', - 'Price' => 'Preis', - 'Prices' => 'Preise', - 'Private' => 'Privatgelände', - 'Productgroup' => 'Produktgruppe', - 'Profile' => 'Profil', - 'Profit' => '#VALUE!', - 'Purchase' => 'Kaufen', - 'Quantity' => 'Menge', - 'RecentInvoices' => 'Jüngste Rechnungen', - 'Region' => '#VALUE!', - 'Rep' => '#VALUE!', - 'Retention' => '#VALUE!', - 'Sales' => 'Der Umsatz', - 'Segment' => 'Segment', - 'Segments' => 'Segmente', - 'Subtype' => 'Untertyp', - 'Support' => 'Unterstützung', - 'Tags' => 'Stichworte', - 'Title' => '#VALUE!', - 'Total' => '#VALUE!', - 'TotalPrice' => '#VALUE!', - 'Type' => 'Typ', - 'UnitPrice' => '#VALUE!', - 'Value' => '#VALUE!', - 'Website' => 'Webseite', - 'Wire' => 'Kabel', - 'YTDSales' => 'Ytd Sales.', - 'Zip' => 'Reißverschluss', +return ['FleetManagement' => [ + 'Vehicle' => 'Fahrzeug', + 'Vehicles' => 'Fahrzeuge', + 'Status' => 'Status', + 'Name' => 'Name', + 'Type' => 'Typ', + 'Make' => 'Marke', + 'Model' => 'Modell', + 'Start' => 'Start', + 'End' => 'Ende', + 'Profile' => 'Profile', + 'Attributes' => 'Attribute', + 'Files' => 'Dateien', + 'Notes' => 'Notizen', + 'Costs' => 'Kosten', + 'Inspections' => 'Inspektionen', + 'Drivers' => 'Fahrer', + 'Milage' => 'Tacho', + 'Driver' => 'Fahrer', + 'Vin' => 'Vin', + 'History' => 'Historie', + 'Upcoming' => 'Upcoming', + 'Responsible' => 'Verantwortlich', + 'Date' => 'Datum', + 'PurchasePrice' => 'Kaufpreis', + 'LeasingFee' => 'Leasingkosten', + ':status1' => 'Aktiv', + ':status2' => 'Inaktiv', + ':status3' => 'Beschädigt', + ':status4' => 'Außer Betrieb', ]]; From 13914471833033b7178ca7b7aea916f22b3a48a2 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 23 Sep 2023 23:05:19 +0000 Subject: [PATCH 46/89] fix language --- Theme/Backend/Lang/Navigation.ar.lang.php | 14 +- Theme/Backend/Lang/Navigation.cs.lang.php | 14 +- Theme/Backend/Lang/Navigation.da.lang.php | 14 +- Theme/Backend/Lang/Navigation.de.lang.php | 14 +- Theme/Backend/Lang/Navigation.el.lang.php | 14 +- Theme/Backend/Lang/Navigation.en.lang.php | 17 ++- Theme/Backend/Lang/Navigation.es.lang.php | 14 +- Theme/Backend/Lang/Navigation.fi.lang.php | 14 +- Theme/Backend/Lang/Navigation.fr.lang.php | 14 +- Theme/Backend/Lang/Navigation.hu.lang.php | 14 +- Theme/Backend/Lang/Navigation.it.lang.php | 14 +- Theme/Backend/Lang/Navigation.ja.lang.php | 14 +- Theme/Backend/Lang/Navigation.ko.lang.php | 14 +- Theme/Backend/Lang/Navigation.no.lang.php | 14 +- Theme/Backend/Lang/Navigation.pl.lang.php | 14 +- Theme/Backend/Lang/Navigation.pt.lang.php | 14 +- Theme/Backend/Lang/Navigation.ru.lang.php | 14 +- Theme/Backend/Lang/Navigation.sv.lang.php | 14 +- Theme/Backend/Lang/Navigation.th.lang.php | 14 +- Theme/Backend/Lang/Navigation.tr.lang.php | 14 +- Theme/Backend/Lang/Navigation.uk.lang.php | 14 +- Theme/Backend/Lang/Navigation.zh.lang.php | 14 +- Theme/Backend/Lang/ar.lang.php | 28 +++- Theme/Backend/Lang/cs.lang.php | 28 +++- Theme/Backend/Lang/da.lang.php | 28 +++- Theme/Backend/Lang/de.lang.php | 165 ++++++++++++++++++---- Theme/Backend/Lang/el.lang.php | 28 +++- Theme/Backend/Lang/en.lang.php | 165 ++++++++++++++++++---- Theme/Backend/Lang/es.lang.php | 28 +++- Theme/Backend/Lang/fi.lang.php | 28 +++- Theme/Backend/Lang/fr.lang.php | 28 +++- Theme/Backend/Lang/hu.lang.php | 28 +++- Theme/Backend/Lang/it.lang.php | 28 +++- Theme/Backend/Lang/ja.lang.php | 28 +++- Theme/Backend/Lang/ko.lang.php | 28 +++- Theme/Backend/Lang/no.lang.php | 28 +++- Theme/Backend/Lang/pl.lang.php | 28 +++- Theme/Backend/Lang/pt.lang.php | 28 +++- Theme/Backend/Lang/ru.lang.php | 28 +++- Theme/Backend/Lang/sv.lang.php | 28 +++- Theme/Backend/Lang/th.lang.php | 28 +++- Theme/Backend/Lang/tr.lang.php | 28 +++- Theme/Backend/Lang/uk.lang.php | 28 +++- Theme/Backend/Lang/zh.lang.php | 28 +++- 44 files changed, 1053 insertions(+), 148 deletions(-) diff --git a/Theme/Backend/Lang/Navigation.ar.lang.php b/Theme/Backend/Lang/Navigation.ar.lang.php index bd2df22..a5d8750 100755 --- a/Theme/Backend/Lang/Navigation.ar.lang.php +++ b/Theme/Backend/Lang/Navigation.ar.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'عميل', - 'Region' => 'منطقة', - 'SalesRep' => 'مندول المبيعات', + 'Client' => 'عميل', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'منطقة', + 'SalesRep' => 'مندول المبيعات', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.cs.lang.php b/Theme/Backend/Lang/Navigation.cs.lang.php index 068927b..30bec4e 100755 --- a/Theme/Backend/Lang/Navigation.cs.lang.php +++ b/Theme/Backend/Lang/Navigation.cs.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Klienta', - 'Region' => 'Kraj', - 'SalesRep' => 'Obchodní zástupce', + 'Client' => 'Klienta', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Kraj', + 'SalesRep' => 'Obchodní zástupce', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.da.lang.php b/Theme/Backend/Lang/Navigation.da.lang.php index 09be767..a94b956 100755 --- a/Theme/Backend/Lang/Navigation.da.lang.php +++ b/Theme/Backend/Lang/Navigation.da.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Klient', - 'Region' => 'Område', - 'SalesRep' => 'Salgsrepræsentant', + 'Client' => 'Klient', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Område', + 'SalesRep' => 'Salgsrepræsentant', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.de.lang.php b/Theme/Backend/Lang/Navigation.de.lang.php index eb72aa7..ce0694c 100755 --- a/Theme/Backend/Lang/Navigation.de.lang.php +++ b/Theme/Backend/Lang/Navigation.de.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Klient', - 'Region' => 'Region', - 'SalesRep' => 'VerkäufeRep', + 'Client' => 'Klient', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Region', + 'SalesRep' => 'VerkäufeRep', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.el.lang.php b/Theme/Backend/Lang/Navigation.el.lang.php index 630eab8..bea8d38 100755 --- a/Theme/Backend/Lang/Navigation.el.lang.php +++ b/Theme/Backend/Lang/Navigation.el.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Πελάτης', - 'Region' => 'Περιοχή', - 'SalesRep' => 'Αντιπρόσωπος Πωλήσεων', + 'Client' => 'Πελάτης', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Περιοχή', + 'SalesRep' => 'Αντιπρόσωπος Πωλήσεων', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index adab256..4997c05 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -13,12 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'FleetManagement' => 'Fleet Management', - 'Vehicles' => 'Vehicles', - 'Drivers' => 'Drivers', - 'Inspections' => 'Inspections', - 'VehicleInspectionTypes' => 'Vehicle Inspection Types', - 'DriverInspectionTypes' => 'Driver Inspection Types', - 'VehicleAttributes' => 'Vehicle Attributes', + 'Client' => '', 'DriverAttributes' => 'Driver Attributes', + 'DriverInspectionTypes' => 'Driver Inspection Types', + 'Drivers' => 'Drivers', + 'FleetManagement' => 'Fleet Management', + 'Inspections' => 'Inspections', + 'Region' => '', + 'SalesRep' => '', + 'VehicleAttributes' => 'Vehicle Attributes', + 'VehicleInspectionTypes' => 'Vehicle Inspection Types', + 'Vehicles' => 'Vehicles', ]]; diff --git a/Theme/Backend/Lang/Navigation.es.lang.php b/Theme/Backend/Lang/Navigation.es.lang.php index b992aa2..878f53b 100755 --- a/Theme/Backend/Lang/Navigation.es.lang.php +++ b/Theme/Backend/Lang/Navigation.es.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Cliente', - 'Region' => 'Región', - 'SalesRep' => 'Vendedores', + 'Client' => 'Cliente', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Región', + 'SalesRep' => 'Vendedores', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.fi.lang.php b/Theme/Backend/Lang/Navigation.fi.lang.php index 33837bd..09cb774 100755 --- a/Theme/Backend/Lang/Navigation.fi.lang.php +++ b/Theme/Backend/Lang/Navigation.fi.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Asiakas', - 'Region' => 'Alue', - 'SalesRep' => 'Myyntiedustaja', + 'Client' => 'Asiakas', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Alue', + 'SalesRep' => 'Myyntiedustaja', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.fr.lang.php b/Theme/Backend/Lang/Navigation.fr.lang.php index 5edee9b..2fd5b82 100755 --- a/Theme/Backend/Lang/Navigation.fr.lang.php +++ b/Theme/Backend/Lang/Navigation.fr.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Client', - 'Region' => 'Région', - 'SalesRep' => 'Représentant commercial', + 'Client' => 'Client', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Région', + 'SalesRep' => 'Représentant commercial', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.hu.lang.php b/Theme/Backend/Lang/Navigation.hu.lang.php index d25dd19..c7e7202 100755 --- a/Theme/Backend/Lang/Navigation.hu.lang.php +++ b/Theme/Backend/Lang/Navigation.hu.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Ügyfél', - 'Region' => 'Vidék', - 'SalesRep' => 'Értékesítés', + 'Client' => 'Ügyfél', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Vidék', + 'SalesRep' => 'Értékesítés', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.it.lang.php b/Theme/Backend/Lang/Navigation.it.lang.php index f9ee055..e26a884 100755 --- a/Theme/Backend/Lang/Navigation.it.lang.php +++ b/Theme/Backend/Lang/Navigation.it.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Cliente', - 'Region' => 'Regione', - 'SalesRep' => 'Rappresentante delle vendite', + 'Client' => 'Cliente', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Regione', + 'SalesRep' => 'Rappresentante delle vendite', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.ja.lang.php b/Theme/Backend/Lang/Navigation.ja.lang.php index 1997a4d..ca5ca08 100755 --- a/Theme/Backend/Lang/Navigation.ja.lang.php +++ b/Theme/Backend/Lang/Navigation.ja.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'クライアント', - 'Region' => '領域', - 'SalesRep' => 'セールスレート', + 'Client' => 'クライアント', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => '領域', + 'SalesRep' => 'セールスレート', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.ko.lang.php b/Theme/Backend/Lang/Navigation.ko.lang.php index 6acbc92..0c9b4e6 100755 --- a/Theme/Backend/Lang/Navigation.ko.lang.php +++ b/Theme/Backend/Lang/Navigation.ko.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => '고객', - 'Region' => '지역', - 'SalesRep' => '매출액', + 'Client' => '고객', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => '지역', + 'SalesRep' => '매출액', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.no.lang.php b/Theme/Backend/Lang/Navigation.no.lang.php index 8ba5a3e..e7e0b71 100755 --- a/Theme/Backend/Lang/Navigation.no.lang.php +++ b/Theme/Backend/Lang/Navigation.no.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Klient', - 'Region' => 'Region', - 'SalesRep' => 'SalesRep.', + 'Client' => 'Klient', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Region', + 'SalesRep' => 'SalesRep.', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.pl.lang.php b/Theme/Backend/Lang/Navigation.pl.lang.php index 161a0ba..4cb69a7 100755 --- a/Theme/Backend/Lang/Navigation.pl.lang.php +++ b/Theme/Backend/Lang/Navigation.pl.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Klient', - 'Region' => 'Region', - 'SalesRep' => 'Przedstawiciel handlowy', + 'Client' => 'Klient', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Region', + 'SalesRep' => 'Przedstawiciel handlowy', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.pt.lang.php b/Theme/Backend/Lang/Navigation.pt.lang.php index ccf216f..a77a9ae 100755 --- a/Theme/Backend/Lang/Navigation.pt.lang.php +++ b/Theme/Backend/Lang/Navigation.pt.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Cliente', - 'Region' => 'Região', - 'SalesRep' => 'Representante de vendas', + 'Client' => 'Cliente', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Região', + 'SalesRep' => 'Representante de vendas', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.ru.lang.php b/Theme/Backend/Lang/Navigation.ru.lang.php index 9d0988e..f48386f 100755 --- a/Theme/Backend/Lang/Navigation.ru.lang.php +++ b/Theme/Backend/Lang/Navigation.ru.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Клиент', - 'Region' => 'Область', - 'SalesRep' => 'Торговый представитель', + 'Client' => 'Клиент', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Область', + 'SalesRep' => 'Торговый представитель', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.sv.lang.php b/Theme/Backend/Lang/Navigation.sv.lang.php index b633b58..0852be9 100755 --- a/Theme/Backend/Lang/Navigation.sv.lang.php +++ b/Theme/Backend/Lang/Navigation.sv.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Klient', - 'Region' => 'Område', - 'SalesRep' => 'Säljare', + 'Client' => 'Klient', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Område', + 'SalesRep' => 'Säljare', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.th.lang.php b/Theme/Backend/Lang/Navigation.th.lang.php index 96a42d5..9586a16 100755 --- a/Theme/Backend/Lang/Navigation.th.lang.php +++ b/Theme/Backend/Lang/Navigation.th.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'ลูกค้า', - 'Region' => 'ภูมิภาค', - 'SalesRep' => 'ตัวแทนฝ่ายขาย', + 'Client' => 'ลูกค้า', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'ภูมิภาค', + 'SalesRep' => 'ตัวแทนฝ่ายขาย', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.tr.lang.php b/Theme/Backend/Lang/Navigation.tr.lang.php index 5696fe8..b07419c 100755 --- a/Theme/Backend/Lang/Navigation.tr.lang.php +++ b/Theme/Backend/Lang/Navigation.tr.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Müşteri', - 'Region' => 'Bölge', - 'SalesRep' => 'Satıcı', + 'Client' => 'Müşteri', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Bölge', + 'SalesRep' => 'Satıcı', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.uk.lang.php b/Theme/Backend/Lang/Navigation.uk.lang.php index 11d03c0..cfb55b1 100755 --- a/Theme/Backend/Lang/Navigation.uk.lang.php +++ b/Theme/Backend/Lang/Navigation.uk.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => 'Клієнт', - 'Region' => 'Регіон', - 'SalesRep' => 'Торговий представник', + 'Client' => 'Клієнт', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => 'Регіон', + 'SalesRep' => 'Торговий представник', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/Navigation.zh.lang.php b/Theme/Backend/Lang/Navigation.zh.lang.php index 2a5b68b..e36b980 100755 --- a/Theme/Backend/Lang/Navigation.zh.lang.php +++ b/Theme/Backend/Lang/Navigation.zh.lang.php @@ -13,7 +13,15 @@ declare(strict_types=1); return ['Navigation' => [ - 'Client' => '客户', - 'Region' => '地区', - 'SalesRep' => '销售代表', + 'Client' => '客户', + 'DriverAttributes' => '', + 'DriverInspectionTypes' => '', + 'Drivers' => '', + 'FleetManagement' => '', + 'Inspections' => '', + 'Region' => '地区', + 'SalesRep' => '销售代表', + 'VehicleAttributes' => '', + 'VehicleInspectionTypes' => '', + 'Vehicles' => '', ]]; diff --git a/Theme/Backend/Lang/ar.lang.php b/Theme/Backend/Lang/ar.lang.php index 0854684..c6543d0 100755 --- a/Theme/Backend/Lang/ar.lang.php +++ b/Theme/Backend/Lang/ar.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'محاسبة', 'Addition' => 'إضافة', 'Address' => 'تبوك', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'عملاء', 'ComparisonTime' => '#VALUE!', 'Contact' => 'اتصل', + 'Costs' => '', 'Country' => 'دولة', 'Created' => 'خلقت', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'تاريخ', 'Default' => 'تقصير', 'Delivery' => 'توصيل', + 'Description' => '', 'Discount' => 'خصم', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'خصم ٪', 'Documents' => 'وثائق', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'بسبب', 'Email' => 'بريد الالكتروني', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'فاكس', 'Files' => 'الملفات', 'Filter' => 'منقي', 'Freightage' => 'شحن', + 'From' => '', 'Group' => 'مجموعة', + 'History' => '', 'ID' => 'بطاقة تعريف', 'Info' => 'معلومات', + 'Inspections' => '', 'Invoice' => 'فاتورة', 'Invoices' => 'الفواتير', 'IsDefault' => 'افتراضي؟', 'Items' => '#VALUE!', 'LastContact' => 'آخر اتصال', 'LastOrder' => 'آخر طلب', + 'LeasingFee' => '', 'Log' => 'سجل', 'Logs' => 'السجلات', 'LostCustomers' => '#VALUE!', 'MRR' => 'مرر', 'MTDSales' => 'مبيعات MTD', + 'Make' => '', 'Margin' => 'هامش', 'Messages' => 'رسائل', + 'Milage' => '', + 'Model' => '', 'Modified' => 'تم التعديل', 'Modules' => 'وحدات', 'Name' => 'اسم', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'الملف الشخصي', 'Profit' => '#VALUE!', 'Purchase' => 'شراء', + 'PurchasePrice' => '', 'Quantity' => 'كمية', 'RecentInvoices' => 'الفواتير الأخيرة', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'مبيعات', 'Segment' => 'قطعة', 'Segments' => 'شرائح', + 'Start' => '', + 'Status' => '', 'Subtype' => 'النوع الفرعي', 'Support' => 'يدعم', 'Tags' => 'كذا', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'نوع', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'موقع إلكتروني', 'Wire' => 'الأسلاك', 'YTDSales' => 'مبيعات YTD', diff --git a/Theme/Backend/Lang/cs.lang.php b/Theme/Backend/Lang/cs.lang.php index dc45264..1459f6a 100755 --- a/Theme/Backend/Lang/cs.lang.php +++ b/Theme/Backend/Lang/cs.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Účetnictví', 'Addition' => 'Přidání', 'Address' => 'Adresa', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Klienti', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Kontakt', + 'Costs' => '', 'Country' => 'Země', 'Created' => 'Vytvořený', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'datum', 'Default' => 'Výchozí hodnota', 'Delivery' => 'dodávka', + 'Description' => '', 'Discount' => 'Sleva', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Sleva%', 'Documents' => 'Dokumenty', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Způsoben', 'Email' => 'E-mailem', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'Soubory', 'Filter' => 'Filtr', 'Freightage' => 'Dopravné', + 'From' => '', 'Group' => 'Skupina', + 'History' => '', 'ID' => 'ID.', 'Info' => 'Info.', + 'Inspections' => '', 'Invoice' => 'Faktura', 'Invoices' => 'Faktury', 'IsDefault' => 'Je výchozí?', 'Items' => '#VALUE!', 'LastContact' => 'Poslední kontakt', 'LastOrder' => 'Poslední objednávka', + 'LeasingFee' => '', 'Log' => 'Log', 'Logs' => 'Protokoly', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr.', 'MTDSales' => 'Prodej MTD.', + 'Make' => '', 'Margin' => 'Okraj', 'Messages' => 'Zprávy', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Upravený', 'Modules' => 'Moduly', 'Name' => 'název', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Nákup', + 'PurchasePrice' => '', 'Quantity' => 'Množství', 'RecentInvoices' => 'Nedávné faktury', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Odbyt', 'Segment' => 'Segment', 'Segments' => 'Segmenty', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Podtyp', 'Support' => 'Podpěra, podpora', 'Tags' => 'Tagy', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Typ', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'webová stránka', 'Wire' => 'Drát', 'YTDSales' => 'Prodej YTD.', diff --git a/Theme/Backend/Lang/da.lang.php b/Theme/Backend/Lang/da.lang.php index dffcaac..de2249f 100755 --- a/Theme/Backend/Lang/da.lang.php +++ b/Theme/Backend/Lang/da.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Regnskab', 'Addition' => 'Tilsætning', 'Address' => 'Adresse', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Klienter.', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Kontakt', + 'Costs' => '', 'Country' => 'Land', 'Created' => 'Oprettet', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Dato', 'Default' => 'Standard', 'Delivery' => 'Levering', + 'Description' => '', 'Discount' => 'Rabat', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Rabat%', 'Documents' => 'Dokumenter', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'På grund', 'Email' => 'Email.', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'Filer.', 'Filter' => 'Filter', 'Freightage' => 'Gods', + 'From' => '', 'Group' => 'Gruppe', + 'History' => '', 'ID' => 'ID.', 'Info' => 'Info.', + 'Inspections' => '', 'Invoice' => 'Faktura', 'Invoices' => 'Fakturaer.', 'IsDefault' => 'Er standard?', 'Items' => '#VALUE!', 'LastContact' => 'Sidste kontakt', 'LastOrder' => 'Sidste ordre', + 'LeasingFee' => '', 'Log' => 'Log', 'Logs' => 'Logs.', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR.', 'MTDSales' => 'MTD Sales.', + 'Make' => '', 'Margin' => 'Margin.', 'Messages' => 'Beskeder', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Modificeret', 'Modules' => 'Moduler.', 'Name' => 'Navn', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Køb', + 'PurchasePrice' => '', 'Quantity' => 'Antal', 'RecentInvoices' => 'Nylige fakturaer.', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'SALG', 'Segment' => 'Segment', 'Segments' => 'Segmenter.', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Subtype.', 'Support' => 'Support', 'Tags' => 'Tags.', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Type', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Internet side', 'Wire' => 'Tråd', 'YTDSales' => 'YTD SALG', diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php index efece01..5e81bad 100755 --- a/Theme/Backend/Lang/de.lang.php +++ b/Theme/Backend/Lang/de.lang.php @@ -13,33 +13,140 @@ declare(strict_types=1); return ['FleetManagement' => [ - 'Vehicle' => 'Fahrzeug', - 'Vehicles' => 'Fahrzeuge', - 'Status' => 'Status', - 'Name' => 'Name', - 'Type' => 'Typ', - 'Make' => 'Marke', - 'Model' => 'Modell', - 'Start' => 'Start', - 'End' => 'Ende', - 'Profile' => 'Profile', - 'Attributes' => 'Attribute', - 'Files' => 'Dateien', - 'Notes' => 'Notizen', - 'Costs' => 'Kosten', - 'Inspections' => 'Inspektionen', - 'Drivers' => 'Fahrer', - 'Milage' => 'Tacho', - 'Driver' => 'Fahrer', - 'Vin' => 'Vin', - 'History' => 'Historie', - 'Upcoming' => 'Upcoming', - 'Responsible' => 'Verantwortlich', - 'Date' => 'Datum', - 'PurchasePrice' => 'Kaufpreis', - 'LeasingFee' => 'Leasingkosten', - ':status1' => 'Aktiv', - ':status2' => 'Inaktiv', - ':status3' => 'Beschädigt', - ':status4' => 'Außer Betrieb', + ':status1' => 'Aktiv', + ':status2' => 'Inaktiv', + ':status3' => 'Beschädigt', + ':status4' => 'Außer Betrieb', + 'Accounting' => '', + 'Addition' => '', + 'Address' => '', + 'Addresses' => '', + 'Africa' => '', + 'AllCustomers' => '', + 'America' => '', + 'Analyse' => '', + 'AreaManager' => '', + 'Articlegroup' => '', + 'Articles' => '', + 'Asia' => '', + 'Attribute' => '', + 'Attributes' => 'Attribute', + 'Balance' => '', + 'BaseTime' => '', + 'Bills' => '', + 'Bonus' => '', + 'Business' => '', + 'CIS' => '', + 'CLV' => '', + 'Calendar' => '', + 'City' => '', + 'Client' => '', + 'ClientID' => '', + 'Clients' => '', + 'ComparisonTime' => '', + 'Contact' => '', + 'Costs' => 'Kosten', + 'Country' => '', + 'Created' => '', + 'CreatedAt' => '', + 'CreditRating' => '', + 'Creditcard' => '', + 'Customers' => '', + 'DSO' => '', + 'Date' => 'Datum', + 'Default' => '', + 'Delivery' => '', + 'Description' => '', + 'Discount' => '', + 'DiscountBonus' => '', + 'DiscountP' => '', + 'Documents' => '', + 'Driver' => 'Fahrer', + 'Drivers' => 'Fahrer', + 'Due' => '', + 'Email' => '', + 'End' => 'Ende', + 'Europe' => '', + 'Fax' => '', + 'Files' => 'Dateien', + 'Filter' => '', + 'Freightage' => '', + 'From' => '', + 'Group' => '', + 'History' => 'Historie', + 'ID' => '', + 'Info' => '', + 'Inspections' => 'Inspektionen', + 'Invoice' => '', + 'Invoices' => '', + 'IsDefault' => '', + 'Items' => '', + 'LastContact' => '', + 'LastOrder' => '', + 'LeasingFee' => 'Leasingkosten', + 'Log' => '', + 'Logs' => '', + 'LostCustomers' => '', + 'MRR' => '', + 'MTDSales' => '', + 'Make' => 'Marke', + 'Margin' => '', + 'Messages' => '', + 'Milage' => 'Tacho', + 'Model' => 'Modell', + 'Modified' => '', + 'Modules' => '', + 'Name' => 'Name', + 'Name1' => '', + 'Name2' => '', + 'Name3' => '', + 'Net' => '', + 'NewCustomers' => '', + 'Notes' => 'Notizen', + 'Number' => '', + 'Office' => '', + 'Other' => '', + 'Payment' => '', + 'PaymentTerm' => '', + 'Permission' => '', + 'Phone' => '', + 'Postal' => '', + 'Price' => '', + 'Prices' => '', + 'Private' => '', + 'Productgroup' => '', + 'Profile' => 'Profile', + 'Profit' => '', + 'Purchase' => '', + 'PurchasePrice' => 'Kaufpreis', + 'Quantity' => '', + 'RecentInvoices' => '', + 'Region' => '', + 'Rep' => '', + 'Responsible' => 'Verantwortlich', + 'Retention' => '', + 'Sales' => '', + 'Segment' => '', + 'Segments' => '', + 'Start' => 'Start', + 'Status' => 'Status', + 'Subtype' => '', + 'Support' => '', + 'Tags' => '', + 'Title' => '', + 'To' => '', + 'Total' => '', + 'TotalPrice' => '', + 'Type' => 'Typ', + 'UnitPrice' => '', + 'Upcoming' => 'Upcoming', + 'VIN' => '', + 'Value' => '', + 'Vehicle' => 'Fahrzeug', + 'Vehicles' => 'Fahrzeuge', + 'Vin' => 'Vin', + 'Website' => '', + 'Wire' => '', + 'YTDSales' => '', + 'Zip' => '', ]]; diff --git a/Theme/Backend/Lang/el.lang.php b/Theme/Backend/Lang/el.lang.php index 2e2659e..61d52ec 100755 --- a/Theme/Backend/Lang/el.lang.php +++ b/Theme/Backend/Lang/el.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Λογιστική', 'Addition' => 'Πρόσθεση', 'Address' => 'Διεύθυνση', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Πελάτες', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Επικοινωνία', + 'Costs' => '', 'Country' => 'Χώρα', 'Created' => 'Δημιουργήθηκε', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Ημερομηνία', 'Default' => 'Προκαθορισμένο', 'Delivery' => 'Διανομή', + 'Description' => '', 'Discount' => 'Εκπτωση', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Έκπτωση%', 'Documents' => 'Εγγραφα', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Λόγω', 'Email' => 'ΗΛΕΚΤΡΟΝΙΚΗ ΔΙΕΥΘΥΝΣΗ', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Φαξ', 'Files' => 'Αρχεία', 'Filter' => 'Φίλτρο', 'Freightage' => 'Ναύλος', + 'From' => '', 'Group' => 'Ομάδα', + 'History' => '', 'ID' => 'ταυτότητα', 'Info' => 'Πληροφορία', + 'Inspections' => '', 'Invoice' => 'Τιμολόγιο', 'Invoices' => 'Τιμολόγια', 'IsDefault' => 'Είναι προεπιλογή;', 'Items' => '#VALUE!', 'LastContact' => 'Τελευταία επαφή', 'LastOrder' => 'Τελευταία παραγγελία', + 'LeasingFee' => '', 'Log' => 'Κούτσουρο', 'Logs' => 'Κούτσουρα', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR', 'MTDSales' => 'Πωλήσεις MTD', + 'Make' => '', 'Margin' => 'Περιθώριο', 'Messages' => 'Μηνύματα', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Τροποποιημένος', 'Modules' => 'Ενότητες', 'Name' => 'Ονομα', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Προφίλ', 'Profit' => '#VALUE!', 'Purchase' => 'Αγορά', + 'PurchasePrice' => '', 'Quantity' => 'Ποσότητα', 'RecentInvoices' => 'Πρόσφατα τιμολόγια', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Εκπτώσεις', 'Segment' => 'Τμήμα', 'Segments' => 'Τμήματα', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Υποτύπωμα', 'Support' => 'Υποστήριξη', 'Tags' => 'Ετικέτες', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Τύπος', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Δικτυακός τόπος', 'Wire' => 'Σύρμα', 'YTDSales' => 'Ytd πωλήσεις', diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 889cdf7..0e838b0 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -13,33 +13,140 @@ declare(strict_types=1); return ['FleetManagement' => [ - 'Vehicle' => 'Vehicle', - 'Vehicles' => 'Vehicles', - 'Status' => 'Status', - 'Name' => 'Name', - 'Type' => 'Type', - 'Make' => 'Make', - 'Model' => 'Model', - 'Start' => 'Start', - 'End' => 'End', - 'Profile' => 'Profile', - 'Attributes' => 'Attributes', - 'Files' => 'Files', - 'Notes' => 'Notes', - 'Costs' => 'Costs', - 'Inspections' => 'Inspections', - 'Drivers' => 'Drivers', - 'Milage' => 'Milage', - 'Driver' => 'Driver', - 'Vin' => 'Vin', - 'History' => 'History', - 'Upcoming' => 'Upcoming', - 'Responsible' => 'Responsible', - 'Date' => 'Date', - 'PurchasePrice' => 'Purchase Price', - 'LeasingFee' => 'Leasing Fee', - ':status1' => 'Active', - ':status2' => 'Inactive', - ':status3' => 'Damaged', - ':status4' => 'Out of order', + ':status1' => 'Active', + ':status2' => 'Inactive', + ':status3' => 'Damaged', + ':status4' => 'Out of order', + 'Accounting' => '', + 'Addition' => '', + 'Address' => '', + 'Addresses' => '', + 'Africa' => '', + 'AllCustomers' => '', + 'America' => '', + 'Analyse' => '', + 'AreaManager' => '', + 'Articlegroup' => '', + 'Articles' => '', + 'Asia' => '', + 'Attribute' => '', + 'Attributes' => 'Attributes', + 'Balance' => '', + 'BaseTime' => '', + 'Bills' => '', + 'Bonus' => '', + 'Business' => '', + 'CIS' => '', + 'CLV' => '', + 'Calendar' => '', + 'City' => '', + 'Client' => '', + 'ClientID' => '', + 'Clients' => '', + 'ComparisonTime' => '', + 'Contact' => '', + 'Costs' => 'Costs', + 'Country' => '', + 'Created' => '', + 'CreatedAt' => '', + 'CreditRating' => '', + 'Creditcard' => '', + 'Customers' => '', + 'DSO' => '', + 'Date' => 'Date', + 'Default' => '', + 'Delivery' => '', + 'Description' => '', + 'Discount' => '', + 'DiscountBonus' => '', + 'DiscountP' => '', + 'Documents' => '', + 'Driver' => 'Driver', + 'Drivers' => 'Drivers', + 'Due' => '', + 'Email' => '', + 'End' => 'End', + 'Europe' => '', + 'Fax' => '', + 'Files' => 'Files', + 'Filter' => '', + 'Freightage' => '', + 'From' => '', + 'Group' => '', + 'History' => 'History', + 'ID' => '', + 'Info' => '', + 'Inspections' => 'Inspections', + 'Invoice' => '', + 'Invoices' => '', + 'IsDefault' => '', + 'Items' => '', + 'LastContact' => '', + 'LastOrder' => '', + 'LeasingFee' => 'Leasing Fee', + 'Log' => '', + 'Logs' => '', + 'LostCustomers' => '', + 'MRR' => '', + 'MTDSales' => '', + 'Make' => 'Make', + 'Margin' => '', + 'Messages' => '', + 'Milage' => 'Milage', + 'Model' => 'Model', + 'Modified' => '', + 'Modules' => '', + 'Name' => 'Name', + 'Name1' => '', + 'Name2' => '', + 'Name3' => '', + 'Net' => '', + 'NewCustomers' => '', + 'Notes' => 'Notes', + 'Number' => '', + 'Office' => '', + 'Other' => '', + 'Payment' => '', + 'PaymentTerm' => '', + 'Permission' => '', + 'Phone' => '', + 'Postal' => '', + 'Price' => '', + 'Prices' => '', + 'Private' => '', + 'Productgroup' => '', + 'Profile' => 'Profile', + 'Profit' => '', + 'Purchase' => '', + 'PurchasePrice' => 'Purchase Price', + 'Quantity' => '', + 'RecentInvoices' => '', + 'Region' => '', + 'Rep' => '', + 'Responsible' => 'Responsible', + 'Retention' => '', + 'Sales' => '', + 'Segment' => '', + 'Segments' => '', + 'Start' => 'Start', + 'Status' => 'Status', + 'Subtype' => '', + 'Support' => '', + 'Tags' => '', + 'Title' => '', + 'To' => '', + 'Total' => '', + 'TotalPrice' => '', + 'Type' => 'Type', + 'UnitPrice' => '', + 'Upcoming' => 'Upcoming', + 'VIN' => '', + 'Value' => '', + 'Vehicle' => 'Vehicle', + 'Vehicles' => 'Vehicles', + 'Vin' => 'Vin', + 'Website' => '', + 'Wire' => '', + 'YTDSales' => '', + 'Zip' => '', ]]; diff --git a/Theme/Backend/Lang/es.lang.php b/Theme/Backend/Lang/es.lang.php index 71bc5c9..f842008 100755 --- a/Theme/Backend/Lang/es.lang.php +++ b/Theme/Backend/Lang/es.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Contabilidad', 'Addition' => 'Adición', 'Address' => 'Habla a', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Clientela', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Contacto', + 'Costs' => '', 'Country' => 'País', 'Created' => 'Creado', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Fecha', 'Default' => 'Defecto', 'Delivery' => 'Entrega', + 'Description' => '', 'Discount' => 'Descuento', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Descuento%', 'Documents' => 'Documentos', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Vencer', 'Email' => 'Correo electrónico', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'Archivos', 'Filter' => 'Filtrar', 'Freightage' => 'Flete', + 'From' => '', 'Group' => 'Grupo', + 'History' => '', 'ID' => 'IDENTIFICACIÓN', 'Info' => 'Información', + 'Inspections' => '', 'Invoice' => 'Factura', 'Invoices' => 'Facturas', 'IsDefault' => 'Es por defecto?', 'Items' => '#VALUE!', 'LastContact' => 'Último contacto', 'LastOrder' => 'Último pedido', + 'LeasingFee' => '', 'Log' => 'Tronco', 'Logs' => 'Registros', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr', 'MTDSales' => 'Ventas MTD', + 'Make' => '', 'Margin' => 'Margen', 'Messages' => 'Mensajes', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Modificado', 'Modules' => 'Módulos', 'Name' => 'Nombre', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Perfil', 'Profit' => '#VALUE!', 'Purchase' => 'Compra', + 'PurchasePrice' => '', 'Quantity' => 'Cantidad', 'RecentInvoices' => 'Facturas recientes', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Ventas', 'Segment' => 'Segmento', 'Segments' => 'Segmentos', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Subtipo', 'Support' => 'Apoyo', 'Tags' => 'Etiquetas', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Escribe', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Sitio web', 'Wire' => 'Cable', 'YTDSales' => 'Ytd ventas', diff --git a/Theme/Backend/Lang/fi.lang.php b/Theme/Backend/Lang/fi.lang.php index 8b53212..48a170e 100755 --- a/Theme/Backend/Lang/fi.lang.php +++ b/Theme/Backend/Lang/fi.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Kirjanpito', 'Addition' => 'Lisäys', 'Address' => 'Osoite', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Asiakkaat', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Ottaa yhteyttä', + 'Costs' => '', 'Country' => 'Maa', 'Created' => 'Luotu', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Päivämäärä', 'Default' => 'Oletusarvo', 'Delivery' => 'Toimitus', + 'Description' => '', 'Discount' => 'Alennus', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Alennus %', 'Documents' => 'Asiakirjat', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Takia', 'Email' => 'Sähköposti', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Faksi', 'Files' => 'Tiedostot', 'Filter' => 'Suodattaa', 'Freightage' => 'Rahti', + 'From' => '', 'Group' => 'Ryhmä', + 'History' => '', 'ID' => 'Id', 'Info' => 'Tiedot', + 'Inspections' => '', 'Invoice' => 'Lasku', 'Invoices' => 'Laskut', 'IsDefault' => 'On oletusarvo?', 'Items' => '#VALUE!', 'LastContact' => 'Viimeinen yhteystieto', 'LastOrder' => 'Viimeinen tilaus', + 'LeasingFee' => '', 'Log' => 'Hirsi', 'Logs' => 'Lokit', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr', 'MTDSales' => 'MTD-myynti', + 'Make' => '', 'Margin' => 'Marginaali', 'Messages' => 'Viestit', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Muokattu', 'Modules' => 'Moduulit', 'Name' => 'Nimi', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profiili', 'Profit' => '#VALUE!', 'Purchase' => 'Ostaa', + 'PurchasePrice' => '', 'Quantity' => 'Määrä', 'RecentInvoices' => 'Viimeaikaiset laskut', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Myynti', 'Segment' => 'Segmentti', 'Segments' => 'Segmentit', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Alatyyppi', 'Support' => 'Tuki', 'Tags' => 'Tunnisteet', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Tyyppi', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Verkkosivusto', 'Wire' => 'Lanka', 'YTDSales' => 'YTD-myynti', diff --git a/Theme/Backend/Lang/fr.lang.php b/Theme/Backend/Lang/fr.lang.php index 4e3da5b..01b1209 100755 --- a/Theme/Backend/Lang/fr.lang.php +++ b/Theme/Backend/Lang/fr.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Comptabilité', 'Addition' => 'Une addition', 'Address' => 'Adresse', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Clients', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Contact', + 'Costs' => '', 'Country' => 'Pays', 'Created' => 'Établi', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Date', 'Default' => 'Défaut', 'Delivery' => 'Livraison', + 'Description' => '', 'Discount' => 'Remise', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Remise %', 'Documents' => 'Documents', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Dû', 'Email' => 'E-mail', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'Des dossiers', 'Filter' => 'Filtre', 'Freightage' => 'Fret', + 'From' => '', 'Group' => 'Grouper', + 'History' => '', 'ID' => 'identifiant', 'Info' => 'Info', + 'Inspections' => '', 'Invoice' => 'Facture d\'achat', 'Invoices' => 'Factures', 'IsDefault' => 'Est par défaut?', 'Items' => '#VALUE!', 'LastContact' => 'Dernier contact', 'LastOrder' => 'Dernière commande', + 'LeasingFee' => '', 'Log' => 'Enregistrer', 'Logs' => 'Journaux', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr', 'MTDSales' => 'Ventes MTD', + 'Make' => '', 'Margin' => 'Marge', 'Messages' => 'messages', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Modifié', 'Modules' => 'Modules', 'Name' => 'Nom', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Acheter', + 'PurchasePrice' => '', 'Quantity' => 'Quantité', 'RecentInvoices' => 'Factures récentes', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Ventes', 'Segment' => 'Segment', 'Segments' => 'Segments', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Sous-type', 'Support' => 'Soutien', 'Tags' => 'Mots clés', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Taper', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Site Internet', 'Wire' => 'Fil', 'YTDSales' => 'Ventes YTD', diff --git a/Theme/Backend/Lang/hu.lang.php b/Theme/Backend/Lang/hu.lang.php index 05bc6b9..4c78940 100755 --- a/Theme/Backend/Lang/hu.lang.php +++ b/Theme/Backend/Lang/hu.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Könyvelés', 'Addition' => 'Kiegészítés', 'Address' => 'Cím', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Kliensek', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Kapcsolatba lépni', + 'Costs' => '', 'Country' => 'Ország', 'Created' => 'Létrehozott', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Dátum', 'Default' => 'Alapértelmezett', 'Delivery' => 'Szállítás', + 'Description' => '', 'Discount' => 'Kedvezmény', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Árengedmény%', 'Documents' => 'Dokumentumok', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Esedékes', 'Email' => 'Email', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'Fájlok', 'Filter' => 'Szűrő', 'Freightage' => 'Fuvardíj', + 'From' => '', 'Group' => 'Csoport', + 'History' => '', 'ID' => 'Idézés', 'Info' => 'Információ', + 'Inspections' => '', 'Invoice' => 'Számla', 'Invoices' => 'Számlák', 'IsDefault' => 'Alapértelmezett?', 'Items' => '#VALUE!', 'LastContact' => 'Utolsó kapcsolat', 'LastOrder' => 'Utolsó rendelés', + 'LeasingFee' => '', 'Log' => 'Napló', 'Logs' => 'Naplók', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr', 'MTDSales' => 'MTD értékesítés', + 'Make' => '', 'Margin' => 'Árrés', 'Messages' => 'üzenetek', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Módosított', 'Modules' => 'Modulok', 'Name' => 'Név', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Vásárlás', + 'PurchasePrice' => '', 'Quantity' => 'Mennyiség', 'RecentInvoices' => 'Legutóbbi számlák', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Értékesítés', 'Segment' => 'Szegmens', 'Segments' => 'Szegmensek', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Altípus', 'Support' => 'Támogatás', 'Tags' => 'Címkék', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'típus', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Weboldal', 'Wire' => 'Huzal', 'YTDSales' => 'YTD értékesítés', diff --git a/Theme/Backend/Lang/it.lang.php b/Theme/Backend/Lang/it.lang.php index 5ddc9ca..6eb9b3c 100755 --- a/Theme/Backend/Lang/it.lang.php +++ b/Theme/Backend/Lang/it.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Contabilità', 'Addition' => 'Aggiunta', 'Address' => 'Indirizzo', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Clienti', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Contatto', + 'Costs' => '', 'Country' => 'Nazione', 'Created' => 'Creato', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Data', 'Default' => 'Predefinito', 'Delivery' => 'Consegna', + 'Description' => '', 'Discount' => 'Sconto', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Sconto%', 'Documents' => 'Documenti', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Dovuto', 'Email' => 'E-mail', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'File', 'Filter' => 'Filtro', 'Freightage' => 'Liberare', + 'From' => '', 'Group' => 'Gruppo', + 'History' => '', 'ID' => 'ID', 'Info' => 'Informazioni', + 'Inspections' => '', 'Invoice' => 'Fattura', 'Invoices' => 'Fatture', 'IsDefault' => 'È predefinito?', 'Items' => '#VALUE!', 'LastContact' => 'Ultimo contatto', 'LastOrder' => 'Ultimo ordine', + 'LeasingFee' => '', 'Log' => 'Tronco d\'albero', 'Logs' => 'Logs.', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr.', 'MTDSales' => 'Vendite di mtd.', + 'Make' => '', 'Margin' => 'Margine', 'Messages' => 'Messaggi', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Modificati', 'Modules' => 'Moduli', 'Name' => 'Nome', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profilo', 'Profit' => '#VALUE!', 'Purchase' => 'Acquistare', + 'PurchasePrice' => '', 'Quantity' => 'Quantità', 'RecentInvoices' => 'Recenti fatture', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Saldi', 'Segment' => 'Segmento', 'Segments' => 'Segmenti', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Sottotipo', 'Support' => 'Supporto', 'Tags' => 'Tags.', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Tipo', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Sito web', 'Wire' => 'Filo', 'YTDSales' => 'Vendite di ytd.', diff --git a/Theme/Backend/Lang/ja.lang.php b/Theme/Backend/Lang/ja.lang.php index eaeeaf8..0eaa6c9 100755 --- a/Theme/Backend/Lang/ja.lang.php +++ b/Theme/Backend/Lang/ja.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => '会計', 'Addition' => '添加', 'Address' => '住所', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'クライアント', 'ComparisonTime' => '#VALUE!', 'Contact' => 'コンタクト', + 'Costs' => '', 'Country' => '国', 'Created' => '作成した', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => '日にち', 'Default' => 'ディフォルト', 'Delivery' => '配達', + 'Description' => '', 'Discount' => '割引', 'DiscountBonus' => '#VALUE!', 'DiscountP' => '割引 %', 'Documents' => '文書', + 'Driver' => '', + 'Drivers' => '', 'Due' => '期限', 'Email' => 'Eメール', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'ファックス', 'Files' => 'ファイル', 'Filter' => 'フィルター', 'Freightage' => 'fre fre', + 'From' => '', 'Group' => 'グループ', + 'History' => '', 'ID' => 'id', 'Info' => '情報', + 'Inspections' => '', 'Invoice' => '請求書', 'Invoices' => '請求書', 'IsDefault' => 'デフォルトですか?', 'Items' => '#VALUE!', 'LastContact' => '最後の連絡先', 'LastOrder' => '最後の順序', + 'LeasingFee' => '', 'Log' => 'ログ', 'Logs' => 'ログ', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR.', 'MTDSales' => 'MTDセールス', + 'Make' => '', 'Margin' => 'マージン', 'Messages' => 'メッセージ', + 'Milage' => '', + 'Model' => '', 'Modified' => '修正された', 'Modules' => 'モジュール', 'Name' => '名前', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'プロフィール', 'Profit' => '#VALUE!', 'Purchase' => '購入', + 'PurchasePrice' => '', 'Quantity' => '量', 'RecentInvoices' => '最近の請求書', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => '売り返り', 'Segment' => 'セグメント', 'Segments' => 'セグメント', + 'Start' => '', + 'Status' => '', 'Subtype' => 'サブタイプ', 'Support' => 'サポート', 'Tags' => 'タグ', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'タイプ', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Webサイト', 'Wire' => 'ワイヤー', 'YTDSales' => 'ytd売上高', diff --git a/Theme/Backend/Lang/ko.lang.php b/Theme/Backend/Lang/ko.lang.php index 6b77cc8..46ca9ee 100755 --- a/Theme/Backend/Lang/ko.lang.php +++ b/Theme/Backend/Lang/ko.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => '회계', 'Addition' => '덧셈', 'Address' => '주소', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => '클라이언트', 'ComparisonTime' => '#VALUE!', 'Contact' => '연락하다', + 'Costs' => '', 'Country' => '국가', 'Created' => '만들어진', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => '날짜', 'Default' => '기본', 'Delivery' => '배달', + 'Description' => '', 'Discount' => '할인', 'DiscountBonus' => '#VALUE!', 'DiscountP' => '할인 %', 'Documents' => '서류', + 'Driver' => '', + 'Drivers' => '', 'Due' => '로 인한', 'Email' => '이메일', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => '팩스', 'Files' => '파일', 'Filter' => '필터', 'Freightage' => '화물', + 'From' => '', 'Group' => '그룹', + 'History' => '', 'ID' => 'ID', 'Info' => '정보', + 'Inspections' => '', 'Invoice' => '송장', 'Invoices' => '송장', 'IsDefault' => '기본값은 무엇입니까?', 'Items' => '#VALUE!', 'LastContact' => '마지막 연락처', 'LastOrder' => '마지막 주문', + 'LeasingFee' => '', 'Log' => '통나무', 'Logs' => '로그인', 'LostCustomers' => '#VALUE!', 'MRR' => '부서', 'MTDSales' => 'MTD 판매', + 'Make' => '', 'Margin' => '여유', 'Messages' => '메시지', + 'Milage' => '', + 'Model' => '', 'Modified' => '수정', 'Modules' => '모듈', 'Name' => '이름', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => '프로필', 'Profit' => '#VALUE!', 'Purchase' => '구입', + 'PurchasePrice' => '', 'Quantity' => '수량', 'RecentInvoices' => '최근 송장', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => '매상', 'Segment' => '분절', 'Segments' => '세그먼트', + 'Start' => '', + 'Status' => '', 'Subtype' => '하위 유형', 'Support' => '지원하다', 'Tags' => '태그', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => '유형', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => '웹 사이트', 'Wire' => '철사', 'YTDSales' => 'YTD 판매', diff --git a/Theme/Backend/Lang/no.lang.php b/Theme/Backend/Lang/no.lang.php index 7390eaf..ebacbd6 100755 --- a/Theme/Backend/Lang/no.lang.php +++ b/Theme/Backend/Lang/no.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Regnskap', 'Addition' => 'Addisjon', 'Address' => 'Adresse', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Klienter', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Kontakt', + 'Costs' => '', 'Country' => 'Land', 'Created' => 'Opprettet', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Dato', 'Default' => 'Misligholde', 'Delivery' => 'Leveranse', + 'Description' => '', 'Discount' => 'Rabatt', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Rabatt%', 'Documents' => 'Dokumenter', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'På grunn av det', 'Email' => 'E-post', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Faks', 'Files' => 'Filer', 'Filter' => 'Filter', 'Freightage' => 'Frakt', + 'From' => '', 'Group' => 'Gruppe', + 'History' => '', 'ID' => 'Id.', 'Info' => 'Info.', + 'Inspections' => '', 'Invoice' => 'Faktura', 'Invoices' => 'Fakturaer', 'IsDefault' => 'Er standard?', 'Items' => '#VALUE!', 'LastContact' => 'Siste kontakt', 'LastOrder' => 'Siste bestilling', + 'LeasingFee' => '', 'Log' => 'Logg', 'Logs' => 'Tømmerstokker', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR.', 'MTDSales' => 'MTD-salg', + 'Make' => '', 'Margin' => 'Margin', 'Messages' => 'Meldinger', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Endret', 'Modules' => 'Moduler', 'Name' => 'Navn', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Kjøp', + 'PurchasePrice' => '', 'Quantity' => 'Mengde', 'RecentInvoices' => 'Nylige fakturaer', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Salg', 'Segment' => 'Segmentet', 'Segments' => 'Segmenter', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Subtype.', 'Support' => 'Brukerstøtte', 'Tags' => 'Tags.', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Type', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Nettside', 'Wire' => 'Metalltråd', 'YTDSales' => 'YTD-salg', diff --git a/Theme/Backend/Lang/pl.lang.php b/Theme/Backend/Lang/pl.lang.php index 97baadc..7e0d63a 100755 --- a/Theme/Backend/Lang/pl.lang.php +++ b/Theme/Backend/Lang/pl.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Rachunkowość', 'Addition' => 'Dodatek', 'Address' => 'Adres', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Klienci.', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Kontakt', + 'Costs' => '', 'Country' => 'Kraj', 'Created' => 'Utworzony', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Data', 'Default' => 'Domyślna', 'Delivery' => 'Dostawa', + 'Description' => '', 'Discount' => 'Zniżka', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Zniżka %', 'Documents' => 'Dokumenty', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Z powodu', 'Email' => 'E-mail', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Faks', 'Files' => 'Pliki', 'Filter' => 'Filtr', 'Freightage' => 'Frachtowanie', + 'From' => '', 'Group' => 'Grupa', + 'History' => '', 'ID' => 'ID', 'Info' => 'Info', + 'Inspections' => '', 'Invoice' => 'Faktura', 'Invoices' => 'Faktury', 'IsDefault' => 'Jest domyślnie?', 'Items' => '#VALUE!', 'LastContact' => 'Ostatni kontakt', 'LastOrder' => 'Ostatnie zamówienie', + 'LeasingFee' => '', 'Log' => 'Dziennik', 'Logs' => 'Kłody', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR.', 'MTDSales' => 'Sprzedaż MTD.', + 'Make' => '', 'Margin' => 'Margines', 'Messages' => 'Wiadomości', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Modyfikowany', 'Modules' => 'Moduły', 'Name' => 'Nazwa', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Zakup', + 'PurchasePrice' => '', 'Quantity' => 'Ilość', 'RecentInvoices' => 'Ostatnie faktury.', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Obroty', 'Segment' => 'Człon', 'Segments' => 'Segmenty', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Podtyp', 'Support' => 'Wsparcie', 'Tags' => 'Tagi.', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Rodzaj', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Stronie internetowej', 'Wire' => 'Drut', 'YTDSales' => 'Sprzedaż Ytd.', diff --git a/Theme/Backend/Lang/pt.lang.php b/Theme/Backend/Lang/pt.lang.php index ffb1b46..21b4391 100755 --- a/Theme/Backend/Lang/pt.lang.php +++ b/Theme/Backend/Lang/pt.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Contabilidade', 'Addition' => 'Adição', 'Address' => 'Endereço', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Clientes', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Contato', + 'Costs' => '', 'Country' => 'País', 'Created' => 'Criado', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Encontro', 'Default' => 'Padrão', 'Delivery' => 'Entrega', + 'Description' => '', 'Discount' => 'Desconto', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Desconto%', 'Documents' => 'Documentos', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Vencimento', 'Email' => 'E-mail', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'arquivos', 'Filter' => 'Filtro', 'Freightage' => 'Freightage', + 'From' => '', 'Group' => 'Grupo', + 'History' => '', 'ID' => 'identificação', 'Info' => 'Info', + 'Inspections' => '', 'Invoice' => 'Fatura', 'Invoices' => 'Faturas', 'IsDefault' => 'É padrão?', 'Items' => '#VALUE!', 'LastContact' => 'Último contato.', 'LastOrder' => 'Último pedido', + 'LeasingFee' => '', 'Log' => 'Registro', 'Logs' => 'Histórico', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR.', 'MTDSales' => 'Sales Mtd.', + 'Make' => '', 'Margin' => 'Margem', 'Messages' => 'Mensagens', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Modificado', 'Modules' => 'Módulos.', 'Name' => 'Nome', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Perfil', 'Profit' => '#VALUE!', 'Purchase' => 'Comprar', + 'PurchasePrice' => '', 'Quantity' => 'Quantidade', 'RecentInvoices' => 'Faturas recentes', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Vendas', 'Segment' => 'Segmento', 'Segments' => 'Segmentos', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Subtipo', 'Support' => 'Apoio, suporte', 'Tags' => 'Tag', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Modelo', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Local na rede Internet', 'Wire' => 'Fio', 'YTDSales' => 'Vendas do ano', diff --git a/Theme/Backend/Lang/ru.lang.php b/Theme/Backend/Lang/ru.lang.php index 83b11e5..4ec258f 100755 --- a/Theme/Backend/Lang/ru.lang.php +++ b/Theme/Backend/Lang/ru.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Учет', 'Addition' => 'Добавление', 'Address' => 'Адрес', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Клиенты', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Контакт', + 'Costs' => '', 'Country' => 'Страна', 'Created' => 'Созданный', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Дата', 'Default' => 'Дефолт', 'Delivery' => 'Доставка', + 'Description' => '', 'Discount' => 'Скидка', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Скидка %', 'Documents' => 'Документы', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Должное', 'Email' => 'Электронное письмо', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Факс', 'Files' => 'Файлы', 'Filter' => 'Фильтр', 'Freightage' => 'Фрахты', + 'From' => '', 'Group' => 'Группа', + 'History' => '', 'ID' => 'Я БЫ', 'Info' => 'Информация', + 'Inspections' => '', 'Invoice' => 'Счет', 'Invoices' => 'Счета', 'IsDefault' => 'По умолчанию?', 'Items' => '#VALUE!', 'LastContact' => 'Последний контакт', 'LastOrder' => 'Последний заказ', + 'LeasingFee' => '', 'Log' => 'Бревно', 'Logs' => 'Журналы', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR', 'MTDSales' => 'MTD Sales.', + 'Make' => '', 'Margin' => 'Допуск', 'Messages' => 'Сообщения', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Модифицированный', 'Modules' => 'Модули', 'Name' => 'Имя', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Профиль', 'Profit' => '#VALUE!', 'Purchase' => 'Покупка', + 'PurchasePrice' => '', 'Quantity' => 'Количество', 'RecentInvoices' => 'Недавние счета', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Продажи', 'Segment' => 'Сегмент', 'Segments' => 'Сегменты', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Подтип', 'Support' => 'Служба поддержки', 'Tags' => 'Теги', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Тип', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Веб-сайт', 'Wire' => 'Проволока', 'YTDSales' => 'YTD Sales.', diff --git a/Theme/Backend/Lang/sv.lang.php b/Theme/Backend/Lang/sv.lang.php index 83c9e20..eca57dc 100755 --- a/Theme/Backend/Lang/sv.lang.php +++ b/Theme/Backend/Lang/sv.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Bokföring', 'Addition' => 'Tillägg', 'Address' => 'Adress', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Klienter', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Kontakt', + 'Costs' => '', 'Country' => 'Land', 'Created' => 'Skapad', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Datum', 'Default' => 'Standard', 'Delivery' => 'Leverans', + 'Description' => '', 'Discount' => 'Rabatt', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Rabatt%', 'Documents' => 'Dokument', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'På grund av', 'Email' => 'E-post', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Fax', 'Files' => 'Filer', 'Filter' => 'Filtrera', 'Freightage' => 'Frakt', + 'From' => '', 'Group' => 'Grupp', + 'History' => '', 'ID' => 'Id', 'Info' => 'Info', + 'Inspections' => '', 'Invoice' => 'Faktura', 'Invoices' => 'Fakturor', 'IsDefault' => 'Är standard?', 'Items' => '#VALUE!', 'LastContact' => 'Senaste kontakten', 'LastOrder' => 'Sista beställningen', + 'LeasingFee' => '', 'Log' => 'Logga', 'Logs' => 'Loggar', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr', 'MTDSales' => 'MTD-försäljning', + 'Make' => '', 'Margin' => 'Marginal', 'Messages' => 'Budskap', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Ändrad', 'Modules' => 'Moduler', 'Name' => 'namn', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Inköp', + 'PurchasePrice' => '', 'Quantity' => 'Kvantitet', 'RecentInvoices' => 'Nya fakturor', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Försäljning', 'Segment' => 'Segmentet', 'Segments' => 'Segment', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Subtyp', 'Support' => 'Stöd', 'Tags' => 'Tagg', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Typ', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Hemsida', 'Wire' => 'Tråd', 'YTDSales' => 'YTD-försäljning', diff --git a/Theme/Backend/Lang/th.lang.php b/Theme/Backend/Lang/th.lang.php index c63cb99..52faf86 100755 --- a/Theme/Backend/Lang/th.lang.php +++ b/Theme/Backend/Lang/th.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'การบัญชี', 'Addition' => 'ส่วนที่เพิ่มเข้าไป', 'Address' => 'ที่อยู่', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'ลูกค้า', 'ComparisonTime' => '#VALUE!', 'Contact' => 'ติดต่อ', + 'Costs' => '', 'Country' => 'ประเทศ', 'Created' => 'สร้าง', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'วันที่', 'Default' => 'ค่าเริ่มต้น', 'Delivery' => 'จัดส่ง', + 'Description' => '', 'Discount' => 'การลดราคา', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'การลดราคา %', 'Documents' => 'เอกสาร', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'เนื่องจาก', 'Email' => 'อีเมล', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'แฟกซ์', 'Files' => 'ไฟล์', 'Filter' => 'กรอง', 'Freightage' => 'การขนส่งสินค้า', + 'From' => '', 'Group' => 'กลุ่ม', + 'History' => '', 'ID' => 'id', 'Info' => 'ข้อมูล', + 'Inspections' => '', 'Invoice' => 'ใบแจ้งหนี้', 'Invoices' => 'ใบแจ้งหนี้', 'IsDefault' => 'เป็นค่าเริ่มต้น?', 'Items' => '#VALUE!', 'LastContact' => 'ติดต่อล่าสุด', 'LastOrder' => 'คำสั่งสุดท้าย', + 'LeasingFee' => '', 'Log' => 'บันทึก', 'Logs' => 'การบันทึก', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR', 'MTDSales' => 'ขาย MTD', + 'Make' => '', 'Margin' => 'ระยะขอบ', 'Messages' => 'ข้อความ', + 'Milage' => '', + 'Model' => '', 'Modified' => 'ที่ได้รับการแก้ไข', 'Modules' => 'โมดูล', 'Name' => 'ชื่อ', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'ประวัติโดยย่อ', 'Profit' => '#VALUE!', 'Purchase' => 'ซื้อ', + 'PurchasePrice' => '', 'Quantity' => 'ปริมาณ', 'RecentInvoices' => 'ใบแจ้งหนี้ล่าสุด', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'ฝ่ายขาย', 'Segment' => 'ส่วน', 'Segments' => 'กลุ่ม', + 'Start' => '', + 'Status' => '', 'Subtype' => 'ประเภทย่อย', 'Support' => 'สนับสนุน', 'Tags' => 'แท็ก', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'พิมพ์', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'เว็บไซต์', 'Wire' => 'ลวด', 'YTDSales' => 'ขาย YTD', diff --git a/Theme/Backend/Lang/tr.lang.php b/Theme/Backend/Lang/tr.lang.php index 722d910..a0e6ff3 100755 --- a/Theme/Backend/Lang/tr.lang.php +++ b/Theme/Backend/Lang/tr.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Muhasebe', 'Addition' => 'İlave', 'Address' => 'Adres', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Müşteriler', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Temas', + 'Costs' => '', 'Country' => 'Ülke', 'Created' => 'Yaratılmış', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Tarih', 'Default' => 'Varsayılan', 'Delivery' => 'Teslimat', + 'Description' => '', 'Discount' => 'İndirim', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'İndirim %', 'Documents' => 'Belgeler', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Vadesi dolmuş', 'Email' => 'E-posta', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Faks', 'Files' => 'Dosyalar', 'Filter' => 'Filtrelemek', 'Freightage' => 'Yük', + 'From' => '', 'Group' => 'Grup', + 'History' => '', 'ID' => 'İD', 'Info' => 'Bilgi', + 'Inspections' => '', 'Invoice' => 'Fatura', 'Invoices' => 'Faturalar', 'IsDefault' => 'Varsayılan mı?', 'Items' => '#VALUE!', 'LastContact' => 'Son iletişim', 'LastOrder' => 'Son sipariş', + 'LeasingFee' => '', 'Log' => 'Kayıt', 'Logs' => 'Kütükler', 'LostCustomers' => '#VALUE!', 'MRR' => 'Mrr', 'MTDSales' => 'Mtd satışları', + 'Make' => '', 'Margin' => 'Marj', 'Messages' => 'Mesaj', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Değiştirilmiş', 'Modules' => 'Modüller', 'Name' => 'İsim', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Profil', 'Profit' => '#VALUE!', 'Purchase' => 'Satın alma', + 'PurchasePrice' => '', 'Quantity' => 'Miktar', 'RecentInvoices' => 'Son Faturalar', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Satış', 'Segment' => 'Segment', 'Segments' => 'Segmentler', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Alt tip', 'Support' => 'Destek', 'Tags' => 'Etiketler', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Tip', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'İnternet sitesi', 'Wire' => 'Tel', 'YTDSales' => 'YTD satışları', diff --git a/Theme/Backend/Lang/uk.lang.php b/Theme/Backend/Lang/uk.lang.php index e3c3f89..880c089 100755 --- a/Theme/Backend/Lang/uk.lang.php +++ b/Theme/Backend/Lang/uk.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => 'Бухгалтерський облік', 'Addition' => 'Додавання', 'Address' => 'Адреса', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => 'Клієнти', 'ComparisonTime' => '#VALUE!', 'Contact' => 'Контакт', + 'Costs' => '', 'Country' => 'Країна', 'Created' => 'Створений', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => 'Дата', 'Default' => 'За замовчуванням', 'Delivery' => 'Доставка', + 'Description' => '', 'Discount' => 'Знижка', 'DiscountBonus' => '#VALUE!', 'DiscountP' => 'Знижка%', 'Documents' => 'Документи', + 'Driver' => '', + 'Drivers' => '', 'Due' => 'Заборгованість', 'Email' => 'Електронна пошта', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => 'Факс', 'Files' => 'Файли', 'Filter' => 'Фільтрувати', 'Freightage' => 'Фрахт', + 'From' => '', 'Group' => 'Група', + 'History' => '', 'ID' => 'Ідентифікатор', 'Info' => 'Інформація', + 'Inspections' => '', 'Invoice' => 'Рахунок-фактура', 'Invoices' => 'Рахунки-фактури', 'IsDefault' => 'Чи є за замовчуванням?', 'Items' => '#VALUE!', 'LastContact' => 'Останній контакт', 'LastOrder' => 'Остання замовлення', + 'LeasingFee' => '', 'Log' => 'Журнал', 'Logs' => 'Журнали', 'LostCustomers' => '#VALUE!', 'MRR' => 'Пан', 'MTDSales' => 'Продажі MTD', + 'Make' => '', 'Margin' => 'Маржа', 'Messages' => 'Повідомлень', + 'Milage' => '', + 'Model' => '', 'Modified' => 'Модифікований', 'Modules' => 'Модулі', 'Name' => 'Назва', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => 'Профіль', 'Profit' => '#VALUE!', 'Purchase' => 'Придбання', + 'PurchasePrice' => '', 'Quantity' => 'Кількість', 'RecentInvoices' => 'Останні рахунки-фактури', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => 'Продаж', 'Segment' => 'Сегмент', 'Segments' => 'Сегменти', + 'Start' => '', + 'Status' => '', 'Subtype' => 'Підтип', 'Support' => 'Підтримка', 'Tags' => 'Теги', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => 'Тип', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => 'Веб-сайт', 'Wire' => 'Дріт', 'YTDSales' => 'Ytd продажі', diff --git a/Theme/Backend/Lang/zh.lang.php b/Theme/Backend/Lang/zh.lang.php index 246599f..4392416 100755 --- a/Theme/Backend/Lang/zh.lang.php +++ b/Theme/Backend/Lang/zh.lang.php @@ -12,7 +12,11 @@ */ declare(strict_types=1); -return ['ClientManagement' => [ +return ['FleetManagement' => [ + ':status1' => '', + ':status2' => '', + ':status3' => '', + ':status4' => '', 'Accounting' => '会计', 'Addition' => '添加', 'Address' => '地址', @@ -41,6 +45,7 @@ return ['ClientManagement' => [ 'Clients' => '客户', 'ComparisonTime' => '#VALUE!', 'Contact' => '接触', + 'Costs' => '', 'Country' => '国家', 'Created' => '创造了', 'CreatedAt' => '#VALUE!', @@ -51,33 +56,44 @@ return ['ClientManagement' => [ 'Date' => '日期', 'Default' => '默认', 'Delivery' => '交货', + 'Description' => '', 'Discount' => '折扣', 'DiscountBonus' => '#VALUE!', 'DiscountP' => '折扣 %', 'Documents' => '文件', + 'Driver' => '', + 'Drivers' => '', 'Due' => '到期的', 'Email' => '电子邮件', + 'End' => '', 'Europe' => '#VALUE!', 'Fax' => '传真', 'Files' => '文件', 'Filter' => '筛选', 'Freightage' => 'FRIGUTAGE.', + 'From' => '', 'Group' => '团体', + 'History' => '', 'ID' => 'ID', 'Info' => '信息', + 'Inspections' => '', 'Invoice' => '发票', 'Invoices' => '发票', 'IsDefault' => '默认为默认情况下?', 'Items' => '#VALUE!', 'LastContact' => '最后联系人', 'LastOrder' => '最后的订单', + 'LeasingFee' => '', 'Log' => '日志', 'Logs' => '日志', 'LostCustomers' => '#VALUE!', 'MRR' => 'MRR.', 'MTDSales' => 'MTD销售', + 'Make' => '', 'Margin' => '利润', 'Messages' => '消息', + 'Milage' => '', + 'Model' => '', 'Modified' => '修改的', 'Modules' => '模块', 'Name' => '名称', @@ -102,23 +118,33 @@ return ['ClientManagement' => [ 'Profile' => '轮廓', 'Profit' => '#VALUE!', 'Purchase' => '购买', + 'PurchasePrice' => '', 'Quantity' => '数量', 'RecentInvoices' => '最近的发票', 'Region' => '#VALUE!', 'Rep' => '#VALUE!', + 'Responsible' => '', 'Retention' => '#VALUE!', 'Sales' => '销售量', 'Segment' => '分割', 'Segments' => '段', + 'Start' => '', + 'Status' => '', 'Subtype' => '亚型', 'Support' => '支持', 'Tags' => '标签', 'Title' => '#VALUE!', + 'To' => '', 'Total' => '#VALUE!', 'TotalPrice' => '#VALUE!', 'Type' => '类型', 'UnitPrice' => '#VALUE!', + 'Upcoming' => '', + 'VIN' => '', 'Value' => '#VALUE!', + 'Vehicle' => '', + 'Vehicles' => '', + 'Vin' => '', 'Website' => '网站', 'Wire' => '金属丝', 'YTDSales' => 'ytd销售', From 8d778175e166fa153a03b37c0aa2d0f0d29737bc Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 02:48:07 +0000 Subject: [PATCH 47/89] fix tests --- Controller/ApiDriverAttributeController.php | 18 ++++---- Controller/ApiVehicleAttributeController.php | 18 ++++---- Models/License.php | 46 ++++++++++++++++++++ Models/LicenseType.php | 46 ++++++++++++++++++++ 4 files changed, 110 insertions(+), 18 deletions(-) diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php index 0831e78..6664f03 100644 --- a/Controller/ApiDriverAttributeController.php +++ b/Controller/ApiDriverAttributeController.php @@ -451,17 +451,17 @@ final class ApiDriverAttributeController extends Controller // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values // either here or other function? - if (!empty($val = $this->validateAttributeValueDelete($request))) { - $response->header->status = RequestStatusCode::R_400; - $this->createInvalidDeleteResponse($request, $response, $val); + // if (!empty($val = $this->validateAttributeValueDelete($request))) { + // $response->header->status = RequestStatusCode::R_400; + // $this->createInvalidDeleteResponse($request, $response, $val); - return; - } + // return; + // } - /** @var \Modules\FleetManagement\Models\DriverAttributeValue $driverAttributeValue */ - $driverAttributeValue = DriverAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); - $this->deleteModel($request->header->account, $driverAttributeValue, DriverAttributeValueMapper::class, 'driver_attribute_value', $request->getOrigin()); - $this->createStandardDeleteResponse($request, $response, $driverAttributeValue); + // /** @var \Modules\FleetManagement\Models\DriverAttributeValue $driverAttributeValue */ + // $driverAttributeValue = DriverAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + // $this->deleteModel($request->header->account, $driverAttributeValue, DriverAttributeValueMapper::class, 'driver_attribute_value', $request->getOrigin()); + // $this->createStandardDeleteResponse($request, $response, $driverAttributeValue); } /** diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php index 1046c5b..67f47fc 100644 --- a/Controller/ApiVehicleAttributeController.php +++ b/Controller/ApiVehicleAttributeController.php @@ -451,17 +451,17 @@ final class ApiVehicleAttributeController extends Controller // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values // either here or other function? - if (!empty($val = $this->validateAttributeValueDelete($request))) { - $response->header->status = RequestStatusCode::R_400; - $this->createInvalidDeleteResponse($request, $response, $val); + // if (!empty($val = $this->validateAttributeValueDelete($request))) { + // $response->header->status = RequestStatusCode::R_400; + // $this->createInvalidDeleteResponse($request, $response, $val); - return; - } + // return; + // } - /** @var \Modules\FleetManagement\Models\VehicleAttributeValue $vehicleAttributeValue */ - $vehicleAttributeValue = VehicleAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); - $this->deleteModel($request->header->account, $vehicleAttributeValue, VehicleAttributeValueMapper::class, 'vehicle_attribute_value', $request->getOrigin()); - $this->createStandardDeleteResponse($request, $response, $vehicleAttributeValue); + // /** @var \Modules\FleetManagement\Models\VehicleAttributeValue $vehicleAttributeValue */ + // $vehicleAttributeValue = VehicleAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + // $this->deleteModel($request->header->account, $vehicleAttributeValue, VehicleAttributeValueMapper::class, 'vehicle_attribute_value', $request->getOrigin()); + // $this->createStandardDeleteResponse($request, $response, $vehicleAttributeValue); } /** diff --git a/Models/License.php b/Models/License.php index e69de29..927a319 100644 --- a/Models/License.php +++ b/Models/License.php @@ -0,0 +1,46 @@ + $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/LicenseType.php b/Models/LicenseType.php index e69de29..f090e41 100644 --- a/Models/LicenseType.php +++ b/Models/LicenseType.php @@ -0,0 +1,46 @@ + $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} From 286fe02c49c310a78afd7f9b62248ad9d6a44555 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 03:57:32 +0000 Subject: [PATCH 48/89] fix db handling --- tests/Bootstrap.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index 5193c0e..b904f0c 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -349,13 +349,6 @@ $GLOBALS['dbpool']->create('update', $CONFIG['db']['core']['masters']['update']) $GLOBALS['dbpool']->create('delete', $CONFIG['db']['core']['masters']['delete']); $GLOBALS['dbpool']->create('schema', $CONFIG['db']['core']['masters']['schema']); -$GLOBALS['dbpool']->get('admin')->connect(); -$GLOBALS['dbpool']->get('select')->connect(); -$GLOBALS['dbpool']->get('insert')->connect(); -$GLOBALS['dbpool']->get('update')->connect(); -$GLOBALS['dbpool']->get('delete')->connect(); -$GLOBALS['dbpool']->get('schema')->connect(); - DataMapperFactory::db($GLOBALS['dbpool']->get()); $GLOBALS['frameworkpath'] = '/phpOMS/'; From 8b0076fdb5875530c84eb115dd947d2b0bac5bed Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 14:19:20 +0000 Subject: [PATCH 49/89] fix tests --- .github/workflows/main.yml | 2 +- .../Api/ApiControllerAttributeTrait.php | 220 ++++++++++++++++++ tests/Controller/ApiControllerTest.php | 4 + 3 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 tests/Controller/Api/ApiControllerAttributeTrait.php diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e12c33f..3281bdf 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,7 +42,7 @@ jobs: run: composer install - name: Autoformat run: | - vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes + vendor/bin/php-cs-fixer fix ./ --rules='{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}' --allow-risky=yes vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ - name: Check for modified files id: git-check diff --git a/tests/Controller/Api/ApiControllerAttributeTrait.php b/tests/Controller/Api/ApiControllerAttributeTrait.php new file mode 100644 index 0000000..5137aac --- /dev/null +++ b/tests/Controller/Api/ApiControllerAttributeTrait.php @@ -0,0 +1,220 @@ +header->account = 1; + $request->setData('name', 'test_attribute'); + $request->setData('title', 'EN:1'); + $request->setData('language', ISO639x1Enum::_EN); + + $this->attrModule->apiVehicleAttributeTypeCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeTypeL11nCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', 'DE:2'); + $request->setData('type', '1'); + $request->setData('language', ISO639x1Enum::_DE); + + $this->attrModule->apiVehicleAttributeTypeL11nCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeValueIntCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('default', '1'); + $request->setData('type', '1'); + $request->setData('value', '1'); + $request->setData('language', ISO639x1Enum::_DE); + $request->setData('country', ISO3166TwoEnum::_DEU); + + $this->attrModule->apiVehicleAttributeValueCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeValueStrCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('type', '1'); + $request->setData('value', '1'); + $request->setData('language', ISO639x1Enum::_DE); + $request->setData('country', ISO3166TwoEnum::_DEU); + + $this->attrModule->apiVehicleAttributeValueCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeValueFloatCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('type', '1'); + $request->setData('value', '1.1'); + $request->setData('language', ISO639x1Enum::_DE); + $request->setData('country', ISO3166TwoEnum::_DEU); + + $this->attrModule->apiVehicleAttributeValueCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeValueDatCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('type', '1'); + $request->setData('value', '2020-08-02'); + $request->setData('language', ISO639x1Enum::_DE); + $request->setData('country', ISO3166TwoEnum::_DEU); + + $this->attrModule->apiVehicleAttributeValueCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('item', '1'); + $request->setData('value', '1'); + $request->setData('type', '1'); + + $this->attrModule->apiVehicleAttributeCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeValueCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->attrModule->apiVehicleAttributeValueCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeTypeCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->attrModule->apiVehicleAttributeTypeCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeTypeL11nCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->attrModule->apiVehicleAttributeTypeL11nCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } + + /** + * @covers Modules\FleetManagement\Controller\ApiController + * @group module + */ + public function testApiVehicleAttributeCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->attrModule->apiVehicleAttributeCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } +} diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index ce5c095..773f0e9 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -16,6 +16,7 @@ namespace Modules\FleetManagement\tests\Controller; use Model\CoreSettings; use Modules\Admin\Models\AccountPermission; +use Modules\FleetManagement\tests\Controller\Api\ApiControllerAttributeTrait; use phpOMS\Account\Account; use phpOMS\Account\AccountManager; use phpOMS\Account\PermissionType; @@ -42,6 +43,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase * @var \Modules\FleetManagement\Controller\ApiController */ protected ModuleAbstract $module; + protected ModuleAbstract $attrModule; /** * {@inheritdoc} @@ -87,4 +89,6 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase TestUtils::setMember($this->module, 'app', $this->app); } + + use ApiControllerAttributeTrait; } From fa450966d96f88edf759f6165e7eb28cd5833fbb Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 14:56:44 +0000 Subject: [PATCH 50/89] rector fixes --- Admin/Installer.php | 36 ++++++++++++++++++------------------ tests/Bootstrap.php | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Admin/Installer.php b/Admin/Installer.php index b5e7345..b329158 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -134,9 +134,9 @@ final class Installer extends InstallerAbstract continue; } - $fuelTypes[$type['name']] = !\is_array($responseData['response']) - ? $responseData['response']->toArray() - : $responseData['response']; + $fuelTypes[$type['name']] = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); $isFirst = true; foreach ($type['l11n'] as $language => $l11n) { @@ -195,9 +195,9 @@ final class Installer extends InstallerAbstract continue; } - $vehicleTypes[$type['name']] = !\is_array($responseData['response']) - ? $responseData['response']->toArray() - : $responseData['response']; + $vehicleTypes[$type['name']] = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); $isFirst = true; foreach ($type['l11n'] as $language => $l11n) { @@ -256,9 +256,9 @@ final class Installer extends InstallerAbstract continue; } - $inspectionTypes[$type['name']] = !\is_array($responseData['response']) - ? $responseData['response']->toArray() - : $responseData['response']; + $inspectionTypes[$type['name']] = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); $isFirst = true; foreach ($type['l11n'] as $language => $l11n) { @@ -317,9 +317,9 @@ final class Installer extends InstallerAbstract continue; } - $inspectionTypes[$type['name']] = !\is_array($responseData['response']) - ? $responseData['response']->toArray() - : $responseData['response']; + $inspectionTypes[$type['name']] = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); $isFirst = true; foreach ($type['l11n'] as $language => $l11n) { @@ -382,9 +382,9 @@ final class Installer extends InstallerAbstract continue; } - $itemAttrType[$attribute['name']] = !\is_array($responseData['response']) - ? $responseData['response']->toArray() - : $responseData['response']; + $itemAttrType[$attribute['name']] = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); $isFirst = true; foreach ($attribute['l11n'] as $language => $l11n) { @@ -453,9 +453,9 @@ final class Installer extends InstallerAbstract continue; } - $attrValue = !\is_array($responseData['response']) - ? $responseData['response']->toArray() - : $responseData['response']; + $attrValue = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); $itemAttrValue[$attribute['name']][] = $attrValue; diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index b904f0c..44438e2 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -381,7 +381,7 @@ function phpServe() : void // Execute the command and store the process ID $output = []; - echo \sprintf('Starting server...') . \PHP_EOL; + echo 'Starting server...' . \PHP_EOL; echo \sprintf(' Current directory: %s', \getcwd()) . \PHP_EOL; echo \sprintf(' %s', $command); \exec($command, $output); @@ -406,7 +406,7 @@ function phpServe() : void // Kill the web server when the process ends \register_shutdown_function(function() use ($killCommand, $pid) : void { - echo \PHP_EOL . \sprintf('Stopping server...') . \PHP_EOL; + echo \PHP_EOL . 'Stopping server...' . \PHP_EOL; echo \sprintf(' %s - Killing process with ID %d', \date('r'), $pid) . \PHP_EOL; \exec($killCommand . $pid); }); From 950e064f6b949782f17e3fb4e461010e1587c2ec Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 16:03:38 +0000 Subject: [PATCH 51/89] fix vendor --- .gitignore | 15 +- composer.json | 4 +- composer.lock | 1360 ++++++++++++++++++++++++------------------------- 3 files changed, 692 insertions(+), 687 deletions(-) diff --git a/.gitignore b/.gitignore index 03b6968..bd6cef1 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,15 @@ -vendor Build +*.cache +.directory +Vagrantfile +vendor +bower_components +node_modules +*.log +.vagrant +.vscode +.sass-cache +cache +Cache +Libraries +.idea \ No newline at end of file diff --git a/composer.json b/composer.json index 1786c28..986c8c8 100755 --- a/composer.json +++ b/composer.json @@ -14,7 +14,9 @@ "phpmd/phpmd": ">=2.9", "phpstan/phpstan": ">=1.8.6", "phan/phan": ">=3.2.6", - "rector/rector": "^0.16.0" + "phploc/phploc": ">=7.0", + "phpmetrics/phpmetrics": ">=2.8", + "rector/rector": ">=0.16.0" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/composer.lock b/composer.lock index e706042..d019236 100755 --- a/composer.lock +++ b/composer.lock @@ -4,21 +4,21 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "64d7374a3cbdb7713d00fa01717ec92c", + "content-hash": "eb4ece0277f659c497f1d85019ebb6b0", "packages": [], "packages-dev": [ { "name": "composer/pcre", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", "shasum": "" }, "require": { @@ -60,7 +60,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.0.0" + "source": "https://github.com/composer/pcre/tree/3.1.0" }, "funding": [ { @@ -76,20 +76,20 @@ "type": "tidelift" } ], - "time": "2022-02-25T20:21:48+00:00" + "time": "2022-11-17T09:50:14+00:00" }, { "name": "composer/semver", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", "shasum": "" }, "require": { @@ -139,9 +139,9 @@ "versioning" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" + "source": "https://github.com/composer/semver/tree/3.4.0" }, "funding": [ { @@ -157,7 +157,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T19:23:25+00:00" + "time": "2023-08-31T09:50:34+00:00" }, { "name": "composer/xdebug-handler", @@ -226,89 +226,17 @@ "time": "2022-02-25T21:32:43+00:00" }, { - "name": "doctrine/annotations", - "version": "1.13.2", + "name": "doctrine/deprecations", + "version": "v1.1.1", "source": { "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^0.12.20", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.2" - }, - "time": "2021-08-05T19:00:23+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", "shasum": "" }, "require": { @@ -316,13 +244,60 @@ }, "require-dev": { "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" + }, + "time": "2023-06-03T09:27:29+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -349,7 +324,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -365,83 +340,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "doctrine/lexer", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9.0", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.11" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.3" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2022-02-28T11:07:21+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "felixfbecker/advanced-json-rpc", @@ -490,51 +389,51 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.8.0", + "version": "v3.28.0", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "113e09fea3d2306319ffaa2423fe3de768b28cff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", - "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/113e09fea3d2306319ffaa2423fe3de768b28cff", + "reference": "113e09fea3d2306319ffaa2423fe3de768b28cff", "shasum": "" }, "require": { - "composer/semver": "^3.2", + "composer/semver": "^3.3", "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^1.13", "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", - "php-cs-fixer/diff": "^2.0", + "sebastian/diff": "^4.0 || ^5.0", "symfony/console": "^5.4 || ^6.0", "symfony/event-dispatcher": "^5.4 || ^6.0", "symfony/filesystem": "^5.4 || ^6.0", "symfony/finder": "^5.4 || ^6.0", "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.25", - "symfony/polyfill-php81": "^1.25", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", "symfony/process": "^5.4 || ^6.0", "symfony/stopwatch": "^5.4 || ^6.0" }, "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.0", "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^1.5", - "mikey179/vfsstream": "^1.6.10", - "php-coveralls/php-coveralls": "^2.5.2", + "keradus/cli-executor": "^2.0", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.15", + "phpspec/prophecy": "^1.16", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "phpunitgoodpractices/polyfill": "^1.5", - "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^6.0", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", + "symfony/phpunit-bridge": "^6.2.3", "symfony/yaml": "^5.4 || ^6.0" }, "suggest": { @@ -565,9 +464,15 @@ } ], "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], "support": { - "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.8.0" + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.28.0" }, "funding": [ { @@ -575,20 +480,20 @@ "type": "github" } ], - "time": "2022-03-18T17:20:59+00:00" + "time": "2023-09-22T20:43:40+00:00" }, { "name": "microsoft/tolerant-php-parser", - "version": "v0.1.1", + "version": "v0.1.2", "source": { "type": "git", "url": "https://github.com/microsoft/tolerant-php-parser.git", - "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16" + "reference": "3eccfd273323aaf69513e2f1c888393f5947804b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/6a965617cf484355048ac6d2d3de7b6ec93abb16", - "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16", + "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/3eccfd273323aaf69513e2f1c888393f5947804b", + "reference": "3eccfd273323aaf69513e2f1c888393f5947804b", "shasum": "" }, "require": { @@ -618,22 +523,22 @@ "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", "support": { "issues": "https://github.com/microsoft/tolerant-php-parser/issues", - "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.1" + "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.2" }, - "time": "2021-07-16T21:28:12+00:00" + "time": "2022-10-05T17:30:19+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -671,7 +576,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -679,20 +584,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "netresearch/jsonmapper", - "version": "v4.0.0", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" + "reference": "f60565f8c0566a31acf06884cdaa591867ecc956" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", - "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/f60565f8c0566a31acf06884cdaa591867ecc956", + "reference": "f60565f8c0566a31acf06884cdaa591867ecc956", "shasum": "" }, "require": { @@ -728,22 +633,22 @@ "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" + "source": "https://github.com/cweiske/jsonmapper/tree/v4.2.0" }, - "time": "2020-12-01T19:48:11+00:00" + "time": "2023-04-09T17:37:40+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.17.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", "shasum": "" }, "require": { @@ -784,22 +689,22 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2023-08-13T19:53:39+00:00" }, { "name": "pdepend/pdepend", - "version": "2.10.3", + "version": "2.15.0", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "da3166a06b4a89915920a42444f707122a1584c9" + "reference": "0d4d8fb87aa74c358c1c4364514017f34b4a68b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/da3166a06b4a89915920a42444f707122a1584c9", - "reference": "da3166a06b4a89915920a42444f707122a1584c9", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/0d4d8fb87aa74c358c1c4364514017f34b4a68b9", + "reference": "0d4d8fb87aa74c358c1c4364514017f34b4a68b9", "shasum": "" }, "require": { @@ -833,9 +738,15 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", + "keywords": [ + "PHP Depend", + "PHP_Depend", + "dev", + "pdepend" + ], "support": { "issues": "https://github.com/pdepend/pdepend/issues", - "source": "https://github.com/pdepend/pdepend/tree/2.10.3" + "source": "https://github.com/pdepend/pdepend/tree/2.15.0" }, "funding": [ { @@ -843,20 +754,20 @@ "type": "tidelift" } ], - "time": "2022-02-23T07:53:09+00:00" + "time": "2023-09-22T02:30:39+00:00" }, { "name": "phan/phan", - "version": "5.3.2", + "version": "5.4.2", "source": { "type": "git", "url": "https://github.com/phan/phan.git", - "reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc" + "reference": "4f2870ed6fea320f62f3c3c63f3274d357a7980e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phan/phan/zipball/b7697eb811e912c038f709f8e1c4911c7ada3edc", - "reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc", + "url": "https://api.github.com/repos/phan/phan/zipball/4f2870ed6fea320f62f3c3c63f3274d357a7980e", + "reference": "4f2870ed6fea320f62f3c3c63f3274d357a7980e", "shasum": "" }, "require": { @@ -866,7 +777,7 @@ "ext-json": "*", "ext-tokenizer": "*", "felixfbecker/advanced-json-rpc": "^3.0.4", - "microsoft/tolerant-php-parser": "^0.1.0", + "microsoft/tolerant-php-parser": "0.1.2", "netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0", "php": "^7.2.0|^8.0.0", "sabre/event": "^5.1.3", @@ -920,9 +831,9 @@ ], "support": { "issues": "https://github.com/phan/phan/issues", - "source": "https://github.com/phan/phan/tree/5.3.2" + "source": "https://github.com/phan/phan/tree/5.4.2" }, - "time": "2022-02-01T00:17:36+00:00" + "time": "2023-03-03T17:20:24+00:00" }, { "name": "phar-io/manifest", @@ -1035,58 +946,6 @@ }, "time": "2022-02-21T01:04:05+00:00" }, - { - "name": "php-cs-fixer/diff", - "version": "v2.0.2", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/29dc0d507e838c4580d018bd8b5cb412474f7ec3", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", - "symfony/process": "^3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "sebastian/diff v3 backport support for PHP 5.6+", - "homepage": "https://github.com/PHP-CS-Fixer", - "keywords": [ - "diff" - ], - "support": { - "issues": "https://github.com/PHP-CS-Fixer/diff/issues", - "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2" - }, - "time": "2020-10-14T08:32:19+00:00" - }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -1199,25 +1058,33 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.1", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "doctrine/deprecations": "^1.0", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" }, "require-dev": { "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", "extra": { @@ -1243,28 +1110,90 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" }, - "time": "2022-03-15T21:29:03+00:00" + "time": "2023-08-12T11:01:26+00:00" }, { - "name": "phpmd/phpmd", - "version": "2.12.0", + "name": "phploc/phploc", + "version": "7.0.2", "source": { "type": "git", - "url": "https://github.com/phpmd/phpmd.git", - "reference": "c0b678ba71902f539c27c14332aa0ddcf14388ec" + "url": "https://github.com/sebastianbergmann/phploc.git", + "reference": "af0d5fc84f3f7725513ba59cdcbe670ac2a4532a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/c0b678ba71902f539c27c14332aa0ddcf14388ec", - "reference": "c0b678ba71902f539c27c14332aa0ddcf14388ec", + "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/af0d5fc84f3f7725513ba59cdcbe670ac2a4532a", + "reference": "af0d5fc84f3f7725513ba59cdcbe670ac2a4532a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0", + "sebastian/cli-parser": "^1.0", + "sebastian/version": "^3.0" + }, + "bin": [ + "phploc" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "A tool for quickly measuring the size of a PHP project.", + "homepage": "https://github.com/sebastianbergmann/phploc", + "support": { + "issues": "https://github.com/sebastianbergmann/phploc/issues", + "source": "https://github.com/sebastianbergmann/phploc/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "abandoned": true, + "time": "2020-12-07T05:51:20+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.13.0", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "dad0228156856b3ad959992f9748514fa943f3e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/dad0228156856b3ad959992f9748514fa943f3e3", + "reference": "dad0228156856b3ad959992f9748514fa943f3e3", "shasum": "" }, "require": { "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", "ext-xml": "*", - "pdepend/pdepend": "^2.10.3", + "pdepend/pdepend": "^2.12.1", "php": ">=5.3.9" }, "require-dev": { @@ -1320,7 +1249,7 @@ "support": { "irc": "irc://irc.freenode.org/phpmd", "issues": "https://github.com/phpmd/phpmd/issues", - "source": "https://github.com/phpmd/phpmd/tree/2.12.0" + "source": "https://github.com/phpmd/phpmd/tree/2.13.0" }, "funding": [ { @@ -1328,42 +1257,48 @@ "type": "tidelift" } ], - "time": "2022-03-24T13:33:01+00:00" + "time": "2022-09-10T08:44:15+00:00" }, { - "name": "phpspec/prophecy", - "version": "v1.15.0", + "name": "phpmetrics/phpmetrics", + "version": "v2.8.2", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + "url": "https://github.com/phpmetrics/PhpMetrics.git", + "reference": "4b77140a11452e63c7a9b98e0648320bf6710090" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "url": "https://api.github.com/repos/phpmetrics/PhpMetrics/zipball/4b77140a11452e63c7a9b98e0648320bf6710090", + "reference": "4b77140a11452e63c7a9b98e0648320bf6710090", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" + "ext-dom": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^3|^4", + "php": ">=5.5" + }, + "replace": { + "halleck45/php-metrics": "*", + "halleck45/phpmetrics": "*" }, "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14", + "sebastian/comparator": ">=1.2.3", + "squizlabs/php_codesniffer": "^3.5", + "symfony/dom-crawler": "^3.0 || ^4.0 || ^5.0" }, + "bin": [ + "bin/phpmetrics" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" + "files": [ + "./src/functions.php" + ], + "psr-0": { + "Hal\\": "./src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1372,43 +1307,85 @@ ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Jean-François Lépine", + "email": "lepinejeanfrancois@yahoo.fr", + "homepage": "http://www.lepine.pro", + "role": "Copyright Holder" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", + "description": "Static analyzer tool for PHP : Coupling, Cyclomatic complexity, Maintainability Index, Halstead's metrics... and more !", + "homepage": "http://www.phpmetrics.org", "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" + "analysis", + "qa", + "quality", + "testing" ], "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + "issues": "https://github.com/PhpMetrics/PhpMetrics/issues", + "source": "https://github.com/phpmetrics/PhpMetrics/tree/v2.8.2" }, - "time": "2021-12-08T12:19:24+00:00" + "time": "2023-03-08T15:03:36+00:00" }, { - "name": "phpstan/phpstan", - "version": "1.10.15", + "name": "phpstan/phpdoc-parser", + "version": "1.24.1", "source": { "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd" + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "9f854d275c2dbf84915a5c0ec9a2d17d2cd86b01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/762c4dac4da6f8756eebb80e528c3a47855da9bd", - "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9f854d275c2dbf84915a5c0ec9a2d17d2cd86b01", + "reference": "9f854d275c2dbf84915a5c0ec9a2d17d2cd86b01", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.1" + }, + "time": "2023-09-18T12:18:02+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.35", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "e730e5facb75ffe09dfb229795e8c01a459f26c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e730e5facb75ffe09dfb229795e8c01a459f26c3", + "reference": "e730e5facb75ffe09dfb229795e8c01a459f26c3", "shasum": "" }, "require": { @@ -1457,27 +1434,27 @@ "type": "tidelift" } ], - "time": "2023-05-09T15:28:01+00:00" + "time": "2023-09-19T15:27:56+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.15", + "version": "9.2.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -1492,8 +1469,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { @@ -1526,7 +1503,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" }, "funding": [ { @@ -1534,7 +1512,7 @@ "type": "github" } ], - "time": "2022-03-07T09:28:20+00:00" + "time": "2023-09-19T04:57:46+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1779,20 +1757,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.20", + "version": "9.6.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -1803,31 +1781,26 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-code-coverage": "^9.2.28", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", "phpunit/php-timer": "^5.0.2", "sebastian/cli-parser": "^1.0.1", "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", + "sebastian/comparator": "^4.0.8", "sebastian/diff": "^4.0.3", "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", + "sebastian/exporter": "^4.0.5", "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.2", "sebastian/version": "^3.0.2" }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -1835,7 +1808,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -1866,7 +1839,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" }, "funding": [ { @@ -1876,58 +1850,13 @@ { "url": "https://github.com/sebastianbergmann", "type": "github" - } - ], - "time": "2022-04-01T12:37:26+00:00" - }, - { - "name": "psr/cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + }, { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/3.0.0" - }, - "time": "2021-02-03T23:26:27+00:00" + "time": "2023-09-19T05:39:22+00:00" }, { "name": "psr/container", @@ -2084,21 +2013,21 @@ }, { "name": "rector/rector", - "version": "0.16.0", + "version": "0.18.3", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "2125ff71ea05b079562a8f59ca48a97eb78dc07f" + "reference": "ba7988e3e028e68e07191d75b0d5473ac320c5e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/2125ff71ea05b079562a8f59ca48a97eb78dc07f", - "reference": "2125ff71ea05b079562a8f59ca48a97eb78dc07f", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/ba7988e3e028e68e07191d75b0d5473ac320c5e7", + "reference": "ba7988e3e028e68e07191d75b0d5473ac320c5e7", "shasum": "" }, "require": { "php": "^7.2|^8.0", - "phpstan/phpstan": "^1.10.14" + "phpstan/phpstan": "^1.10.31" }, "conflict": { "rector/rector-doctrine": "*", @@ -2110,11 +2039,6 @@ "bin/rector" ], "type": "library", - "extra": { - "branch-alias": { - "dev-main": "0.15-dev" - } - }, "autoload": { "files": [ "bootstrap.php" @@ -2133,7 +2057,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/0.16.0" + "source": "https://github.com/rectorphp/rector/tree/0.18.3" }, "funding": [ { @@ -2141,7 +2065,7 @@ "type": "github" } ], - "time": "2023-05-05T12:12:17+00:00" + "time": "2023-09-12T20:18:14+00:00" }, { "name": "sabre/event", @@ -2378,16 +2302,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -2440,7 +2364,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -2448,7 +2372,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -2509,16 +2433,16 @@ }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", "shasum": "" }, "require": { @@ -2563,7 +2487,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" }, "funding": [ { @@ -2571,20 +2495,20 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-07T05:35:17+00:00" }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -2626,7 +2550,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -2634,20 +2558,20 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -2703,7 +2627,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -2711,20 +2635,20 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "5.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "bde739e7565280bda77be70044ac1047bc007e34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", "shasum": "" }, "require": { @@ -2767,7 +2691,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" }, "funding": [ { @@ -2775,7 +2699,7 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2023-08-02T09:26:13+00:00" }, { "name": "sebastian/lines-of-code", @@ -2948,16 +2872,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -2996,10 +2920,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -3007,7 +2931,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -3066,16 +2990,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -3087,7 +3011,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3110,7 +3034,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -3118,7 +3042,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -3175,16 +3099,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.2", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", "shasum": "" }, "require": { @@ -3220,49 +3144,47 @@ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", - "standards" + "standards", + "static analysis" ], "support": { "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2021-12-12T21:44:58+00:00" + "time": "2023-02-22T23:07:41+00:00" }, { "name": "symfony/config", - "version": "v6.0.7", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "22850bfdd2b6090568ad05dece6843c859d933b7" + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/22850bfdd2b6090568ad05dece6843c859d933b7", - "reference": "22850bfdd2b6090568ad05dece6843c859d933b7", + "url": "https://api.github.com/repos/symfony/config/zipball/b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", "shasum": "" }, "require": { - "php": ">=8.0.2", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/filesystem": "^5.4|^6.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php81": "^1.22" + "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/finder": "<4.4" + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" }, "require-dev": { "symfony/event-dispatcher": "^5.4|^6.0", "symfony/finder": "^5.4|^6.0", "symfony/messenger": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/yaml": "^5.4|^6.0" }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" - }, "type": "library", "autoload": { "psr-4": { @@ -3289,7 +3211,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.0.7" + "source": "https://github.com/symfony/config/tree/v6.3.2" }, "funding": [ { @@ -3305,26 +3227,27 @@ "type": "tidelift" } ], - "time": "2022-03-22T16:12:04+00:00" + "time": "2023-07-19T20:22:16+00:00" }, { "name": "symfony/console", - "version": "v6.0.7", + "version": "v6.3.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e" + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", - "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", + "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6", + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/string": "^5.4|^6.0" }, "conflict": { @@ -3346,12 +3269,6 @@ "symfony/process": "^5.4|^6.0", "symfony/var-dumper": "^5.4|^6.0" }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, "type": "library", "autoload": { "psr-4": { @@ -3379,12 +3296,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.0.7" + "source": "https://github.com/symfony/console/tree/v6.3.4" }, "funding": [ { @@ -3400,34 +3317,34 @@ "type": "tidelift" } ], - "time": "2022-03-31T17:18:25+00:00" + "time": "2023-08-16T10:10:12+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.0.7", + "version": "v6.3.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "3e8a405fcc2eaf4eadb25b5e259ad9bf90499848" + "reference": "68a5a9570806a087982f383f6109c5e925892a49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3e8a405fcc2eaf4eadb25b5e259ad9bf90499848", - "reference": "3e8a405fcc2eaf4eadb25b5e259ad9bf90499848", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/68a5a9570806a087982f383f6109c5e925892a49", + "reference": "68a5a9570806a087982f383f6109c5e925892a49", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php81": "^1.22", - "symfony/service-contracts": "^1.1.6|^2.0|^3.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.2.10" }, "conflict": { "ext-psr": "<1.1|>=2", - "symfony/config": "<5.4", + "symfony/config": "<6.1", "symfony/finder": "<5.4", - "symfony/proxy-manager-bridge": "<5.4", + "symfony/proxy-manager-bridge": "<6.3", "symfony/yaml": "<5.4" }, "provide": { @@ -3435,17 +3352,10 @@ "symfony/service-implementation": "1.1|2.0|3.0" }, "require-dev": { - "symfony/config": "^5.4|^6.0", + "symfony/config": "^6.1", "symfony/expression-language": "^5.4|^6.0", "symfony/yaml": "^5.4|^6.0" }, - "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, "type": "library", "autoload": { "psr-4": { @@ -3472,7 +3382,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.0.7" + "source": "https://github.com/symfony/dependency-injection/tree/v6.3.4" }, "funding": [ { @@ -3488,29 +3398,29 @@ "type": "tidelift" } ], - "time": "2022-03-08T15:43:52+00:00" + "time": "2023-08-16T17:55:17+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.1", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -3539,7 +3449,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" }, "funding": [ { @@ -3555,28 +3465,29 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.0.3", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934" + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934", - "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", "shasum": "" }, "require": { - "php": ">=8.0.2", - "symfony/event-dispatcher-contracts": "^2|^3" + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", @@ -3589,13 +3500,9 @@ "symfony/error-handler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/http-foundation": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/stopwatch": "^5.4|^6.0" }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, "type": "library", "autoload": { "psr-4": { @@ -3622,7 +3529,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" }, "funding": [ { @@ -3638,33 +3545,30 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2023-07-06T06:56:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.0.1", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051", - "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -3701,7 +3605,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" }, "funding": [ { @@ -3717,24 +3621,24 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/filesystem", - "version": "v6.0.7", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff" + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, @@ -3764,7 +3668,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.7" + "source": "https://github.com/symfony/filesystem/tree/v6.3.1" }, "funding": [ { @@ -3780,24 +3684,27 @@ "type": "tidelift" } ], - "time": "2022-04-01T12:54:51+00:00" + "time": "2023-06-01T08:30:39+00:00" }, { "name": "symfony/finder", - "version": "v6.0.3", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430" + "reference": "9915db259f67d21eefee768c1abcf1cc61b1fc9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8661b74dbabc23223f38c9b99d3f8ade71170430", - "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430", + "url": "https://api.github.com/repos/symfony/finder/zipball/9915db259f67d21eefee768c1abcf1cc61b1fc9e", + "reference": "9915db259f67d21eefee768c1abcf1cc61b1fc9e", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" }, "type": "library", "autoload": { @@ -3825,7 +3732,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.3" + "source": "https://github.com/symfony/finder/tree/v6.3.3" }, "funding": [ { @@ -3841,25 +3748,25 @@ "type": "tidelift" } ], - "time": "2022-01-26T17:23:29+00:00" + "time": "2023-07-31T08:31:44+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.0.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "51f7006670febe4cbcbae177cbffe93ff833250d" + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/51f7006670febe4cbcbae177cbffe93ff833250d", - "reference": "51f7006670febe4cbcbae177cbffe93ff833250d", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", "shasum": "" }, "require": { - "php": ">=8.0.2", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -3892,7 +3799,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.0.3" + "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" }, "funding": [ { @@ -3908,20 +3815,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2023-05-12T14:21:09+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { @@ -3936,7 +3843,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3974,7 +3881,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" }, "funding": [ { @@ -3990,20 +3897,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -4015,7 +3922,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4055,7 +3962,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" }, "funding": [ { @@ -4071,20 +3978,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -4096,7 +4003,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4139,7 +4046,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" }, "funding": [ { @@ -4155,20 +4062,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -4183,7 +4090,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4222,7 +4129,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, "funding": [ { @@ -4238,20 +4145,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { @@ -4260,7 +4167,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4305,7 +4212,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" }, "funding": [ { @@ -4321,20 +4228,20 @@ "type": "tidelift" } ], - "time": "2022-03-04T08:16:47+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", "shasum": "" }, "require": { @@ -4343,7 +4250,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4384,7 +4291,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" }, "funding": [ { @@ -4400,24 +4307,24 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:11+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/process", - "version": "v6.0.7", + "version": "v6.3.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4" + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", - "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", + "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -4445,7 +4352,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.0.7" + "source": "https://github.com/symfony/process/tree/v6.3.4" }, "funding": [ { @@ -4461,36 +4368,33 @@ "type": "tidelift" } ], - "time": "2022-03-18T16:21:55+00:00" + "time": "2023-08-07T10:39:22+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.0.1", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -4500,7 +4404,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4527,7 +4434,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" }, "funding": [ { @@ -4543,25 +4450,25 @@ "type": "tidelift" } ], - "time": "2022-03-13T20:10:05+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.0.5", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "f2c1780607ec6502f2121d9729fd8150a655d337" + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f2c1780607ec6502f2121d9729fd8150a655d337", - "reference": "f2c1780607ec6502f2121d9729fd8150a655d337", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", "shasum": "" }, "require": { - "php": ">=8.0.2", - "symfony/service-contracts": "^1|^2|^3" + "php": ">=8.1", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -4589,7 +4496,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.0.5" + "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" }, "funding": [ { @@ -4605,36 +4512,37 @@ "type": "tidelift" } ], - "time": "2022-02-21T17:15:17+00:00" + "time": "2023-02-16T10:14:28+00:00" }, { "name": "symfony/string", - "version": "v6.0.3", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2" + "reference": "53d1a83225002635bca3482fcbf963001313fb68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2", - "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2", + "url": "https://api.github.com/repos/symfony/string/zipball/53d1a83225002635bca3482fcbf963001313fb68", + "reference": "53d1a83225002635bca3482fcbf963001313fb68", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": "<2.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { "symfony/error-handler": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", - "symfony/translation-contracts": "^2.0|^3.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.5|^3.0", "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", @@ -4674,7 +4582,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.3" + "source": "https://github.com/symfony/string/tree/v6.3.2" }, "funding": [ { @@ -4690,7 +4598,81 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2023-07-05T08:41:27+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v6.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/df1f8aac5751871b83d30bf3e2c355770f8f0691", + "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-08-16T18:14:47+00:00" }, { "name": "theseer/tokenizer", @@ -4744,30 +4726,38 @@ }, { "name": "tysonandre/var_representation_polyfill", - "version": "0.1.1", + "version": "0.1.3", "source": { "type": "git", "url": "https://github.com/TysonAndre/var_representation_polyfill.git", - "reference": "0a942e74e18af5514749895507bc6ca7ab96399a" + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/0a942e74e18af5514749895507bc6ca7ab96399a", - "reference": "0a942e74e18af5514749895507bc6ca7ab96399a", + "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/e9116c2c352bb0835ca428b442dde7767c11ad32", + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": "^7.2.0|^8.0.0" }, + "provide": { + "ext-var_representation": "*" + }, "require-dev": { - "phan/phan": "^4.0", + "phan/phan": "^5.4.1", "phpunit/phpunit": "^8.5.0" }, "suggest": { - "ext-var_representation": "*" + "ext-var_representation": "For best performance" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.3-dev" + } + }, "autoload": { "files": [ "src/var_representation.php" @@ -4792,27 +4782,27 @@ ], "support": { "issues": "https://github.com/TysonAndre/var_representation_polyfill/issues", - "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.1" + "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.3" }, - "time": "2021-08-16T00:12:50+00:00" + "time": "2022-08-31T12:59:22+00:00" }, { "name": "webmozart/assert", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -4850,9 +4840,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" + "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2022-06-03T18:03:27+00:00" } ], "aliases": [], From 0c2230c87f446aea45d347d8000b09d7456518f0 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 17:57:28 +0000 Subject: [PATCH 52/89] fix tests --- .github/workflows/main.yml | 29 +++++++++++++++++++++++++++-- tests/Admin/AdminTest.php | 2 +- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3281bdf..f256cbe 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,6 +3,30 @@ name: CI on: [push, pull_request] jobs: + hash_generation: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'NO_CI')" + strategy: + fail-fast: false + max-parallel: 3 + steps: + - name: Checkout Repository + uses: actions/checkout@main + with: + fetch-depth: 1 + - name: hash + run: find ./ -type f -not -path "./vendor/*" -name -exec md5sum {} \; > hashs.txt + - name: Check for modified files + id: git-check + run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) + - name: Push changes + if: steps.git-check.outputs.modified == 'true' + run: | + git config --global user.name 'Hash Bot' + git config --global user.email 'hash.bot@jingga.app' + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} + git commit -am "Automated hash generation (NO_CI)" + git push autoformat: runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'NO_CI')" @@ -44,6 +68,7 @@ jobs: run: | vendor/bin/php-cs-fixer fix ./ --rules='{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}' --allow-risky=yes vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ + find ./ -type f -not -path "./vendor/*" -name -exec md5sum {} \; > hashs.txt - name: Check for modified files id: git-check run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) @@ -51,9 +76,9 @@ jobs: if: steps.git-check.outputs.modified == 'true' run: | git config --global user.name 'Formatter Bot' - git config --global user.email 'formatter.bot@karaka.app' + git config --global user.email 'formatter.bot@jingga.app' git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} - git commit -am "Automated formatting changes" + git commit -am "Automated formatting changes (NO_CI)" git push code-tests: runs-on: ubuntu-latest diff --git a/tests/Admin/AdminTest.php b/tests/Admin/AdminTest.php index 1b6302a..56ad3be 100755 --- a/tests/Admin/AdminTest.php +++ b/tests/Admin/AdminTest.php @@ -23,5 +23,5 @@ final class AdminTest extends \PHPUnit\Framework\TestCase protected const URI_LOAD = ''; - use \Modules\tests\ModuleTestTrait; + use \Build\Helper\ModuleTestTrait; } From 4bc00eea73f586649bfdc5f406ae0fe600cae7d3 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 18:23:44 +0000 Subject: [PATCH 53/89] fix test script --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f256cbe..7618968 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: with: fetch-depth: 1 - name: hash - run: find ./ -type f -not -path "./vendor/*" -name -exec md5sum {} \; > hashs.txt + run: find ./ -type f -not -path "./vendor/*" -exec md5sum {} \; > hashs.txt - name: Check for modified files id: git-check run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) @@ -68,7 +68,7 @@ jobs: run: | vendor/bin/php-cs-fixer fix ./ --rules='{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}' --allow-risky=yes vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ - find ./ -type f -not -path "./vendor/*" -name -exec md5sum {} \; > hashs.txt + find ./ -type f -not -path "./vendor/*" -exec md5sum {} \; > hashs.txt - name: Check for modified files id: git-check run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) From 81671afb66fb510748d8b0bdf81b291d77283be3 Mon Sep 17 00:00:00 2001 From: Formatter Bot Date: Sun, 24 Sep 2023 18:29:08 +0000 Subject: [PATCH 54/89] Automated formatting changes (NO_CI) --- Controller/ApiDriverAttributeController.php | 1 - Controller/ApiVehicleAttributeController.php | 1 - tests/Controller/ApiControllerTest.php | 3 ++- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php index 6664f03..56fa662 100644 --- a/Controller/ApiDriverAttributeController.php +++ b/Controller/ApiDriverAttributeController.php @@ -447,7 +447,6 @@ final class ApiDriverAttributeController extends Controller */ public function apiDriverAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - return; // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values // either here or other function? diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php index 67f47fc..463838f 100644 --- a/Controller/ApiVehicleAttributeController.php +++ b/Controller/ApiVehicleAttributeController.php @@ -447,7 +447,6 @@ final class ApiVehicleAttributeController extends Controller */ public function apiVehicleAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void { - return; // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values // either here or other function? diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 773f0e9..e70f7bf 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -43,6 +43,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase * @var \Modules\FleetManagement\Controller\ApiController */ protected ModuleAbstract $module; + protected ModuleAbstract $attrModule; /** @@ -69,7 +70,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase $account = new Account(); TestUtils::setMember($account, 'id', 1); - $permission = new AccountPermission(); + $permission = new AccountPermission(); $permission->unit = 1; $permission->app = 2; $permission->setPermission( From df2b6b550e4a3c557aff252336bf2dd7097f5094 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 20:29:22 +0000 Subject: [PATCH 55/89] test fixes --- tests/phpunit_default.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index 4db1f21..f5cc76f 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -3,11 +3,7 @@ *vendor* - vendor - ../vendor - ../phpOMS ../phpOMS* - ../phpOMS/* ../tests* ../*/tests* ../**/tests* From 78da45ae96e6e38f6fe681bdfe81494178c2de6b Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 21:37:03 +0000 Subject: [PATCH 56/89] fix tests --- tests/Autoloader.php | 5 +---- tests/phpunit_default.xml | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index d2d0080..3e4fb27 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -79,10 +79,7 @@ final class Autoloader $class = \strtr($class, '_\\', '//'); foreach (self::$paths as $path) { - $file = $path . $class . '.php'; - $file = \str_replace('/Modules/', '/', $file); - - if (\is_file($file)) { + if (\is_file($file = $path . $class . '.php')) { include_once $file; return; diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index f5cc76f..1ddff9f 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -47,7 +47,7 @@ - + From 9d80e5f9b88ca28c26fadfed29ec283ccc1ab696 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 22:02:54 +0000 Subject: [PATCH 57/89] fix autoloader bug --- tests/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 3e4fb27..3194eea 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -59,7 +59,7 @@ final class Autoloader */ public static function addPath(string $path) : void { - self::$paths[] = $path; + self::$paths[] = \rtrim($path, '/\\') . '/'; } /** From 774eed62e85d364dc3382e5ac3c59895e394d27d Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 22:44:32 +0000 Subject: [PATCH 58/89] test fixes --- tests/Bootstrap.php | 369 ++++++++++++++++++++++++++------------------ 1 file changed, 222 insertions(+), 147 deletions(-) diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index 44438e2..f817e99 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -1,8 +1,6 @@ [ 'core' => [ 'masters' => [ 'admin' => [ - 'db' => 'mysql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'insert' => [ - 'db' => 'mysql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'select' => [ - 'db' => 'mysql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'update' => [ - 'db' => 'mysql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'delete' => [ - 'db' => 'mysql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'schema' => [ - 'db' => 'mysql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mysql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '3306', /* db host port */ + 'login' => 'root', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], ], 'postgresql' => [ 'admin' => [ - 'db' => 'pgsql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'insert' => [ - 'db' => 'pgsql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'select' => [ - 'db' => 'pgsql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'update' => [ - 'db' => 'pgsql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'delete' => [ - 'db' => 'pgsql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'schema' => [ - 'db' => 'pgsql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => 'root', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], ], 'sqlite' => [ 'admin' => [ - 'db' => 'sqlite', /* db type */ - 'database' => __DIR__ . '/test.sqlite', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'insert' => [ - 'db' => 'sqlite', /* db type */ - 'database' => __DIR__ . '/test.sqlite', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'select' => [ - 'db' => 'sqlite', /* db type */ - 'database' => __DIR__ . '/test.sqlite', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'update' => [ - 'db' => 'sqlite', /* db type */ - 'database' => __DIR__ . '/test.sqlite', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'delete' => [ - 'db' => 'sqlite', /* db type */ - 'database' => __DIR__ . '/test.sqlite', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'schema' => [ - 'db' => 'sqlite', /* db type */ - 'database' => __DIR__ . '/test.sqlite', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], ], 'mssql' => [ 'admin' => [ - 'db' => 'mssql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'R00troot', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'insert' => [ - 'db' => 'mssql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'R00troot', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'select' => [ - 'db' => 'mssql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'R00troot', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'update' => [ - 'db' => 'mssql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'R00troot', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'delete' => [ - 'db' => 'mssql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'R00troot', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], 'schema' => [ - 'db' => 'mssql', /* db type */ - 'host' => '127.0.0.1', /* db host address */ - 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'R00troot', /* db login password */ - 'database' => 'oms', /* db name */ - 'weight' => 1000, /* db table prefix */ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '1433', /* db host port */ + 'login' => 'sa', /* db login name */ + 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'database' => 'oms', /* db name */ + 'weight' => 1000, /* db table prefix */ + 'datetimeformat' => 'Y-m-d H:i:s', ], ], ], @@ -412,4 +483,8 @@ function phpServe() : void }); } -\phpServe(); +try { + \phpServe(); +} catch(\Throwable $t) { + echo $t->getMessage(); +} From d502b8892225ca159018601bc453f4ff36e1ac44 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 24 Sep 2023 23:20:27 +0000 Subject: [PATCH 59/89] fix tests --- .github/workflows/main.yml | 49 +++++++++++--------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7618968..7eaad66 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -121,28 +121,6 @@ jobs: uses: actions/checkout@main with: fetch-depth: 1 - - name: Checkout Build Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Build - path: Build - - name: Checkout Resource Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Resources - path: Resources - - name: Checkout phpOMS Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/phpOMS - path: phpOMS - token: ${{ secrets.GH_PAT }} - name: Checkout Karaka Repository uses: actions/checkout@main with: @@ -150,6 +128,7 @@ jobs: ref: develop repository: Karaka-Management/Karaka path: Karaka + submodules: recursive - name: Setup PHP, with composer and extensions uses: shivammathur/setup-php@master with: @@ -192,14 +171,14 @@ jobs: ref: develop repository: Karaka-Management/Build path: Build - - name: Checkout phpOMS Repository + - name: Checkout Karaka Repository uses: actions/checkout@main with: fetch-depth: 1 ref: develop - repository: Karaka-Management/phpOMS - path: phpOMS - token: ${{ secrets.GH_PAT }} + repository: Karaka-Management/Karaka + path: Karaka + submodules: recursive - name: Setup PHP, with composer and extensions uses: shivammathur/setup-php@master with: @@ -218,7 +197,7 @@ jobs: - name: Setup Composer run: composer install - name: phpstan - run: vendor/bin/phpstan analyse -a phpOMS/Autoloader.php --no-progress -l 9 -c Build/Config/phpstan.neon ./ + run: vendor/bin/phpstan analyse -a tests/Autoloader.php --no-progress -l 9 -c Build/Config/phpstan.neon ./ codestyle-tests: runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'NO_CI')" @@ -262,14 +241,14 @@ jobs: run: vendor/bin/phpcs --severity=1 ./ --standard="Build/Config/phpcs.xml" -s --report=full - name: rector run: vendor/bin/rector process --dry-run --config Build/Config/rector.php ./ - - name: Install NPM - uses: actions/setup-node@v3 - with: - node-version: '14' - cache: 'npm' - - run: npm install - - name: eslint - run: npx eslint ./ -c Build/Config/.eslintrc.json + # - name: Install NPM + # uses: actions/setup-node@v3 + # with: + # node-version: '14' + # cache: 'npm' + # - run: npm install + # - name: eslint + # run: npx eslint ./ -c Build/Config/.eslintrc.json # linting: # runs-on: ubuntu-latest # if: "!contains(github.event.head_commit.message, 'NO_CI')" From 693f0b67714623dacdf43699f7f57ca4eff5204e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 00:35:07 +0000 Subject: [PATCH 60/89] fix autoloader --- tests/Autoloader.php | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 3194eea..f08bcb9 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -75,11 +75,25 @@ final class Autoloader */ public static function defaultAutoloader(string $class) : void { - $class = \ltrim($class, '\\'); - $class = \strtr($class, '_\\', '//'); + $class = \ltrim($class, '\\'); + $class = \strtr($class, '_\\', '//'); + $class2 = $class; + + $pos = \stripos($class, '/'); + if ($pos !== false) { + $pos = \stripos($class, '/', $pos + 1); + + if ($pos !== false) { + $class2 = \substr($class, $pos + 1); + } + } foreach (self::$paths as $path) { - if (\is_file($file = $path . $class . '.php')) { + if (\is_file($file = $path . $class2 . '.php')) { + include_once $file; + + return; + } elseif (\is_file($file = $path . $class . '.php')) { include_once $file; return; From 552e7c6847fb1f52163917ca5c17eea06d2e5c6f Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 01:12:31 +0000 Subject: [PATCH 61/89] test fixes (NO_CI) --- tests/Admin/AdminTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Admin/AdminTest.php b/tests/Admin/AdminTest.php index 56ad3be..e949318 100755 --- a/tests/Admin/AdminTest.php +++ b/tests/Admin/AdminTest.php @@ -23,5 +23,5 @@ final class AdminTest extends \PHPUnit\Framework\TestCase protected const URI_LOAD = ''; - use \Build\Helper\ModuleTestTrait; + use \tests\Modules\ModuleTestTrait; } From b187154f2d90690ed5feaea17d3b0ec8bcd32cb2 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 01:27:18 +0000 Subject: [PATCH 62/89] use reusable workflows NO_CI --- .github/workflows/main.yml | 304 +------------------------------------ 1 file changed, 5 insertions(+), 299 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7eaad66..53db0e3 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,302 +3,8 @@ name: CI on: [push, pull_request] jobs: - hash_generation: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'NO_CI')" - strategy: - fail-fast: false - max-parallel: 3 - steps: - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - - name: hash - run: find ./ -type f -not -path "./vendor/*" -exec md5sum {} \; > hashs.txt - - name: Check for modified files - id: git-check - run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) - - name: Push changes - if: steps.git-check.outputs.modified == 'true' - run: | - git config --global user.name 'Hash Bot' - git config --global user.email 'hash.bot@jingga.app' - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} - git commit -am "Automated hash generation (NO_CI)" - git push - autoformat: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'NO_CI')" - strategy: - fail-fast: false - max-parallel: 3 - matrix: - php-versions: ['8.1'] - steps: - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - - name: Checkout Build Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Build - path: Build - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, bcmath, redis, memcached - ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - name: Setup Composer - run: composer install - - name: Autoformat - run: | - vendor/bin/php-cs-fixer fix ./ --rules='{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "global_namespace_import": {"import_classes": false, "import_constants": false, "import_functions": false}, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align", ">>=": "align", "<<=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": {"const": "one", "method": "one", "property": "one"} }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": true, "yoda_style": {"equal": false, "identical": false, "less_and_greater": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "constant_case": {"case": "lower"}, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": {"include": ["@all"]}, "new_with_braces": true, "no_extra_blank_lines": {"tokens": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"]}, "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"replacements": {"this": "self"}}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}' --allow-risky=yes - vendor/bin/phpcbf --standard=Build/Config/phpcs.xml ./ - find ./ -type f -not -path "./vendor/*" -exec md5sum {} \; > hashs.txt - - name: Check for modified files - id: git-check - run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) - - name: Push changes - if: steps.git-check.outputs.modified == 'true' - run: | - git config --global user.name 'Formatter Bot' - git config --global user.email 'formatter.bot@jingga.app' - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} - git commit -am "Automated formatting changes (NO_CI)" - git push - code-tests: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'NO_CI')" - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: false - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: oms - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - postgres: - image: postgres:10.8 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: root - POSTGRES_DB: oms - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 - redis: - image: redis - ports: - - 6379:6379 - options: --entrypoint redis-server - memcached: - image: memcached - ports: - - 11211:11211 - strategy: - fail-fast: false - max-parallel: 3 - matrix: - php-versions: ['8.1'] - steps: - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - - name: Checkout Karaka Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Karaka - path: Karaka - submodules: recursive - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached - ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 - coverage: pcov - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - name: Setup Composer - run: composer install - - name: phpunit - run: vendor/bin/phpunit --coverage-clover tests/coverage.xml --configuration tests/phpunit_default.xml - static-tests: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'NO_CI')" - strategy: - fail-fast: false - max-parallel: 3 - matrix: - php-versions: ['8.1'] - steps: - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - submodules: recursive - token: ${{ secrets.GH_PAT }} - - name: Checkout Build Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Build - path: Build - - name: Checkout Karaka Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Karaka - path: Karaka - submodules: recursive - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached - ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - name: Setup Composer - run: composer install - - name: phpstan - run: vendor/bin/phpstan analyse -a tests/Autoloader.php --no-progress -l 9 -c Build/Config/phpstan.neon ./ - codestyle-tests: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'NO_CI')" - strategy: - fail-fast: false - max-parallel: 3 - matrix: - php-versions: ['8.1'] - steps: - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - submodules: recursive - token: ${{ secrets.GH_PAT }} - - name: Checkout Build Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Build - path: Build - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached - ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - name: Setup Composer - run: composer install - - name: phpcs - run: vendor/bin/phpcs --severity=1 ./ --standard="Build/Config/phpcs.xml" -s --report=full - - name: rector - run: vendor/bin/rector process --dry-run --config Build/Config/rector.php ./ - # - name: Install NPM - # uses: actions/setup-node@v3 - # with: - # node-version: '14' - # cache: 'npm' - # - run: npm install - # - name: eslint - # run: npx eslint ./ -c Build/Config/.eslintrc.json -# linting: -# runs-on: ubuntu-latest -# if: "!contains(github.event.head_commit.message, 'NO_CI')" -# strategy: -# fail-fast: false -# max-parallel: 3 -# steps: -# - name: Checkout Repository -# uses: actions/checkout@main -# with: -# fetch-depth: 0 -# submodules: recursive -# token: ${{ secrets.GH_TOKEN }} -# - name: Lint Code Base -# uses: github/super-linter/slim@v4 -# env: -# VALIDATE_ALL_CODEBASE: false -# VALIDATE_PHP: true -# VALIDATE_PHP_BUILTIN: true -# DEFAULT_BRANCH: develop -# GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - custom: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'NO_CI')" - strategy: - fail-fast: false - max-parallel: 3 - matrix: - php-versions: ['8.1'] - steps: - - name: Checkout Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - - name: Checkout Build Repository - uses: actions/checkout@main - with: - fetch-depth: 1 - ref: develop - repository: Karaka-Management/Build - path: Build - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, bcmath, redis, memcached - ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1 - - name: PHP linting - run: | - find ./ -type f \ - -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v "No syntax errors detected" ) - - name: Php strict - run: if [[ $(grep -r -L "declare(strict_types=1);" --include=*.php --exclude={*.tpl.php,*Hooks.php,*Routes.php,*SearchCommands.php} ./) -ne "" ]]; then exit 1; fi + general_module_workflow: + uses: Karaka-Management/Karaka/.github/workflows/module.yml@develop + secrets: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_PAT: ${{ secrets.GH_PAT }} From 516c36ae19d27513839dcbc0036f788933a7e559 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 03:09:09 +0000 Subject: [PATCH 63/89] image optimization and test fixes --- .github/workflows/image.yml | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml index d079329..6f8f14a 100755 --- a/.github/workflows/image.yml +++ b/.github/workflows/image.yml @@ -1,24 +1,10 @@ -name: Compress images -on: - push: - paths: - - '**.jpg' - - '**.png' - - '**.webp' - pull_request: - paths: - - '**.jpg' - - '**.png' - - '**.webp' -jobs: - build: - name: calibreapp/image-actions - runs-on: ubuntu-latest - steps: - - name: Checkout Repo - uses: actions/checkout@main +name: Image optimization - - name: Compress Images - uses: calibreapp/image-actions@main - with: - githubToken: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file +on: [push, pull_request] + +jobs: + general_image_workflow: + uses: Karaka-Management/Karaka/.github/workflows/image.yml@develop + secrets: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_PAT: ${{ secrets.GH_PAT }} From 8321cf5239a8317ba460c93c3fff33366fad2a7f Mon Sep 17 00:00:00 2001 From: Image Bot Date: Mon, 25 Sep 2023 03:18:19 +0000 Subject: [PATCH 64/89] Automated image optimization (NO_CI) --- Docs/Dev/img/er.png | Bin 312054 -> 216744 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Docs/Dev/img/er.png diff --git a/Docs/Dev/img/er.png b/Docs/Dev/img/er.png old mode 100755 new mode 100644 index ce0e2b91f6ea9c3dd87a91464fc983adbd566bb7..b4b4986acb8c92bb406985e710ffacff1facd5c0 GIT binary patch literal 216744 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

t~(`5%+3$Z-SdJw5+RYm;}6 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 literal 312054 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

fvDEQrSysTM~UV@u)Wc)c^S+_-E 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 z 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 z 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

3rA0&0A9H@Yv8-N}M;vkO`cL3gYd!!wg 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 w{fqyer1$4@{ww_Z=l| Date: Mon, 25 Sep 2023 11:04:33 +0000 Subject: [PATCH 65/89] fix tests --- tests/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index f08bcb9..d07405a 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -34,7 +34,7 @@ final class Autoloader */ private static $paths = [ __DIR__ . '/../', - __DIR__ . '/../Karaka/', + __DIR__ . '/../MainAutoloader/', __DIR__ . '/../../', ]; From b1620679de75bb0650fdccd826e9615a924ad6bc Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 11:32:51 +0000 Subject: [PATCH 66/89] fix autoloader --- tests/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index d07405a..621bdc4 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -34,7 +34,7 @@ final class Autoloader */ private static $paths = [ __DIR__ . '/../', - __DIR__ . '/../MainAutoloader/', + __DIR__ . '/../MainRepository/', __DIR__ . '/../../', ]; From 8b51e097b6cd79da91ece0a22a47aa73c8f943e0 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 12:22:03 +0000 Subject: [PATCH 67/89] fix tests --- tests/phpunit_default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index 1ddff9f..f45f39b 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -27,7 +27,7 @@ - ../Karaka/Install/tests* + ../MainRepository/Install/tests* ../tests* From 19d783e14090c0dbcea41871bfb74fbc16793fa6 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 17:28:08 +0000 Subject: [PATCH 68/89] fix tests --- tests/Autoloader.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 621bdc4..602019b 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -77,6 +77,11 @@ final class Autoloader { $class = \ltrim($class, '\\'); $class = \strtr($class, '_\\', '//'); + + if (\stripos($class, 'Web/Backend')) { + $class = \str_replace('Web', 'Install/Application', $class); + } + $class2 = $class; $pos = \stripos($class, '/'); From 714ffde226855c25e3e3e68af970ffc454c17916 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 19:59:41 +0000 Subject: [PATCH 69/89] fix tests --- tests/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 602019b..a6e0894 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -79,7 +79,7 @@ final class Autoloader $class = \strtr($class, '_\\', '//'); if (\stripos($class, 'Web/Backend')) { - $class = \str_replace('Web', 'Install/Application', $class); + $class = \str_replace('Web/', 'Install/Application/', $class); } $class2 = $class; From 4829e899176ef2d7657aed05025e0c3080980705 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 25 Sep 2023 22:54:39 +0000 Subject: [PATCH 70/89] fix tests --- tests/Admin/AdminTest.php | 2 +- tests/Autoloader.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Admin/AdminTest.php b/tests/Admin/AdminTest.php index e949318..808ff14 100755 --- a/tests/Admin/AdminTest.php +++ b/tests/Admin/AdminTest.php @@ -21,7 +21,7 @@ final class AdminTest extends \PHPUnit\Framework\TestCase { protected const NAME = 'FleetManagement'; - protected const URI_LOAD = ''; + protected const URI_LOAD = 'http://127.0.0.1/en/backend/fleet'; use \tests\Modules\ModuleTestTrait; } diff --git a/tests/Autoloader.php b/tests/Autoloader.php index a6e0894..b23e8e6 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -78,7 +78,7 @@ final class Autoloader $class = \ltrim($class, '\\'); $class = \strtr($class, '_\\', '//'); - if (\stripos($class, 'Web/Backend')) { + if (\stripos($class, 'Web/Backend') !== false || \stripos($class, 'Web/Api') !== false) { $class = \str_replace('Web/', 'Install/Application/', $class); } From 52af76a2858c21d36404ef13c389be031544fe6c Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 26 Sep 2023 03:03:31 +0000 Subject: [PATCH 71/89] fix tests --- tests/Controller/ApiControllerTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index e70f7bf..6768d70 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -86,9 +86,11 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase $this->app->accountManager->add($account); $this->app->router = new WebRouter(); - $this->module = $this->app->moduleManager->get('FleetManagement'); + $this->module = $this->app->moduleManager->get('FleetManagement', 'Api'); + $this->attrModule = $this->app->moduleManager->get('FleetManagement', 'ApiVehicleAttribute'); TestUtils::setMember($this->module, 'app', $this->app); + TestUtils::setMember($this->attrModule, 'app', $this->app); } use ApiControllerAttributeTrait; From f6a175327ff4a9816e70cf7d90b8a99850b50c2f Mon Sep 17 00:00:00 2001 From: Formatter Bot Date: Tue, 26 Sep 2023 03:08:56 +0000 Subject: [PATCH 72/89] Automated formatting changes (NO_CI) --- tests/Controller/ApiControllerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 6768d70..59609bf 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -86,7 +86,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase $this->app->accountManager->add($account); $this->app->router = new WebRouter(); - $this->module = $this->app->moduleManager->get('FleetManagement', 'Api'); + $this->module = $this->app->moduleManager->get('FleetManagement', 'Api'); $this->attrModule = $this->app->moduleManager->get('FleetManagement', 'ApiVehicleAttribute'); TestUtils::setMember($this->module, 'app', $this->app); From 9588df60c6c67e3c8754e9ab55439db153ee88d0 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 26 Sep 2023 15:47:52 +0000 Subject: [PATCH 73/89] fix tests --- .github/workflows/main.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 53db0e3..f781ee9 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,16 @@ name: CI -on: [push, pull_request] +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + - develop + schedule: + - cron: '0 0 1,15 * *' jobs: general_module_workflow: From e2b485ea3fc501f2e302880639a37477967dc563 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 01:22:13 +0000 Subject: [PATCH 74/89] fix tests --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f781ee9..1dacd12 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ on: jobs: general_module_workflow: - uses: Karaka-Management/Karaka/.github/workflows/module.yml@develop + uses: Karaka-Management/Karaka/.github/workflows/php_template.yml@develop secrets: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_PAT: ${{ secrets.GH_PAT }} From 0c9df219ea49e5614fde3a345043598dc308fc4b Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 04:19:18 +0000 Subject: [PATCH 75/89] fix autoloader --- tests/Autoloader.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index b23e8e6..8e90d81 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -12,9 +12,9 @@ */ declare(strict_types=1); -namespace tests; +namespace Modules\FleettManagement\tests; -\spl_autoload_register('\tests\Autoloader::defaultAutoloader'); +\spl_autoload_register('\Modules\FleettManagement\tests\Autoloader::defaultAutoloader'); /** * Autoloader class. @@ -80,6 +80,8 @@ final class Autoloader if (\stripos($class, 'Web/Backend') !== false || \stripos($class, 'Web/Api') !== false) { $class = \str_replace('Web/', 'Install/Application/', $class); + } elseif (\stripos($class, 'Autoloader') !== false) { + $class = 'tests/Autoloader.php'; } $class2 = $class; From 7f89b4faf75d9f2d4bce7c9f42b3ce1ca95005d8 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 04:25:21 +0000 Subject: [PATCH 76/89] fix autoloading --- tests/Autoloader.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 8e90d81..b4c5a81 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -80,8 +80,6 @@ final class Autoloader if (\stripos($class, 'Web/Backend') !== false || \stripos($class, 'Web/Api') !== false) { $class = \str_replace('Web/', 'Install/Application/', $class); - } elseif (\stripos($class, 'Autoloader') !== false) { - $class = 'tests/Autoloader.php'; } $class2 = $class; From 19052be60ce41fe100306ad7efb1d3440a5d6e64 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 14:42:42 +0000 Subject: [PATCH 77/89] fix tests --- tests/Autoloader.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index b4c5a81..a33ea0b 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -83,9 +83,12 @@ final class Autoloader } $class2 = $class; + $class3 = $class; $pos = \stripos($class, '/'); if ($pos !== false) { + $class3 = \substr($class, $pos + 1); + $pos = \stripos($class, '/', $pos + 1); if ($pos !== false) { @@ -94,7 +97,7 @@ final class Autoloader } foreach (self::$paths as $path) { - if (\is_file($file = $path . $class2 . '.php')) { + if (\is_file($file = $path . $class2 . '.php') && \stripos($file, $class3) !== false) { include_once $file; return; From a5ca8e6e4b637fae4333aad13bc8023cf8f367cf Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 16:55:09 +0000 Subject: [PATCH 78/89] fix tests --- Admin/Routes/Web/Backend.php | 2 +- Controller/BackendController.php | 147 +++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 50cca4e..08bf0dc 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -167,7 +167,7 @@ return [ ], '^.*/fleet/inspection/profile.*$' => [ [ - 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementVehicleProfile', + 'dest' => '\Modules\FleetManagement\Controller\BackendController:viewFleetManagementInspectionProfile', 'verb' => RouteVerb::GET, 'permission' => [ 'module' => BackendController::NAME, diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 0ea4d5e..bc88bd8 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -71,6 +71,35 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementDriverAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type-list'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003503001, $request, $response); + + /** @var \Modules\Attribute\Models\AttributeType[] $attributes */ + $attributes = VehicleAttributeTypeMapper::getAll() + ->with('l11n') + ->where('l11n/language', $response->header->l11n->language) + ->execute(); + + $view->data['attributes'] = $attributes; + + return $view; + } + /** * Routing end-point for application behaviour. * @@ -159,6 +188,34 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementInspectionTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/inspection-list'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + $list = InspectionMapper::getAll() + ->sort('id', 'DESC') + ->execute(); + + $view->data['inspectionss'] = $list; + + return $view; + } + /** * Routing end-point for application behaviour. * @@ -194,6 +251,41 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementDriverAttributeType(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response); + + /** @var \Modules\Attribute\Models\AttributeType $attribute */ + $attribute = VehicleAttributeTypeMapper::get() + ->with('l11n') + ->where('id', (int) $request->getData('id')) + ->where('l11n/language', $response->header->l11n->language) + ->execute(); + + $l11ns = VehicleAttributeTypeL11nMapper::getAll() + ->where('ref', $attribute->id) + ->execute(); + + $view->data['attribute'] = $attribute; + $view->data['l11ns'] = $l11ns; + + return $view; + } + /** * Routing end-point for application behaviour. * @@ -227,6 +319,61 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementDriverCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/vehicle-profile'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + /** @var \Model\Setting $settings */ + $settings = $this->app->appSettings->get(null, [ + SettingsEnum::DEFAULT_LOCALIZATION, + ]); + + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); + + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['vehicle-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); + + return $view; + } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementInspectionProfile(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/inspection-profile'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + return $view; + } + /** * Routing end-point for application behaviour. * From ce9ec8029deca194e009f9ec59522ddb027bc38f Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 17:32:55 +0000 Subject: [PATCH 79/89] fix tests --- .../Api/ApiControllerAttributeTrait.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/Controller/Api/ApiControllerAttributeTrait.php b/tests/Controller/Api/ApiControllerAttributeTrait.php index 5137aac..b0c0b01 100644 --- a/tests/Controller/Api/ApiControllerAttributeTrait.php +++ b/tests/Controller/Api/ApiControllerAttributeTrait.php @@ -24,7 +24,7 @@ use phpOMS\Uri\HttpUri; trait ApiControllerAttributeTrait { /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeTypeCreate() : void @@ -42,7 +42,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeTypeL11nCreate() : void @@ -60,7 +60,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeValueIntCreate() : void @@ -80,7 +80,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeValueStrCreate() : void @@ -99,7 +99,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeValueFloatCreate() : void @@ -118,7 +118,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeValueDatCreate() : void @@ -137,7 +137,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeCreate() : void @@ -155,7 +155,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeValueCreateInvalidData() : void @@ -171,7 +171,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeTypeCreateInvalidData() : void @@ -187,7 +187,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeTypeL11nCreateInvalidData() : void @@ -203,7 +203,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiController + * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute * @group module */ public function testApiVehicleAttributeCreateInvalidData() : void From e99dcdebc1e98fe9759e4b0873c12ce7ffb6e4eb Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 20:43:39 +0000 Subject: [PATCH 80/89] fix tests --- Controller/BackendController.php | 28 +++++++++++++++++++ .../Api/ApiControllerAttributeTrait.php | 22 +++++++-------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/Controller/BackendController.php b/Controller/BackendController.php index bc88bd8..41853fe 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -216,6 +216,34 @@ final class BackendController extends Controller return $view; } + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Returns a renderable object + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewFleetManagementInspectionCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + + $view->setTemplate('/Modules/FleetManagement/Theme/Backend/inspection-list'); + $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003502001, $request, $response); + + $list = InspectionMapper::getAll() + ->sort('id', 'DESC') + ->execute(); + + $view->data['inspectionss'] = $list; + + return $view; + } + /** * Routing end-point for application behaviour. * diff --git a/tests/Controller/Api/ApiControllerAttributeTrait.php b/tests/Controller/Api/ApiControllerAttributeTrait.php index b0c0b01..48933c2 100644 --- a/tests/Controller/Api/ApiControllerAttributeTrait.php +++ b/tests/Controller/Api/ApiControllerAttributeTrait.php @@ -24,7 +24,7 @@ use phpOMS\Uri\HttpUri; trait ApiControllerAttributeTrait { /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeTypeCreate() : void @@ -42,7 +42,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeTypeL11nCreate() : void @@ -60,7 +60,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeValueIntCreate() : void @@ -80,7 +80,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeValueStrCreate() : void @@ -99,7 +99,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeValueFloatCreate() : void @@ -118,7 +118,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeValueDatCreate() : void @@ -137,7 +137,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeCreate() : void @@ -155,7 +155,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeValueCreateInvalidData() : void @@ -171,7 +171,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeTypeCreateInvalidData() : void @@ -187,7 +187,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeTypeL11nCreateInvalidData() : void @@ -203,7 +203,7 @@ trait ApiControllerAttributeTrait } /** - * @covers Modules\FleetManagement\Controller\ApiVehicleAttribute + * @covers Modules\FleetManagement\Controller\ApiVehicleAttributeController * @group module */ public function testApiVehicleAttributeCreateInvalidData() : void From 9b54e1d1adfaeae78f20e6db3bb0f6399b5dbe3e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 27 Sep 2023 22:33:53 +0000 Subject: [PATCH 81/89] make data in routing endpoint array --- Controller/ApiDriverAttributeController.php | 60 ++++++++++---------- Controller/ApiDriverController.php | 28 ++++----- Controller/ApiVehicleAttributeController.php | 60 ++++++++++---------- Controller/ApiVehicleController.php | 52 ++++++++--------- Controller/BackendController.php | 56 +++++++++--------- 5 files changed, 128 insertions(+), 128 deletions(-) diff --git a/Controller/ApiDriverAttributeController.php b/Controller/ApiDriverAttributeController.php index 56fa662..fcd869f 100644 --- a/Controller/ApiDriverAttributeController.php +++ b/Controller/ApiDriverAttributeController.php @@ -44,7 +44,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -52,7 +52,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -71,7 +71,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -79,7 +79,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -98,7 +98,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -106,7 +106,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -125,7 +125,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -133,7 +133,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -167,7 +167,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -175,7 +175,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -194,7 +194,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -202,7 +202,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -245,7 +245,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -253,7 +253,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeDelete($request))) { $response->header->status = RequestStatusCode::R_400; @@ -282,7 +282,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -290,7 +290,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeL11nUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -312,7 +312,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -320,7 +320,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeL11nDelete($request))) { $response->header->status = RequestStatusCode::R_400; @@ -340,7 +340,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -348,7 +348,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -370,7 +370,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -380,7 +380,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeDelete($request))) { $response->header->status = RequestStatusCode::R_400; @@ -400,7 +400,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -408,7 +408,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -437,7 +437,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -445,7 +445,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values @@ -468,7 +468,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -476,7 +476,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueL11nUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -498,7 +498,7 @@ final class ApiDriverAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -506,7 +506,7 @@ final class ApiDriverAttributeController extends Controller * * @since 1.0.0 */ - public function apiDriverAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueL11nDelete($request))) { $response->header->status = RequestStatusCode::R_400; diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php index bb9249f..d3b872e 100644 --- a/Controller/ApiDriverController.php +++ b/Controller/ApiDriverController.php @@ -53,7 +53,7 @@ final class ApiDriverController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -61,7 +61,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiInspectionCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiInspectionCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateInspectionCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -123,7 +123,7 @@ final class ApiDriverController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -131,7 +131,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiDriverCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateDriverCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -309,7 +309,7 @@ final class ApiDriverController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -317,7 +317,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiMediaAddToDriver(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiMediaAddToDriver(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateMediaAddToDriver($request))) { $response->header->status = RequestStatusCode::R_400; @@ -455,7 +455,7 @@ final class ApiDriverController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -463,7 +463,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiDriverInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateDriverInspectionTypeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -522,7 +522,7 @@ final class ApiDriverController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -530,7 +530,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiDriverInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiDriverInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateDriverInspectionTypeL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -591,7 +591,7 @@ final class ApiDriverController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -599,7 +599,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateNoteCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -649,7 +649,7 @@ final class ApiDriverController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -657,7 +657,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiNoteEdit(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiNoteEdit(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { $this->app->moduleManager->get('Editor', 'Api')->apiEditorUpdate($request, $response, $data); diff --git a/Controller/ApiVehicleAttributeController.php b/Controller/ApiVehicleAttributeController.php index 463838f..fb55865 100644 --- a/Controller/ApiVehicleAttributeController.php +++ b/Controller/ApiVehicleAttributeController.php @@ -44,7 +44,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -52,7 +52,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -71,7 +71,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -79,7 +79,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -98,7 +98,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -106,7 +106,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -125,7 +125,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -133,7 +133,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -167,7 +167,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -175,7 +175,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -194,7 +194,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -202,7 +202,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -245,7 +245,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -253,7 +253,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeDelete($request))) { $response->header->status = RequestStatusCode::R_400; @@ -282,7 +282,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -290,7 +290,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeL11nUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -312,7 +312,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -320,7 +320,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeL11nDelete($request))) { $response->header->status = RequestStatusCode::R_400; @@ -340,7 +340,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -348,7 +348,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -370,7 +370,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -380,7 +380,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeTypeDelete($request))) { $response->header->status = RequestStatusCode::R_400; @@ -400,7 +400,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -408,7 +408,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -437,7 +437,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -445,7 +445,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { // @todo: I don't think values can be deleted? Only Attributes // However, It should be possible to remove UNUSED default values @@ -468,7 +468,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -476,7 +476,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueL11nUpdate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -498,7 +498,7 @@ final class ApiVehicleAttributeController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -506,7 +506,7 @@ final class ApiVehicleAttributeController extends Controller * * @since 1.0.0 */ - public function apiVehicleAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateAttributeValueL11nDelete($request))) { $response->header->status = RequestStatusCode::R_400; diff --git a/Controller/ApiVehicleController.php b/Controller/ApiVehicleController.php index 5fc3fe4..f708279 100755 --- a/Controller/ApiVehicleController.php +++ b/Controller/ApiVehicleController.php @@ -60,7 +60,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -68,7 +68,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiMilageCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiMilageCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateMilageCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -133,7 +133,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -141,7 +141,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiInspectionCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiInspectionCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateInspectionCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -203,7 +203,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -211,7 +211,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiVehicleTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleTypeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateVehicleTypeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -270,7 +270,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -278,7 +278,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiVehicleTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateVehicleTypeL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -339,7 +339,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -347,7 +347,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiFuelTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiFuelTypeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateFuelTypeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -406,7 +406,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -414,7 +414,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiFuelTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiFuelTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateFuelTypeL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -475,7 +475,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -483,7 +483,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiVehicleCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiVehicleCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateVehicleCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -666,7 +666,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -674,7 +674,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiMediaAddToVehicle(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiMediaAddToVehicle(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateMediaAddToVehicle($request))) { $response->header->status = RequestStatusCode::R_400; @@ -812,7 +812,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -820,7 +820,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiInspectionTypeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateInspectionTypeCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -879,7 +879,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -887,7 +887,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiInspectionTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateInspectionTypeL11nCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -948,7 +948,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -956,7 +956,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { if (!empty($val = $this->validateNoteCreate($request))) { $response->header->status = RequestStatusCode::R_400; @@ -1006,7 +1006,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -1014,7 +1014,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { // @todo: check permissions $this->app->moduleManager->get('Editor', 'Api')->apiEditorDocUpdate($request, $response, $data); @@ -1025,7 +1025,7 @@ final class ApiVehicleController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return void * @@ -1033,7 +1033,7 @@ final class ApiVehicleController extends Controller * * @since 1.0.0 */ - public function apiNoteDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + public function apiNoteDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { // @todo: check permissions $this->app->moduleManager->get('Editor', 'Api')->apiEditorDocDelete($request, $response, $data); diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 41853fe..79e03e2 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -47,14 +47,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type-list'); @@ -76,14 +76,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementDriverAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementDriverAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type-list'); @@ -105,14 +105,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementVehicleList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementVehicleList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -136,14 +136,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementDriverList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementDriverList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -165,14 +165,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementInspectionList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementInspectionList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -193,14 +193,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementInspectionTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementInspectionTypeList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -221,14 +221,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementInspectionCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementInspectionCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -249,14 +249,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementAttributeType(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementAttributeType(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type'); @@ -284,14 +284,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementDriverAttributeType(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementDriverAttributeType(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/FleetManagement/Theme/Backend/attribute-type'); @@ -319,14 +319,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementVehicleCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementVehicleCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -352,14 +352,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementDriverCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementDriverCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -385,14 +385,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementInspectionProfile(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementInspectionProfile(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -407,14 +407,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementVehicleProfile(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementVehicleProfile(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); @@ -503,14 +503,14 @@ final class BackendController extends Controller * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param array $data Generic data * * @return RenderableInterface Returns a renderable object * * @since 1.0.0 * @codeCoverageIgnore */ - public function viewFleetManagementDriverProfile(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewFleetManagementDriverProfile(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); From b3f3efac29debc66218733e72d8bd00d6e274f43 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Thu, 28 Sep 2023 02:53:01 +0000 Subject: [PATCH 82/89] fix autoloader --- tests/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index a33ea0b..6e280a8 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -97,7 +97,7 @@ final class Autoloader } foreach (self::$paths as $path) { - if (\is_file($file = $path . $class2 . '.php') && \stripos($file, $class3) !== false) { + if (($file = \realpath($path . $class2 . '.php')) !== false && \stripos($file, $class3) !== false) { include_once $file; return; From 36b77c009dd466c2389be7eedd673dbf961d4fad Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Thu, 28 Sep 2023 15:34:43 +0000 Subject: [PATCH 83/89] minor test fixes --- Admin/Routes/Web/Api.php | 8 ++++---- Controller/ApiVehicleController.php | 17 +++++++++++++++++ .../Api/ApiControllerAttributeTrait.php | 2 ++ tests/phpunit_default.xml | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index 387ac6e..21cc724 100644 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -74,7 +74,7 @@ return [ '^.*/fleet/vehicle/note.*$' => [ [ - 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleAttributeController:apiNoteCreate', + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleController:apiNoteCreate', 'verb' => RouteVerb::PUT, 'permission' => [ 'module' => Controller::NAME, @@ -83,7 +83,7 @@ return [ ], ], [ - 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleAttributeController:apiNoteEdit', + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleController:apiNoteEdit', 'verb' => RouteVerb::SET, 'permission' => [ 'module' => Controller::NAME, @@ -95,7 +95,7 @@ return [ '^.*/fleet/driver/note.*$' => [ [ - 'dest' => '\Modules\FleetManagement\Controller\ApiDriverAttributeController:apiNoteCreate', + 'dest' => '\Modules\FleetManagement\Controller\ApiDriverController:apiNoteCreate', 'verb' => RouteVerb::PUT, 'permission' => [ 'module' => Controller::NAME, @@ -104,7 +104,7 @@ return [ ], ], [ - 'dest' => '\Modules\FleetManagement\Controller\ApiDriverAttributeController:apiNoteEdit', + 'dest' => '\Modules\FleetManagement\Controller\ApiDriverController:apiNoteEdit', 'verb' => RouteVerb::SET, 'permission' => [ 'module' => Controller::NAME, diff --git a/Controller/ApiVehicleController.php b/Controller/ApiVehicleController.php index f708279..ade5276 100755 --- a/Controller/ApiVehicleController.php +++ b/Controller/ApiVehicleController.php @@ -55,6 +55,23 @@ use phpOMS\Message\ResponseAbstract; */ final class ApiVehicleController extends Controller { + /** + * Api method to create a vehicle + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiVehicleFind(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + } + /** * Api method to create a vehicle * diff --git a/tests/Controller/Api/ApiControllerAttributeTrait.php b/tests/Controller/Api/ApiControllerAttributeTrait.php index 48933c2..f366833 100644 --- a/tests/Controller/Api/ApiControllerAttributeTrait.php +++ b/tests/Controller/Api/ApiControllerAttributeTrait.php @@ -21,6 +21,8 @@ use phpOMS\Message\Http\HttpResponse; use phpOMS\Message\Http\RequestStatusCode; use phpOMS\Uri\HttpUri; +include_once __DIR__ . '/../../Autoloader.php'; + trait ApiControllerAttributeTrait { /** diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index f45f39b..349f4ee 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -48,6 +48,6 @@ - + From 0c94adead200d1624706b1ca1b0cb51d1c5f455e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Thu, 28 Sep 2023 17:00:27 +0000 Subject: [PATCH 84/89] fix tests --- tests/phpunit_default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index 349f4ee..f45f39b 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -48,6 +48,6 @@ - + From da3f1786538a43980f638e61d9badb05dc7499fa Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 29 Sep 2023 02:38:01 +0000 Subject: [PATCH 85/89] fix tests --- Admin/Routes/Web/Api.php | 4 +- Controller/ApiDriverController.php | 2 +- .../Api/ApiControllerAttributeTrait.php | 2 +- .../Api/ApiControllerVehicleTrait.php | 53 +++++++++++++++++++ tests/Controller/ApiControllerTest.php | 4 +- 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 tests/Controller/Api/ApiControllerVehicleTrait.php diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index 21cc724..f01c3b2 100644 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -83,7 +83,7 @@ return [ ], ], [ - 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleController:apiNoteEdit', + 'dest' => '\Modules\FleetManagement\Controller\ApiVehicleController:apiNoteUpdate', 'verb' => RouteVerb::SET, 'permission' => [ 'module' => Controller::NAME, @@ -104,7 +104,7 @@ return [ ], ], [ - 'dest' => '\Modules\FleetManagement\Controller\ApiDriverController:apiNoteEdit', + 'dest' => '\Modules\FleetManagement\Controller\ApiDriverController:apiNoteUpdate', 'verb' => RouteVerb::SET, 'permission' => [ 'module' => Controller::NAME, diff --git a/Controller/ApiDriverController.php b/Controller/ApiDriverController.php index d3b872e..a02bc67 100644 --- a/Controller/ApiDriverController.php +++ b/Controller/ApiDriverController.php @@ -657,7 +657,7 @@ final class ApiDriverController extends Controller * * @since 1.0.0 */ - public function apiNoteEdit(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { $this->app->moduleManager->get('Editor', 'Api')->apiEditorUpdate($request, $response, $data); diff --git a/tests/Controller/Api/ApiControllerAttributeTrait.php b/tests/Controller/Api/ApiControllerAttributeTrait.php index f366833..0091863 100644 --- a/tests/Controller/Api/ApiControllerAttributeTrait.php +++ b/tests/Controller/Api/ApiControllerAttributeTrait.php @@ -148,7 +148,7 @@ trait ApiControllerAttributeTrait $request = new HttpRequest(new HttpUri('')); $request->header->account = 1; - $request->setData('item', '1'); + $request->setData('ref', '1'); $request->setData('value', '1'); $request->setData('type', '1'); diff --git a/tests/Controller/Api/ApiControllerVehicleTrait.php b/tests/Controller/Api/ApiControllerVehicleTrait.php new file mode 100644 index 0000000..8c62084 --- /dev/null +++ b/tests/Controller/Api/ApiControllerVehicleTrait.php @@ -0,0 +1,53 @@ +execute(); + $vehicleTypeCount = \count($vehicleType); + $fuelTypeCount = FuelTypeMapper::count()->execute(); + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $LOREM = \array_slice(Text::LOREM_IPSUM, 0, 25); + $LOREM_COUNT = \count($LOREM) - 1; + + $request->header->account = 1; + $request->setData('name', \ucfirst(Text::LOREM_IPSUM[\mt_rand(0, $LOREM_COUNT - 1)])); + $request->setData('type', \mt_rand(1, $vehicleTypeCount)); + $request->setData('fuel', \mt_rand(1, $fuelTypeCount)); + $request->setData('status', 1); + + $this->module->apiVehicleCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->id); + } +} diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 59609bf..4f2ac37 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -16,6 +16,7 @@ namespace Modules\FleetManagement\tests\Controller; use Model\CoreSettings; use Modules\Admin\Models\AccountPermission; +use Modules\FleetManagement\tests\Controller\Api\ApiControllerVehicleTrait; use Modules\FleetManagement\tests\Controller\Api\ApiControllerAttributeTrait; use phpOMS\Account\Account; use phpOMS\Account\AccountManager; @@ -86,12 +87,13 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase $this->app->accountManager->add($account); $this->app->router = new WebRouter(); - $this->module = $this->app->moduleManager->get('FleetManagement', 'Api'); + $this->module = $this->app->moduleManager->get('FleetManagement', 'ApiVehicle'); $this->attrModule = $this->app->moduleManager->get('FleetManagement', 'ApiVehicleAttribute'); TestUtils::setMember($this->module, 'app', $this->app); TestUtils::setMember($this->attrModule, 'app', $this->app); } + use ApiControllerVehicleTrait; use ApiControllerAttributeTrait; } From 95ac868a5a76512fa85a3e9e1be8b5cd06a2aa4c Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 29 Sep 2023 04:32:27 +0000 Subject: [PATCH 86/89] fix composer file --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 986c8c8..2e47a08 100755 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "phan/phan": ">=3.2.6", "phploc/phploc": ">=7.0", "phpmetrics/phpmetrics": ">=2.8", - "rector/rector": ">=0.16.0" + "rector/rector": ">=0.18.0" }, "minimum-stability": "dev", "prefer-stable": true From 33d717365b514055dd111c97fd3301171700a0d2 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 29 Sep 2023 20:48:38 +0000 Subject: [PATCH 87/89] fix tests --- tests/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 6e280a8..1ac4f9b 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -79,7 +79,7 @@ final class Autoloader $class = \strtr($class, '_\\', '//'); if (\stripos($class, 'Web/Backend') !== false || \stripos($class, 'Web/Api') !== false) { - $class = \str_replace('Web/', 'Install/Application/', $class); + $class = \is_dir(__DIR__ . '/Web') ? $class : \str_replace('Web/', 'Karaka/Web/', $class); } $class2 = $class; From eb3dd77db4f8a1142b1e9b8cf2415b1f6209083e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 29 Sep 2023 21:57:42 +0000 Subject: [PATCH 88/89] fix coverage directories --- tests/phpunit_default.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index f45f39b..6462505 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -1,8 +1,13 @@ + + ../ + *vendor* + *MainRepository* + ../Admin/Install/Application ../phpOMS* ../tests* ../*/tests* From 36a75d639a0732e690bd76cc03de32dd0b4f4651 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 29 Sep 2023 22:35:38 +0000 Subject: [PATCH 89/89] fix coverage paths --- tests/phpunit_default.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index 6462505..ad47a51 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -5,9 +5,9 @@ ../ - *vendor* - *MainRepository* - ../Admin/Install/Application + ../vendor* + ../MainRepository* + ../Admin/Install/Application* ../phpOMS* ../tests* ../*/tests*