├── src
├── Template
│ ├── .github
│ │ ├── dependabot.yml
│ │ └── workflows
│ │ │ ├── phpcpd.yml
│ │ │ ├── phpcsfixer.yml
│ │ │ ├── unused.yml
│ │ │ ├── infection.yml
│ │ │ ├── psalm.yml
│ │ │ ├── deptrac.yml
│ │ │ ├── rector.yml
│ │ │ ├── phpstan.yml
│ │ │ └── phpunit.yml
│ ├── .editorconfig
│ ├── infection.json.dist
│ ├── phpstan.neon.dist
│ ├── psalm_autoload.php
│ ├── composer-unused.php
│ ├── psalm.xml
│ ├── .php-cs-fixer.dist.php
│ ├── phpunit.xml.dist
│ ├── phpunit9.xml.dist
│ ├── deptrac.yaml
│ ├── rector.php
│ └── Vagrantfile.dist
├── BADGES.md
├── docker
│ ├── docker-compose.yaml
│ └── README.md
└── ide
│ └── phpstorm
│ └── .phpstorm.meta.php
├── psalm_autoload.php
├── CONTRIBUTING.md
├── .php-cs-fixer.dist.php
├── psalm.xml
├── LICENSE
├── SECURITY.md
├── composer.json
├── rector.php
└── README.md
/src/Template/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: composer
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 |
9 | - package-ecosystem: "github-actions"
10 | directory: "/"
11 | schedule:
12 | interval: daily
13 |
--------------------------------------------------------------------------------
/src/Template/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This file is for unifying the coding style for different editors and IDEs.
2 | ; More information at http://editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | indent_size = 4
9 | indent_style = space
10 | end_of_line = lf
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
14 | [*.{yml,yaml}]
15 | indent_size = 2
16 |
--------------------------------------------------------------------------------
/src/Template/infection.json.dist:
--------------------------------------------------------------------------------
1 | {
2 | "source": {
3 | "directories": [
4 | "app/"
5 | ],
6 | "excludes": [
7 | "Config",
8 | "Database/Migrations",
9 | "Views"
10 | ]
11 | },
12 | "logs": {
13 | "text": "build/infection.log"
14 | },
15 | "mutators": {
16 | "@default": true
17 | },
18 | "bootstrap": "vendor/codeigniter4/framework/system/Test/bootstrap.php"
19 | }
20 |
--------------------------------------------------------------------------------
/psalm_autoload.php:
--------------------------------------------------------------------------------
1 | files()
9 | ->in([
10 | __DIR__ . '/src/',
11 | ])
12 | ->exclude('build')
13 | ->append([
14 | __FILE__,
15 | __DIR__ . '/rector.php',
16 | ]);
17 |
18 | $overrides = [];
19 |
20 | $options = [
21 | 'finder' => $finder,
22 | 'cacheFile' => 'build/.php-cs-fixer.cache',
23 | ];
24 |
25 | return Factory::create(new CodeIgniter4(), $overrides, $options)->forProjects();
26 |
--------------------------------------------------------------------------------
/src/Template/psalm_autoload.php:
--------------------------------------------------------------------------------
1 | $config
11 | // ->addNamedFilter(NamedFilter::fromString('symfony/config'))
12 | // ->addPatternFilter(PatternFilter::fromString('/symfony-.*/'))
13 | ->setAdditionalFilesFor('codeigniter4/framework', [
14 | ...Glob::glob(__DIR__ . '/vendor/codeigniter4/framework/system/Helpers/*.php'),
15 | ]);
16 |
--------------------------------------------------------------------------------
/src/Template/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Template/.php-cs-fixer.dist.php:
--------------------------------------------------------------------------------
1 | files()
9 | ->in([
10 | __DIR__ . '/app/',
11 | __DIR__ . '/tests/',
12 | ])
13 | ->exclude([
14 | 'build',
15 | 'Views',
16 | ])
17 | ->append([
18 | __FILE__,
19 | __DIR__ . '/rector.php',
20 | ]);
21 |
22 | $overrides = [
23 | // 'declare_strict_types' => true,
24 | // 'void_return' => true,
25 | ];
26 |
27 | $options = [
28 | 'finder' => $finder,
29 | 'cacheFile' => 'build/.php-cs-fixer.cache',
30 | ];
31 |
32 | return Factory::create(new CodeIgniter4(), $overrides, $options)->forProjects();
33 |
--------------------------------------------------------------------------------
/src/BADGES.md:
--------------------------------------------------------------------------------
1 | # Badges
2 |
3 | GitHub Actions (and some third-party tools) provide nice badges you can put in your README!
4 | Here are some examples from the devkit workflows (replace "organization/project" with your path).
5 |
6 | [](https://github.com/organization/project/actions/workflows/phpunit.yml)
7 | [](https://github.com/organization/project/actions/workflows/phpstan.yml)
8 | [](https://github.com/organization/project/actions/workflows/deptrac.yml)
9 | [](https://coveralls.io/github/organization/project?branch=develop)
10 |
--------------------------------------------------------------------------------
/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/phpcpd.yml:
--------------------------------------------------------------------------------
1 | name: PHPCPD
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - '.github/workflows/phpcpd.yml'
10 | push:
11 | branches:
12 | - develop
13 | paths:
14 | - '**.php'
15 | - '.github/workflows/phpcpd.yml'
16 |
17 | jobs:
18 | build:
19 | name: Code Copy-Paste Detection
20 | runs-on: ubuntu-latest
21 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
22 |
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@v4
26 |
27 | - name: Setup PHP
28 | uses: shivammathur/setup-php@v2
29 | with:
30 | php-version: '8.1'
31 | tools: phpcpd
32 | extensions: dom, mbstring
33 | coverage: none
34 |
35 | - name: Detect duplicate code
36 | run: phpcpd app/ tests/
37 |
--------------------------------------------------------------------------------
/src/docker/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | postgres:
5 | image: postgres:13-alpine
6 | ports:
7 | - "5432:5432"
8 | environment:
9 | POSTGRES_DB: test
10 | POSTGRES_USER: postgres
11 | POSTGRES_PASSWORD: postgres
12 |
13 | mssql:
14 | image: mcr.microsoft.com/mssql/server:2019-latest
15 | ports:
16 | - "1433:1433"
17 | environment:
18 | SA_PASSWORD: 1Secure*Password1
19 | ACCEPT_EULA: Y
20 | MSSQL_PID: Developer
21 |
22 | mysql:
23 | image: mysql:8.0
24 | ports:
25 | - "3306:3306"
26 | environment:
27 | MYSQL_ROOT_PASSWORD: mysql
28 | MYSQL_DATABASE: test
29 | MYSQL_USER: mysql
30 | MYSQL_PASSWORD: mysql
31 |
32 | oracle:
33 | image: gvenzl/oracle-xe:21
34 | ports:
35 | - "1521:1521"
36 | environment:
37 | ORACLE_RANDOM_PASSWORD: true
38 | APP_USER: ORACLE
39 | APP_USER_PASSWORD: ORACLE
40 |
41 | mailhog:
42 | image: mailhog/mailhog
43 | ports:
44 | - 1025:1025
45 | - 8025:8025
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 CodeIgniter Foundation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | The development team and community take all security issues seriously. **Please do not make public any uncovered flaws.**
4 |
5 | ## Reporting a Vulnerability
6 |
7 | Thank you for improving the security of our code! Any assistance in removing security flaws will be acknowledged.
8 |
9 | **Please report security flaws by emailing the development team directly: security@codeigniter.com**.
10 |
11 | The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating
12 | the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the
13 | progress towards a fix and full announcement, and may ask for additional information or guidance.
14 |
15 | ## Disclosure Policy
16 |
17 | When the security team receives a security bug report, they will assign it to a primary handler.
18 | This person will coordinate the fix and release process, involving the following steps:
19 |
20 | - Confirm the problem and determine the affected versions.
21 | - Audit code to find any potential similar problems.
22 | - Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible.
23 |
24 | ## Comments on this Policy
25 |
26 | If you have suggestions on how this process could be improved please submit a Pull Request.
27 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/phpcsfixer.yml:
--------------------------------------------------------------------------------
1 | name: PHPCSFixer
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - '.github/workflows/phpcsfixer.yml'
10 | push:
11 | branches:
12 | - develop
13 | paths:
14 | - '**.php'
15 | - '.github/workflows/phpcsfixer.yml'
16 |
17 | jobs:
18 | build:
19 | name: Coding Standards
20 | runs-on: ubuntu-latest
21 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
22 |
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@v4
26 |
27 | - name: Set up PHP
28 | uses: shivammathur/setup-php@v2
29 | with:
30 | php-version: '8.1'
31 | extensions: json, tokenizer
32 | coverage: none
33 | env:
34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 |
36 | - name: Get composer cache directory
37 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
38 |
39 | - name: Cache composer dependencies
40 | uses: actions/cache@v4
41 | with:
42 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
43 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
44 | restore-keys: ${{ runner.os }}-composer-
45 |
46 | - name: Install dependencies
47 | run: |
48 | if [ -f composer.lock ]; then
49 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
50 | else
51 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
52 | fi
53 |
54 | - name: Check code for standards compliance
55 | run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --using-cache=no --diff
56 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/unused.yml:
--------------------------------------------------------------------------------
1 | name: Unused
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - 'composer.*'
10 | - '.github/workflows/unused.yml'
11 | push:
12 | branches:
13 | - develop
14 | paths:
15 | - '**.php'
16 | - 'composer.*'
17 | - '.github/workflows/unused.yml'
18 |
19 | jobs:
20 | build:
21 | name: Unused Package Detection
22 | runs-on: ubuntu-latest
23 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@v4
28 |
29 | - name: Setup PHP
30 | uses: shivammathur/setup-php@v2
31 | with:
32 | php-version: '8.1'
33 | tools: composer, composer-unused
34 | extensions: intl, json, mbstring, xml
35 | coverage: none
36 | env:
37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38 |
39 | - name: Get composer cache directory
40 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
41 |
42 | - name: Cache composer dependencies
43 | uses: actions/cache@v4
44 | with:
45 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
46 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
47 | restore-keys: ${{ runner.os }}-composer-
48 |
49 | - name: Install dependencies
50 | run: |
51 | if [ -f composer.lock ]; then
52 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
53 | else
54 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
55 | fi
56 |
57 | - name: Detect unused packages
58 | run: composer-unused -vvv --output-format=github --ansi --no-interaction --no-progress
59 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/infection.yml:
--------------------------------------------------------------------------------
1 | name: Infection
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - 'composer.*'
10 | - 'phpunit*'
11 | - '.github/workflows/infection.yml'
12 |
13 | jobs:
14 | main:
15 | name: Mutation Testing
16 | runs-on: ubuntu-latest
17 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
18 |
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v4
22 |
23 | - name: Set up PHP
24 | uses: shivammathur/setup-php@v2
25 | with:
26 | php-version: '8.2'
27 | tools: infection, phpunit
28 | extensions: intl, json, mbstring, gd, xml, sqlite3
29 | coverage: xdebug
30 | env:
31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 |
33 | - name: Set up problem matchers for PHPUnit
34 | run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
35 |
36 | - name: Configure matchers
37 | uses: mheap/phpunit-matcher-action@v1
38 |
39 | - name: Get composer cache directory
40 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
41 |
42 | - name: Cache composer dependencies
43 | uses: actions/cache@v4
44 | with:
45 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
46 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
47 | restore-keys: ${{ runner.os }}-composer-
48 |
49 | - name: Install dependencies
50 | run: |
51 | if [ -f composer.lock ]; then
52 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
53 | else
54 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
55 | fi
56 |
57 | - name: Run Infection for added files only
58 | run: |
59 | git fetch --depth=1 origin $GITHUB_BASE_REF
60 | infection --threads=max --git-diff-lines --git-diff-base=origin/$GITHUB_BASE_REF --ignore-msi-with-no-mutations --only-covered --logger-github
61 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/psalm.yml:
--------------------------------------------------------------------------------
1 | name: Psalm
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - 'composer.*'
10 | - 'psalm*'
11 | - '.github/workflows/psalm.yml'
12 | push:
13 | branches:
14 | - develop
15 | paths:
16 | - '**.php'
17 | - 'composer.*'
18 | - 'psalm*'
19 | - '.github/workflows/psalm.yml'
20 |
21 | jobs:
22 | build:
23 | name: Psalm Analysis
24 | runs-on: ubuntu-latest
25 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
26 |
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v4
30 |
31 | - name: Setup PHP
32 | uses: shivammathur/setup-php@v2
33 | with:
34 | php-version: '8.1'
35 | tools: phpstan, phpunit
36 | extensions: intl, json, mbstring, xml
37 | coverage: none
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 |
41 | - name: Get composer cache directory
42 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
43 |
44 | - name: Cache composer dependencies
45 | uses: actions/cache@v4
46 | with:
47 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
48 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
49 | restore-keys: ${{ runner.os }}-composer-
50 |
51 | - name: Create Psalm cache directory
52 | run: mkdir -p build/psalm
53 |
54 | - name: Cache Psalm results
55 | uses: actions/cache@v4
56 | with:
57 | path: build/psalm
58 | key: ${{ runner.os }}-psalm-${{ github.sha }}
59 | restore-keys: ${{ runner.os }}-psalm-
60 |
61 | - name: Install dependencies
62 | run: |
63 | if [ -f composer.lock ]; then
64 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
65 | else
66 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
67 | fi
68 |
69 | - name: Run Psalm analysis
70 | run: vendor/bin/psalm
71 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/deptrac.yml:
--------------------------------------------------------------------------------
1 | name: Deptrac
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - 'composer.*'
10 | - 'depfile.yaml'
11 | - '.github/workflows/deptrac.yml'
12 | push:
13 | branches:
14 | - develop
15 | paths:
16 | - '**.php'
17 | - 'composer.*'
18 | - 'depfile.yaml'
19 | - '.github/workflows/deptrac.yml'
20 |
21 | jobs:
22 | build:
23 | name: Dependency Tracing
24 | runs-on: ubuntu-latest
25 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
26 |
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v4
30 |
31 | - name: Set up PHP
32 | uses: shivammathur/setup-php@v2
33 | with:
34 | php-version: '8.1'
35 | extensions: intl, json, mbstring, xml
36 | coverage: none
37 | env:
38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | - name: Get composer cache directory
41 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
42 |
43 | - name: Cache composer dependencies
44 | uses: actions/cache@v4
45 | with:
46 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
47 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
48 | restore-keys: ${{ runner.os }}-composer-
49 |
50 | - name: Create Deptrac cache directory
51 | run: mkdir -p build/
52 |
53 | - name: Cache Deptrac results
54 | uses: actions/cache@v4
55 | with:
56 | path: build
57 | key: ${{ runner.os }}-deptrac-${{ github.sha }}
58 | restore-keys: ${{ runner.os }}-deptrac-
59 |
60 | - name: Install dependencies
61 | run: |
62 | if [ -f composer.lock ]; then
63 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
64 | else
65 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
66 | fi
67 |
68 | - name: Trace dependencies
69 | run: |
70 | composer require --dev qossmic/deptrac-shim
71 | vendor/bin/deptrac analyze --cache-file=build/deptrac.cache
72 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/rector.yml:
--------------------------------------------------------------------------------
1 | name: Rector
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - 'composer.*'
10 | - 'rector.php'
11 | - '.github/workflows/rector.yml'
12 | push:
13 | branches:
14 | - develop
15 | paths:
16 | - '**.php'
17 | - 'composer.*'
18 | - 'rector.php'
19 | - '.github/workflows/rector.yml'
20 |
21 | jobs:
22 | build:
23 | name: PHP ${{ matrix.php-versions }} Rector Analysis
24 | runs-on: ubuntu-latest
25 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
26 | strategy:
27 | fail-fast: false
28 | matrix:
29 | php-versions: ['8.1', '8.2', '8.3', '8.4']
30 |
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@v4
34 |
35 | - name: Set up PHP
36 | uses: shivammathur/setup-php@v2
37 | with:
38 | php-version: ${{ matrix.php-versions }}
39 | tools: phpstan
40 | extensions: intl, json, mbstring, xml
41 | coverage: none
42 | env:
43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44 |
45 | - name: Get composer cache directory
46 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
47 |
48 | - name: Cache composer dependencies
49 | uses: actions/cache@v4
50 | with:
51 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
52 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
53 | restore-keys: ${{ runner.os }}-composer-
54 |
55 | - name: Install dependencies
56 | run: |
57 | if [ -f composer.lock ]; then
58 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
59 | else
60 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
61 | fi
62 |
63 | - name: Rector Cache
64 | uses: actions/cache@v4
65 | with:
66 | path: /tmp/rector
67 | key: ${{ runner.os }}-rector-${{ github.run_id }}
68 | restore-keys: ${{ runner.os }}-rector-
69 |
70 | - run: mkdir -p /tmp/rector
71 |
72 | - name: Analyze for refactoring
73 | run: vendor/bin/rector process --dry-run --no-progress-bar
74 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/phpstan.yml:
--------------------------------------------------------------------------------
1 | name: PHPStan
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - 'composer.*'
10 | - 'phpstan*'
11 | - '.github/workflows/phpstan.yml'
12 | push:
13 | branches:
14 | - develop
15 | paths:
16 | - '**.php'
17 | - 'composer.*'
18 | - 'phpstan*'
19 | - '.github/workflows/phpstan.yml'
20 |
21 | jobs:
22 | build:
23 | name: PHP ${{ matrix.php-versions }} Static Analysis
24 | runs-on: ubuntu-latest
25 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
26 | strategy:
27 | fail-fast: false
28 | matrix:
29 | php-versions: ['8.1', '8.2', '8.3', '8.4']
30 |
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@v4
34 |
35 | - name: Setup PHP
36 | uses: shivammathur/setup-php@v2
37 | with:
38 | php-version: ${{ matrix.php-versions }}
39 | tools: phpstan, phpunit
40 | extensions: intl, json, mbstring, xml
41 | coverage: none
42 | env:
43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44 |
45 | - name: Get composer cache directory
46 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
47 |
48 | - name: Cache composer dependencies
49 | uses: actions/cache@v4
50 | with:
51 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
52 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
53 | restore-keys: ${{ runner.os }}-composer-
54 |
55 | - name: Create PHPStan cache directory
56 | run: mkdir -p build/phpstan
57 |
58 | - name: Cache PHPStan results
59 | uses: actions/cache@v4
60 | with:
61 | path: build/phpstan
62 | key: ${{ runner.os }}-phpstan-${{ github.sha }}
63 | restore-keys: ${{ runner.os }}-phpstan-
64 |
65 | - name: Install dependencies
66 | run: |
67 | if [ -f composer.lock ]; then
68 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
69 | else
70 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
71 | fi
72 |
73 | - name: Run static analysis
74 | run: vendor/bin/phpstan analyze
75 |
--------------------------------------------------------------------------------
/src/docker/README.md:
--------------------------------------------------------------------------------
1 | # Docker for development
2 |
3 | ## Included
4 |
5 | - PostgreSQL 13
6 | - SQL Server 2019
7 | - MySQL 8.0
8 | - Oracle Database 21c XE
9 | - MailHog
10 |
11 | ## Usage
12 |
13 | ```
14 | $ docker-compose up -d
15 | ```
16 |
17 | ```
18 | $ docker-compose down
19 | ```
20 |
21 | ## Config
22 |
23 | ### PostgreSQL
24 |
25 | #### .env
26 |
27 | ```
28 | database.default.hostname = localhost
29 | database.default.database = test
30 | database.default.username = postgres
31 | database.default.password = postgres
32 | database.default.DBDriver = Postgre
33 | database.default.port = 5432
34 | ```
35 |
36 | ### SQL Server
37 |
38 | #### Create Database
39 |
40 | ```
41 | $ docker-compose exec mssql bash
42 | mssql@aaa8e9411491:/$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "1Secure*Password1" -Q "CREATE DATABASE test"
43 | ```
44 |
45 | #### .env
46 |
47 | ```
48 | database.default.hostname = localhost
49 | database.default.database = test
50 | database.default.username = sa
51 | database.default.password = 1Secure*Password1
52 | database.default.DBDriver = SQLSRV
53 | database.default.port = 1433
54 | ```
55 |
56 | See https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-ver15&pivots=cs1-bash
57 |
58 | ### MySQL
59 |
60 | #### .env
61 |
62 | ```
63 | database.default.hostname = localhost
64 | database.default.database = test
65 | database.default.username = mysql
66 | database.default.password = mysql
67 | database.default.DBDriver = MySQLi
68 | database.default.port = 3306
69 | ```
70 |
71 | ### Oracle
72 |
73 | #### .env
74 |
75 | ```
76 | NLS_LANG = 'AMERICAN_AMERICA.UTF8'
77 | NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
78 | NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
79 | NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
80 | database.default.DSN = localhost:1521/XEPDB1
81 | database.default.hostname =
82 | database.default.database =
83 | database.default.username = ORACLE
84 | database.default.password = ORACLE
85 | database.default.DBDriver = OCI8
86 | database.default.charset = AL32UTF8
87 | database.default.port = 1521
88 | ```
89 |
90 | ### MailHog
91 |
92 | #### .env
93 |
94 | ```
95 | email.protocol = smtp
96 | email.SMTPHost = localhost
97 | email.SMTPPort = 1025
98 | email.SMTPCrypto =
99 | email.fromEmail = info@example.com
100 | ```
101 |
102 | Navigate to http://localhost:8025/ to see sent mails.
103 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "codeigniter4/devkit",
3 | "description": "Development toolkit for CodeIgniter libraries and projects",
4 | "license": "MIT",
5 | "type": "library",
6 | "keywords": [
7 | "codeigniter",
8 | "codeigniter4",
9 | "devkit",
10 | "toolkit",
11 | "development",
12 | "tools",
13 | "static analysis"
14 | ],
15 | "authors": [
16 | {
17 | "name": "Matthew Gatner",
18 | "email": "mgatner@tattersoftware.com",
19 | "homepage": "https://tattersoftware.com",
20 | "role": "Developer"
21 | }
22 | ],
23 | "homepage": "https://github.com/codeigniter4/devkit",
24 | "require": {
25 | "php": "^8.1",
26 | "codeigniter/coding-standard": "^1.5",
27 | "fakerphp/faker": "^1.9",
28 | "mikey179/vfsstream": "^1.6",
29 | "nexusphp/cs-config": "^3.6",
30 | "nexusphp/tachycardia": "^2.0",
31 | "phpstan/extension-installer": "^1.1",
32 | "phpstan/phpstan": "^2.0",
33 | "phpstan/phpstan-deprecation-rules": "^2.0",
34 | "phpstan/phpstan-phpunit": "^2.0",
35 | "phpunit/phpunit": "^10.5 || ^11.5",
36 | "rector/rector": "^2.0",
37 | "roave/security-advisories": "dev-latest",
38 | "vimeo/psalm": "^5.0 || ^6.0"
39 | },
40 | "require-dev": {
41 | "codeigniter4/framework": "^4.1",
42 | "icanhazstring/composer-unused": "dev-main"
43 | },
44 | "minimum-stability": "dev",
45 | "prefer-stable": true,
46 | "config": {
47 | "allow-plugins": {
48 | "phpstan/extension-installer": true
49 | }
50 | },
51 | "scripts": {
52 | "analyze": [
53 | "Composer\\Config::disableProcessTimeout",
54 | "phpstan analyze",
55 | "psalm",
56 | "rector process --dry-run"
57 | ],
58 | "ci": [
59 | "Composer\\Config::disableProcessTimeout",
60 | "@cs",
61 | "@deduplicate",
62 | "@inspect",
63 | "@analyze",
64 | "@test"
65 | ],
66 | "cs": "php-cs-fixer fix --ansi --verbose --dry-run --diff",
67 | "cs-fix": "php-cs-fixer fix --ansi --verbose --diff",
68 | "deduplicate": "phpcpd app/ src/",
69 | "inspect": "deptrac analyze --cache-file=build/deptrac.cache",
70 | "mutate": "infection --threads=2 --skip-initial-tests --coverage=build/phpunit",
71 | "sa": "@analyze",
72 | "style": "@cs-fix",
73 | "test": "phpunit"
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/Template/.github/workflows/phpunit.yml:
--------------------------------------------------------------------------------
1 | name: PHPUnit
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - develop
7 | paths:
8 | - '**.php'
9 | - 'composer.*'
10 | - 'phpunit*'
11 | - '.github/workflows/phpunit.yml'
12 | push:
13 | branches:
14 | - develop
15 | paths:
16 | - '**.php'
17 | - 'composer.*'
18 | - 'phpunit*'
19 | - '.github/workflows/phpunit.yml'
20 |
21 | jobs:
22 | main:
23 | name: PHP ${{ matrix.php-versions }} Unit Tests
24 | runs-on: ubuntu-latest
25 | if: (! contains(github.event.head_commit.message, '[ci skip]'))
26 | strategy:
27 | matrix:
28 | php-versions: ['8.1', '8.2', '8.3', '8.4']
29 |
30 | steps:
31 | - name: Checkout
32 | uses: actions/checkout@v4
33 |
34 | - name: Set up PHP
35 | uses: shivammathur/setup-php@v2
36 | with:
37 | php-version: ${{ matrix.php-versions }}
38 | tools: composer, phive, phpunit
39 | extensions: intl, json, mbstring, gd, xdebug, xml, sqlite3
40 | coverage: xdebug
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 |
44 | - name: Get composer cache directory
45 | run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV
46 |
47 | - name: Cache composer dependencies
48 | uses: actions/cache@v4
49 | with:
50 | path: ${{ env.COMPOSER_CACHE_FILES_DIR }}
51 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
52 | restore-keys: ${{ runner.os }}-composer-
53 |
54 | - name: Install dependencies
55 | run: |
56 | if [ -f composer.lock ]; then
57 | composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
58 | else
59 | composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
60 | fi
61 |
62 | - name: Test with PHPUnit
63 | run: vendor/bin/phpunit --verbose --coverage-text
64 | env:
65 | TERM: xterm-256color
66 | TACHYCARDIA_MONITOR_GA: enabled
67 |
68 | - if: matrix.php-versions == '8.1'
69 | name: Run Coveralls
70 | continue-on-error: true
71 | run: |
72 | sudo phive --no-progress install --global --trust-gpg-keys E82B2FB314E9906E php-coveralls
73 | php-coveralls --verbose --coverage_clover=build/phpunit/clover.xml --json_path build/phpunit/coveralls-upload.json
74 | env:
75 | COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76 | COVERALLS_PARALLEL: true
77 | COVERALLS_FLAG_NAME: PHP ${{ matrix.php-versions }}
78 |
79 | coveralls:
80 | needs: [main]
81 | name: Coveralls Finished
82 | runs-on: ubuntu-latest
83 | steps:
84 | - name: Upload Coveralls results
85 | uses: coverallsapp/github-action@master
86 | continue-on-error: true
87 | with:
88 | github-token: ${{ secrets.GITHUB_TOKEN }}
89 | parallel-finished: true
90 |
--------------------------------------------------------------------------------
/src/Template/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ./tests
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
64 |
65 |
66 |
67 | ./app/
68 |
69 |
70 | ./app/Config
71 | ./app/Views
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/Template/phpunit9.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
24 | ./app/
25 |
26 |
27 | ./app/Config
28 | ./app/Views
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | ./tests
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 0.50
51 |
52 |
53 | 30
54 |
55 |
56 | 2
57 |
58 |
59 | true
60 |
61 |
62 | true
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/src/ide/phpstorm/.phpstorm.meta.php:
--------------------------------------------------------------------------------
1 | \CodeIgniter\Autoloader\Autoloader::class,
6 | 'cache' => \CodeIgniter\Cache\CacheInterface::class,
7 | 'clirequest' => \CodeIgniter\HTTP\CLIRequest::class,
8 | 'codeigniter' => \CodeIgniter\CodeIgniter::class,
9 | 'commands' => \CodeIgniter\CLI\Commands::class,
10 | 'csp' => \CodeIgniter\HTTP\ContentSecurityPolicy::class,
11 | 'curlrequest' => \CodeIgniter\HTTP\CURLRequest::class,
12 | 'email' => \CodeIgniter\Email\Email::class,
13 | 'encrypter' => \CodeIgniter\Encryption\EncrypterInterface::class,
14 | 'exceptions' => \CodeIgniter\Debug\Exceptions::class,
15 | 'filters' => \CodeIgniter\Filters\Filters::class,
16 | 'format' => \CodeIgniter\Format\Format::class,
17 | 'honeypot' => \CodeIgniter\Honeypot\Honeypot::class,
18 | 'image' => \CodeIgniter\Images\Handlers\BaseHandler::class,
19 | 'iterator' => \CodeIgniter\Debug\Iterator::class,
20 | 'language' => \CodeIgniter\Language\Language::class,
21 | 'locator' => \CodeIgniter\Autoloader\FileLocator::class,
22 | 'logger' => \CodeIgniter\Log\Logger::class,
23 | 'migrations' => \CodeIgniter\Database\MigrationRunner::class,
24 | 'negotiator' => \CodeIgniter\HTTP\Negotiate::class,
25 | 'pager' => \CodeIgniter\Pager\Pager::class,
26 | 'parser' => \CodeIgniter\View\Parser::class,
27 | 'redirectresponse' => \CodeIgniter\HTTP\RedirectResponse::class,
28 | 'renderer' => \CodeIgniter\View\View::class,
29 | 'request' => \CodeIgniter\HTTP\IncomingRequest::class,
30 | 'response' => \CodeIgniter\HTTP\Response::class,
31 | 'router' => \CodeIgniter\Router\Router::class,
32 | 'routes' => \CodeIgniter\Router\RouteCollection::class,
33 | 'security' => \CodeIgniter\Security\Security::class,
34 | 'session' => \CodeIgniter\Session\Session::class,
35 | 'throttler' => \CodeIgniter\Throttle\Throttler::class,
36 | 'timer' => \CodeIgniter\Debug\Timer::class,
37 | 'toolbar' => \CodeIgniter\Debug\Toolbar::class,
38 | 'typography' => \CodeIgniter\Typography\Typography::class,
39 | 'uri' => \CodeIgniter\HTTP\URI::class,
40 | 'validation' => \CodeIgniter\Validation\Validation::class,
41 | 'viewcell' => \CodeIgniter\View\Cell::class,
42 | ]));
43 |
44 | override(\config(), map([
45 | 'App' => \Config\App::class,
46 | 'Autoload' => \Config\Autoload::class,
47 | 'Cache' => \Config\Cache::class,
48 | 'ContentSecurityPolicy' => \Config\ContentSecurityPolicy::class,
49 | 'Cookie' => \Config\Cookie::class,
50 | 'CURLRequest' => \Config\CURLRequest::class,
51 | 'Database' => \Config\Database::class,
52 | 'DocTypes' => \Config\DocTypes::class,
53 | 'Email' => \Config\Email::class,
54 | 'Encryption' => \Config\Encryption::class,
55 | 'Exceptions' => \Config\Exceptions::class,
56 | 'Feature' => \Config\Feature::class,
57 | 'Filters' => \Config\Filters::class,
58 | 'ForeignCharacters' => \Config\ForeignCharacters::class,
59 | 'Format' => \Config\Format::class,
60 | 'Generators' => \Config\Generators::class,
61 | 'Honeypot' => \Config\Honeypot::class,
62 | 'Images' => \Config\Images::class,
63 | 'Kint' => \Config\Kint::class,
64 | 'Logger' => \Config\Logger::class,
65 | 'Migrations' => \Config\Migrations::class,
66 | 'Mimes' => \Config\Mimes::class,
67 | 'Modules' => \Config\Modules::class,
68 | 'Pager' => \Config\Pager::class,
69 | 'Publisher' => \Config\Publisher::class,
70 | 'Security' => \Config\Security::class,
71 | 'Services' => \Config\Services::class,
72 | 'Toolbar' => \Config\Toolbar::class,
73 | 'UserAgents' => \Config\UserAgents::class,
74 | 'Validation' => \Config\Validation::class,
75 | 'View' => \Config\View::class,
76 | ]));
77 | }
78 |
--------------------------------------------------------------------------------
/src/Template/deptrac.yaml:
--------------------------------------------------------------------------------
1 | deptrac:
2 | paths:
3 | - ./app/
4 | - ./vendor/codeigniter4/framework/system/
5 | exclude_files:
6 | - '#.*test.*#i'
7 | layers:
8 | - name: Model
9 | collectors:
10 | - type: bool
11 | must:
12 | - type: class
13 | value: .*[A-Za-z]+Model$
14 | must_not:
15 | - type: directory
16 | value: vendor/.*
17 | - name: Vendor Model
18 | collectors:
19 | - type: bool
20 | must:
21 | - type: class
22 | value: .*[A-Za-z]+Model$
23 | - type: directory
24 | value: vendor/.*
25 | - name: Controller
26 | collectors:
27 | - type: bool
28 | must:
29 | - type: class
30 | value: .*\/Controllers\/.*
31 | must_not:
32 | - type: directory
33 | value: vendor/.*
34 | - name: Vendor Controller
35 | collectors:
36 | - type: bool
37 | must:
38 | - type: class
39 | value: .*\/Controllers\/.*
40 | - type: directory
41 | value: vendor/.*
42 | - name: Config
43 | collectors:
44 | - type: bool
45 | must:
46 | - type: directory
47 | value: app/Config/.*
48 | must_not:
49 | - type: class
50 | value: .*Services
51 | - type: directory
52 | value: vendor/.*
53 | - name: Vendor Config
54 | collectors:
55 | - type: bool
56 | must:
57 | - type: directory
58 | value: vendor/.*/Config/.*
59 | must_not:
60 | - type: class
61 | value: .*Services
62 | - name: Entity
63 | collectors:
64 | - type: bool
65 | must:
66 | - type: directory
67 | value: app/Entities/.*
68 | must_not:
69 | - type: directory
70 | value: vendor/.*
71 | - name: Vendor Entity
72 | collectors:
73 | - type: bool
74 | must:
75 | - type: directory
76 | value: vendor/.*/Entities/.*
77 | - name: View
78 | collectors:
79 | - type: bool
80 | must:
81 | - type: directory
82 | value: app/Views/.*
83 | must_not:
84 | - type: directory
85 | value: vendor/.*
86 | - name: Vendor View
87 | collectors:
88 | - type: bool
89 | must:
90 | - type: directory
91 | value: vendor/.*/Views/.*
92 | - name: Service
93 | collectors:
94 | - type: class
95 | value: .*Services.*
96 | ruleset:
97 | Entity:
98 | - Config
99 | - Model
100 | - Service
101 | - Vendor Config
102 | - Vendor Entity
103 | - Vendor Model
104 | Config:
105 | - Service
106 | - Vendor Config
107 | Model:
108 | - Config
109 | - Entity
110 | - Service
111 | - Vendor Config
112 | - Vendor Entity
113 | - Vendor Model
114 | Service:
115 | - Config
116 | - Vendor Config
117 |
118 | # Ignore anything in the Vendor layers
119 | Vendor Model:
120 | - Config
121 | - Service
122 | - Vendor Config
123 | - Vendor Controller
124 | - Vendor Entity
125 | - Vendor Model
126 | - Vendor View
127 | Vendor Controller:
128 | - Service
129 | - Vendor Config
130 | - Vendor Controller
131 | - Vendor Entity
132 | - Vendor Model
133 | - Vendor View
134 | Vendor Config:
135 | - Config
136 | - Service
137 | - Vendor Config
138 | - Vendor Controller
139 | - Vendor Entity
140 | - Vendor Model
141 | - Vendor View
142 | Vendor Entity:
143 | - Service
144 | - Vendor Config
145 | - Vendor Controller
146 | - Vendor Entity
147 | - Vendor Model
148 | - Vendor View
149 | Vendor View:
150 | - Service
151 | - Vendor Config
152 | - Vendor Controller
153 | - Vendor Entity
154 | - Vendor Model
155 | - Vendor View
156 | skip_violations: []
157 |
--------------------------------------------------------------------------------
/rector.php:
--------------------------------------------------------------------------------
1 | sets([
49 | SetList::DEAD_CODE,
50 | LevelSetList::UP_TO_PHP_74,
51 | PHPUnitSetList::PHPUNIT_CODE_QUALITY,
52 | PHPUnitSetList::PHPUNIT_100,
53 | ]);
54 |
55 | $rectorConfig->parallel();
56 |
57 | // Github action cache
58 | $rectorConfig->cacheClass(FileCacheStorage::class);
59 | if (is_dir('/tmp')) {
60 | $rectorConfig->cacheDirectory('/tmp/rector');
61 | }
62 |
63 | // The paths to refactor (can also be supplied with CLI arguments)
64 | $rectorConfig->paths([
65 | __DIR__ . '/src/',
66 | ]);
67 |
68 | // Include Composer's autoload - required for global execution, remove if running locally
69 | $rectorConfig->autoloadPaths([
70 | __DIR__ . '/vendor/autoload.php',
71 | ]);
72 |
73 | // Do you need to include constants, class aliases, or a custom autoloader?
74 | $rectorConfig->bootstrapFiles([
75 | realpath(getcwd()) . '/vendor/codeigniter4/framework/system/Test/bootstrap.php',
76 | ]);
77 |
78 | if (is_file(__DIR__ . '/phpstan.neon.dist')) {
79 | $rectorConfig->phpstanConfig(__DIR__ . '/phpstan.neon.dist');
80 | }
81 |
82 | // Set the target version for refactoring
83 | $rectorConfig->phpVersion(PhpVersion::PHP_74);
84 |
85 | // Auto-import fully qualified class names
86 | $rectorConfig->importNames();
87 |
88 | // Are there files or rules you need to skip?
89 | $rectorConfig->skip([
90 | __DIR__ . '/src/Views',
91 |
92 | StringifyStrNeedlesRector::class,
93 | YieldDataProviderRector::class,
94 |
95 | // Note: requires php 8
96 | RemoveUnusedPromotedPropertyRector::class,
97 | AnnotationWithValueToAttributeRector::class,
98 |
99 | // May load view files directly when detecting classes
100 | StringClassNameToClassConstantRector::class,
101 | ]);
102 |
103 | // auto import fully qualified class names
104 | $rectorConfig->importNames();
105 |
106 | $rectorConfig->rule(SimplifyUselessVariableRector::class);
107 | $rectorConfig->rule(RemoveAlwaysElseRector::class);
108 | $rectorConfig->rule(CountArrayToEmptyArrayComparisonRector::class);
109 | $rectorConfig->rule(ChangeNestedForeachIfsToEarlyContinueRector::class);
110 | $rectorConfig->rule(ChangeIfElseValueAssignToEarlyReturnRector::class);
111 | $rectorConfig->rule(SimplifyStrposLowerRector::class);
112 | $rectorConfig->rule(CombineIfRector::class);
113 | $rectorConfig->rule(SimplifyIfReturnBoolRector::class);
114 | $rectorConfig->rule(InlineIfToExplicitIfRector::class);
115 | $rectorConfig->rule(PreparedValueToEarlyReturnRector::class);
116 | $rectorConfig->rule(ShortenElseIfRector::class);
117 | $rectorConfig->rule(SimplifyIfElseToTernaryRector::class);
118 | $rectorConfig->rule(UnusedForeachValueToArrayKeysRector::class);
119 | $rectorConfig->rule(ChangeArrayPushToArrayAssignRector::class);
120 | $rectorConfig->rule(UnnecessaryTernaryExpressionRector::class);
121 | $rectorConfig->rule(SimplifyRegexPatternRector::class);
122 | $rectorConfig->rule(FuncGetArgsToVariadicParamRector::class);
123 | $rectorConfig->rule(MakeInheritedMethodVisibilitySameAsParentRector::class);
124 | $rectorConfig->rule(SimplifyEmptyArrayCheckRector::class);
125 | $rectorConfig->rule(SimplifyEmptyCheckOnEmptyArrayRector::class);
126 | $rectorConfig->rule(TernaryEmptyArrayArrayDimFetchToCoalesceRector::class);
127 | $rectorConfig->rule(EmptyOnNullableObjectToInstanceOfRector::class);
128 | $rectorConfig->rule(DisallowedEmptyRuleFixerRector::class);
129 | $rectorConfig
130 | ->ruleWithConfiguration(TypedPropertyFromAssignsRector::class, [
131 | /**
132 | * The INLINE_PUBLIC value is default to false to avoid BC break,
133 | * if you use for libraries and want to preserve BC break, you don't
134 | * need to configure it, as it included in LevelSetList::UP_TO_PHP_74
135 | * Set to true for projects that allow BC break
136 | */
137 | TypedPropertyFromAssignsRector::INLINE_PUBLIC => true,
138 | ]);
139 | $rectorConfig->rule(StringClassNameToClassConstantRector::class);
140 | $rectorConfig->rule(PrivatizeFinalClassPropertyRector::class);
141 | $rectorConfig->rule(CompleteDynamicPropertiesRector::class);
142 | $rectorConfig->rule(BooleanInIfConditionRuleFixerRector::class);
143 | $rectorConfig->rule(SingleInArrayToCompareRector::class);
144 | $rectorConfig->rule(VersionCompareFuncCallToConstantRector::class);
145 | $rectorConfig->rule(ExplicitBoolCompareRector::class);
146 | };
147 |
--------------------------------------------------------------------------------
/src/Template/rector.php:
--------------------------------------------------------------------------------
1 | sets([
49 | SetList::DEAD_CODE,
50 | LevelSetList::UP_TO_PHP_81,
51 | PHPUnitSetList::PHPUNIT_CODE_QUALITY,
52 | PHPUnitSetList::PHPUNIT_100,
53 | ]);
54 |
55 | $rectorConfig->parallel();
56 |
57 | // Github action cache
58 | $rectorConfig->cacheClass(FileCacheStorage::class);
59 | if (is_dir('/tmp')) {
60 | $rectorConfig->cacheDirectory('/tmp/rector');
61 | }
62 |
63 | // The paths to refactor (can also be supplied with CLI arguments)
64 | $rectorConfig->paths([
65 | __DIR__ . '/app/',
66 | __DIR__ . '/tests/',
67 | ]);
68 |
69 | // Include Composer's autoload - required for global execution, remove if running locally
70 | $rectorConfig->autoloadPaths([
71 | __DIR__ . '/vendor/autoload.php',
72 | ]);
73 |
74 | // Do you need to include constants, class aliases, or a custom autoloader?
75 | $rectorConfig->bootstrapFiles([
76 | realpath(getcwd()) . '/vendor/codeigniter4/framework/system/Test/bootstrap.php',
77 | ]);
78 |
79 | if (is_file(__DIR__ . '/phpstan.neon.dist')) {
80 | $rectorConfig->phpstanConfig(__DIR__ . '/phpstan.neon.dist');
81 | }
82 |
83 | // Set the target version for refactoring
84 | $rectorConfig->phpVersion(PhpVersion::PHP_81);
85 |
86 | // Auto-import fully qualified class names
87 | $rectorConfig->importNames();
88 |
89 | // Are there files or rules you need to skip?
90 | $rectorConfig->skip([
91 | __DIR__ . '/app/Views',
92 |
93 | StringifyStrNeedlesRector::class,
94 | YieldDataProviderRector::class,
95 |
96 | // Note: requires php 8
97 | RemoveUnusedPromotedPropertyRector::class,
98 | AnnotationWithValueToAttributeRector::class,
99 |
100 | // May load view files directly when detecting classes
101 | StringClassNameToClassConstantRector::class,
102 | ]);
103 |
104 | // auto import fully qualified class names
105 | $rectorConfig->importNames();
106 |
107 | $rectorConfig->rule(SimplifyUselessVariableRector::class);
108 | $rectorConfig->rule(RemoveAlwaysElseRector::class);
109 | $rectorConfig->rule(CountArrayToEmptyArrayComparisonRector::class);
110 | $rectorConfig->rule(ChangeNestedForeachIfsToEarlyContinueRector::class);
111 | $rectorConfig->rule(ChangeIfElseValueAssignToEarlyReturnRector::class);
112 | $rectorConfig->rule(SimplifyStrposLowerRector::class);
113 | $rectorConfig->rule(CombineIfRector::class);
114 | $rectorConfig->rule(SimplifyIfReturnBoolRector::class);
115 | $rectorConfig->rule(InlineIfToExplicitIfRector::class);
116 | $rectorConfig->rule(PreparedValueToEarlyReturnRector::class);
117 | $rectorConfig->rule(ShortenElseIfRector::class);
118 | $rectorConfig->rule(SimplifyIfElseToTernaryRector::class);
119 | $rectorConfig->rule(UnusedForeachValueToArrayKeysRector::class);
120 | $rectorConfig->rule(ChangeArrayPushToArrayAssignRector::class);
121 | $rectorConfig->rule(UnnecessaryTernaryExpressionRector::class);
122 | $rectorConfig->rule(SimplifyRegexPatternRector::class);
123 | $rectorConfig->rule(FuncGetArgsToVariadicParamRector::class);
124 | $rectorConfig->rule(MakeInheritedMethodVisibilitySameAsParentRector::class);
125 | $rectorConfig->rule(SimplifyEmptyArrayCheckRector::class);
126 | $rectorConfig->rule(SimplifyEmptyCheckOnEmptyArrayRector::class);
127 | $rectorConfig->rule(TernaryEmptyArrayArrayDimFetchToCoalesceRector::class);
128 | $rectorConfig->rule(EmptyOnNullableObjectToInstanceOfRector::class);
129 | $rectorConfig->rule(DisallowedEmptyRuleFixerRector::class);
130 | $rectorConfig
131 | ->ruleWithConfiguration(TypedPropertyFromAssignsRector::class, [
132 | /**
133 | * The INLINE_PUBLIC value is default to false to avoid BC break,
134 | * if you use for libraries and want to preserve BC break, you don't
135 | * need to configure it, as it included in LevelSetList::UP_TO_PHP_74
136 | * Set to true for projects that allow BC break
137 | */
138 | TypedPropertyFromAssignsRector::INLINE_PUBLIC => true,
139 | ]);
140 | $rectorConfig->rule(StringClassNameToClassConstantRector::class);
141 | $rectorConfig->rule(PrivatizeFinalClassPropertyRector::class);
142 | $rectorConfig->rule(CompleteDynamicPropertiesRector::class);
143 | $rectorConfig->rule(BooleanInIfConditionRuleFixerRector::class);
144 | $rectorConfig->rule(SingleInArrayToCompareRector::class);
145 | $rectorConfig->rule(VersionCompareFuncCallToConstantRector::class);
146 | $rectorConfig->rule(ExplicitBoolCompareRector::class);
147 | };
148 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodeIgniter DevKit
2 |
3 | Development toolkit for CodeIgniter libraries and projects
4 |
5 | ## Installation
6 |
7 | Install via Composer:
8 |
9 | ```console
10 | composer config minimum-stability dev
11 | composer config prefer-stable true
12 | composer require --dev codeigniter4/devkit
13 | ```
14 |
15 | ## Included Dependencies
16 |
17 | ### Styles and Standards
18 |
19 | * [CodeIgniter Coding Standard](https://github.com/CodeIgniter/coding-standard)
20 | * [NexusPHP CS Config](https://github.com/NexusPHP/cs-config)
21 |
22 | ### Testing and Analysis
23 |
24 | * [NexusPHP Tachycardia](https://github.com/NexusPHP/tachycardia)
25 | * [PHPStan](https://phpstan.org/user-guide/getting-started)
26 | * [PHPUnit](https://phpunit.readthedocs.io)
27 | * [Psalm](https://psalm.dev)
28 |
29 | ### Mocking
30 |
31 | * [FakerPHP](https://fakerphp.github.io)
32 | * [VFS Stream](https://github.com/bovigo/vfsStream/wiki)
33 |
34 | ### Security
35 |
36 | * [Dependabot](https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates)
37 | * [Roave Security Advisories](https://github.com/Roave/SecurityAdvisories)
38 |
39 | ### Additional Tools
40 |
41 | These are integrated into the workflows but not included via Composer. If you want to use them
42 | locally they will need to be installed. All of them (except Rector) are available via [Phive](https://phar.io/#Tools).
43 |
44 | * [Composer Normalize](https://github.com/ergebnis/composer-normalize)
45 | * [Composer Unused](https://github.com/composer-unused/composer-unused)
46 | * [Deptrac](https://github.com/deptrac/deptrac)
47 | * [Infection](https://infection.github.io/)
48 | * [PHP Coveralls](https://php-coveralls.github.io/php-coveralls/)
49 | * [PHP CS Fixer](https://cs.symfony.com/)
50 | * [Rector](https://github.com/rectorphp/rector/)
51 |
52 | ## Template Files
53 |
54 | The provided source files (in **Template/**) should be considered guidelines for your own use,
55 | as they may need changing to fit your environment. These are based on the following assumptions:
56 |
57 | 1. Your default repository branch is set to `develop`
58 | 2. You use Composer to manage all necessary dependencies
59 | 3. Your source code is located in **app/** (for projects) or **src/** (for libraries)
60 | 4. Your unit tests are located in **tests/**
61 | 5. Your CodeIgniter dependency is `codeigniter4/framework` (some paths need to be changed for `dev-develop`)
62 |
63 | ### Workflows
64 |
65 | This kit includes a number of workflow templates for integrating [GitHub Actions](https://docs.github.com/en/actions)
66 | into your library or project development process. To add these to your repo simply copy the
67 | workflows into a **Template/.github/workflows/** directory.
68 |
69 | > [!TIP]
70 | > The [source files](src/.github) also include a configuration for Dependabot which
71 | > will help keep your dependencies and workflows updated.
72 |
73 | Below is a brief description of each workflow; see the links above for help with each tool.
74 |
75 | #### Deptrac
76 |
77 | *Requires **depfile.yaml***
78 |
79 | Deptrac is a "dependency tracing" tool that allows developers to define which components should
80 | be allowed to access each other. This helps keep your project architecture logical and concise
81 | by enforcing the rules you set. For example, you may want to impose an MVC-style architecture
82 | by allowing a `Controller` to use any `Model` but not vice-versa.
83 |
84 | #### Infection
85 |
86 | *Requires **infection.json.dist***
87 |
88 | Just because your tests reach a high level of code coverage does not mean they are comprehensive.
89 | Mutation Testing is a way of gauging the *quality* of your unit tests. A silly example: your
90 | code has an increment function with a single unit test for 100% coverage:
91 |
92 | ```php
93 | function increment(int $num1, int $num2): int
94 | {
95 | return $num1 + $num2;
96 | }
97 |
98 | function testIncrementWithZero()
99 | {
100 | $result = increment(42, 0);
101 | $this->assertSame(42, $result);
102 | }
103 | ```
104 |
105 | Infection will re-run your unit test against "mutated" versions of your code that *should*
106 | cause failures and report "escaped mutations" when they still pass. In this example, Infection
107 | mutates your `increment()` function to use `-` instead of `+`, but since your test case
108 | still asserts `42` as the result it is considered an "escape" and you should plan to add
109 | more tests.
110 |
111 | #### PHPCPD
112 |
113 | PHP Copy-Paste Detector analyzes your code and reports when there are blocks of duplicate code
114 | more than a certain number of lines long (default: 5). In most cases this is a sign of poor
115 | code structure and an opportunity to consolidate classes or functions.
116 |
117 | #### PHP CS Fixer
118 |
119 | PHP CS Fixer is used to enforce coding standards. Once the rules are defined in the config file
120 | the workflow will check your code against the definitions and fail for any deviance.
121 |
122 | #### PHPStan
123 |
124 | *Requires **phpstan.neon.dist***
125 |
126 | Static analysis is a major factor in catching bugs and issues before they happen. PHPStan will
127 | analyze your code for mistakes based on the configuration supplied.
128 |
129 | #### PHPUnit
130 |
131 | *Requires **phpunit.xml.dist***
132 |
133 | Unit testing automates running your code through all the possible scenarios before putting it
134 | into use in production. PHPUnit is a highly-configurable framework and suite for writing and
135 | running unit tests. This workflow also configures PHPUnit to report on code coverage and
136 | upload the results to [Coveralls.io](https://coveralls.io) (you will need a free account,
137 | but it is also fine to use this workflow without Coveralls).
138 |
139 | #### Rector
140 |
141 | *Requires **rector.php***
142 |
143 | Rector provides automated refactoring of code, allowing you to make sweeping updates based on
144 | predefined rulesets. Rector can be highly opinionated based on its configuration file (**rector.php**)
145 | so be sure to read the documentation and figure out the best fit for you. This workflow performs
146 | a "dry run" to check for any changes that Rector would have made and fail if there are matches.
147 |
148 | > [!NOTE]
149 | > Rector updates rules all the time, so you may want to lock your repo to
150 | > the latest known working version of Rector to prevent unexpected failures.
151 | > Using pinned version in `composer.json` and update it with dependabot is the
152 | > best practice.
153 |
154 | #### Unused
155 |
156 | Composer Unused does one thing: checks that your code actually uses the dependencies you
157 | have included via Composer. It can be easy to forget to update your **composer.json** when
158 | your code drops a dependency, so this workflow will help track those down.
159 |
160 | ### Hosting with Vagrant
161 |
162 | > [!NOTE]
163 | > The `Vagrantfile.dist` is unmaintained. It might not work now.
164 | > Contributions are welcome.
165 |
166 | Virtualization is an effective way to test your webapp in the environment you
167 | plan to deploy on, even if you develop on a different one.
168 | Even if you are using the same platform for both, virtualization provides an
169 | isolated environment for testing.
170 |
171 | The codebase comes with a **src/Template/Vagrantfile.dist**, that can be copied to **Vagrantfile**
172 | and tailored for your system, for instance enabling access to specific database or caching engines.
173 |
174 | #### Setting Up
175 |
176 | It assumes that you have installed [VirtualBox](https://www.virtualbox.org/wiki/Downloads) and
177 | [Vagrant](https://www.vagrantup.com/downloads.html)
178 | for your platform.
179 |
180 | The Vagrant configuration file assumes you have set up a [ubuntu/bionic64 Vagrant box](https://app.vagrantup.com/ubuntu/boxes/bionic64) on your system:
181 |
182 | ```console
183 | > vagrant box add ubuntu/bionic64
184 | ```
185 |
186 | #### Testing
187 |
188 | Once set up, you can then launch your webapp inside a VM, with the command:
189 |
190 | ```console
191 | > vagrant up
192 | ```
193 |
194 | Your webapp will be accessible at http://localhost:8080, with the code coverage
195 | report for your build at http://localhost:8081 and the user guide for
196 | it at http://localhost:8082.
197 |
198 | ## Example Files
199 |
200 | Besides the template files, this repo includes some examples for integrating CodeIgniter
201 | with other third-party resources. These files (in **Examples/**) may change over time and
202 | should not be relied on for anything more than a reference for your own code.
203 |
--------------------------------------------------------------------------------
/src/Template/Vagrantfile.dist:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | # https://github.com/hashicorp/vagrant/issues/9442#issuecomment-374785457
5 | unless Vagrant::DEFAULT_SERVER_URL.frozen?
6 | Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com')
7 | end
8 |
9 | Vagrant.configure("2") do |config|
10 | # VM Box
11 | config.vm.box = "ubuntu/bionic64"
12 | # Automatic box update checking
13 | config.vm.box_check_update = true
14 |
15 | # CodeIgniter virtual host
16 | config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
17 | # Code Coverage virtual host
18 | config.vm.network "forwarded_port", guest: 81, host: 8081, host_ip: "127.0.0.1"
19 | # User Guide virtual host
20 | config.vm.network "forwarded_port", guest: 82, host: 8082, host_ip: "127.0.0.1"
21 | # MySQL server
22 | #config.vm.network "forwarded_port", guest: 3306, host: 3307, host_ip: "127.0.0.1"
23 | # PostgreSQL server
24 | #config.vm.network "forwarded_port", guest: 5432, host: 5433, host_ip: "127.0.0.1"
25 | # Memcached server
26 | #config.vm.network "forwarded_port", guest: 11211, host: 11212, host_ip: "127.0.0.1"
27 | # Redis server
28 | #config.vm.network "forwarded_port", guest: 6379, host: 6380, host_ip: "127.0.0.1"
29 |
30 | # Add "192.168.10.10 ${VIRTUALHOST}" in your host file to access by domain
31 | #config.vm.network "private_network", ip: "192.168.10.10"
32 |
33 | # Same path set in the $CODEIGNITER_PATH Provision
34 | # "virtualbox" type allow auto-sync host to guest and guest to host
35 | # but chmod does not work... tests will fail.
36 | # Default rsync__args except "--copy-links", to allow phpunit correctly works by symlink
37 | config.vm.synced_folder ".", "/var/www/codeigniter", type: "rsync", rsync__args: ["--verbose", "--archive", "--delete", "-z"]
38 |
39 | # Provider-specific configuration
40 | config.vm.provider "virtualbox" do |vb|
41 | # Display the VirtualBox GUI when booting the machine
42 | vb.gui = false
43 | # Customize the amount of memory on the VM:
44 | vb.memory = "1024"
45 | end
46 |
47 | # Provision
48 | config.vm.provision "shell", inline: <<-SHELL
49 | MYSQL_ROOT_PASS="password"
50 | PGSQL_ROOT_PASS="password"
51 | VIRTUALHOST="localhost"
52 | CODEIGNITER_PATH="/var/www/codeigniter"
53 | PHP_VERSION=7.4
54 | PGSQL_VERSION=10
55 | #APT_PROXY="192.168.10.1:3142"
56 |
57 | grep -q "127.0.0.1 ${VIRTUALHOST}" /etc/hosts || echo "127.0.0.1 ${VIRTUALHOST}" >> /etc/hosts
58 |
59 | # Creates a swap file if necessary
60 | RAM=`awk '/MemTotal/ {print $2}' /proc/meminfo`
61 | if [ $RAM -lt 1000000 ] && [ ! -f /swap/swapfile ]; then
62 | echo "================================================================================"
63 | echo "Adding swap"
64 | echo "================================================================================"
65 | echo "This process may take a few minutes. Please wait..."
66 | mkdir /swap
67 | dd if=/dev/zero of=/swap/swapfile bs=1024 count=1000000
68 | chmod 600 /swap/swapfile
69 | mkswap /swap/swapfile
70 | swapon /swap/swapfile
71 | echo "/swap/swapfile swap swap defaults 0 0" >> /etc/fstab
72 | echo "Done."
73 | fi
74 |
75 | # Prepare to use APT Proxy
76 | if [ ! -z $APT_PROXY ]; then
77 | if [ ! -f /etc/apt/sources.list-origin ]; then
78 | cp /etc/apt/sources.list /etc/apt/sources.list-origin
79 | fi
80 | sed -i "s/archive.ubuntu.com/${APT_PROXY}/" /etc/apt/sources.list
81 | sed -i "s/security.ubuntu.com/${APT_PROXY}/" /etc/apt/sources.list
82 | fi
83 |
84 | export DEBIAN_FRONTEND=noninteractive
85 |
86 | echo "================================================================================"
87 | echo "Updating and Installing Required Packages"
88 | echo "================================================================================"
89 |
90 | add-apt-repository ppa:ondrej/php
91 |
92 | apt-get update
93 |
94 | debconf-set-selections <<< "mysql-server mysql-server/root_password password ${MYSQL_ROOT_PASS}"
95 | debconf-set-selections <<< "mysql-server mysql-server/root_password_again password ${MYSQL_ROOT_PASS}"
96 |
97 | apt-get install -y \
98 | php$PHP_VERSION apache2 composer \
99 | php-intl php-mbstring php-xml php-zip php-xdebug \
100 | php-mysql mysql-server mysql-client \
101 | php-pgsql postgresql-$PGSQL_VERSION \
102 | php-sqlite3 sqlite3 \
103 | php-memcached memcached \
104 | php-redis redis-server \
105 | php-curl curl \
106 | php-gd php-imagick \
107 | python-pip
108 |
109 | pip install sphinx sphinxcontrib-phpdomain
110 |
111 | apt-get autoclean
112 |
113 | echo "================================================================================"
114 | echo "Preparing User Guide"
115 | echo "================================================================================"
116 |
117 | cd "${CODEIGNITER_PATH}/user_guide_src/cilexer"
118 | python setup.py install
119 | cd ..
120 | make html
121 |
122 | echo "================================================================================"
123 | echo "Configuring Databases"
124 | echo "================================================================================"
125 |
126 | sed -i "s/^bind-address/#bind-address/" /etc/mysql/mysql.conf.d/mysqld.cnf
127 | mysql -e "CREATE DATABASE IF NOT EXISTS codeigniter COLLATE 'utf8_general_ci';
128 | UPDATE mysql.user SET Host='%' WHERE user='root';
129 | GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
130 | FLUSH PRIVILEGES;" -uroot -p$MYSQL_ROOT_PASS
131 | systemctl restart mysql
132 |
133 | sed -i "s/^#listen_addresses = 'localhost'/listen_addresses = '*'/" /etc/postgresql/$PGSQL_VERSION/main/postgresql.conf
134 | grep -q "host all root all md5" /etc/postgresql/$PGSQL_VERSION/main/pg_hba.conf || echo "host all root all md5" >> /etc/postgresql/$PGSQL_VERSION/main/pg_hba.conf
135 | sudo -u postgres psql -tc "SELECT 1 FROM pg_roles WHERE rolname='root'" | grep -q 1 || sudo -u postgres psql -c "CREATE ROLE root WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN"
136 | sudo -u postgres psql -c "ALTER ROLE root WITH PASSWORD '${PGSQL_ROOT_PASS}'"
137 | sudo -u postgres psql -tc "SELECT 1 FROM pg_database WHERE datname='codeigniter'" | grep -q 1 ||sudo -u postgres psql -c "CREATE DATABASE codeigniter"
138 | sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE codeigniter TO root"
139 | systemctl restart postgresql
140 |
141 | echo "================================================================================"
142 | echo "Configuring Memcached and Redis"
143 | echo "================================================================================"
144 |
145 | sed -i "s/^bind 127.0.0.1/#bind 127.0.0.1/" /etc/redis/redis.conf
146 | sed -i "s/^protected-mode yes/protected-mode no/" /etc/redis/redis.conf
147 | sed -i "s/^-l 127.0.0.1/#-l 127.0.0.1/" /etc/memcached.conf
148 | systemctl restart redis
149 | systemctl restart memcached
150 |
151 | echo "================================================================================"
152 | echo "Configuring Virtual Hosts"
153 | echo "================================================================================"
154 |
155 | mkdir -p "${CODEIGNITER_PATH}/build/coverage-html"
156 | mkdir -p "${CODEIGNITER_PATH}/public"
157 | mkdir -p "${CODEIGNITER_PATH}/user_guide_src/build/html"
158 | mkdir -p "${CODEIGNITER_PATH}/writable/apache"
159 | chown -R vagrant:vagrant $CODEIGNITER_PATH
160 |
161 | # Creates a symlink in the user home
162 | if [ ! -d /home/vagrant/codeigniter ]; then
163 | ln -s $CODEIGNITER_PATH /home/vagrant/codeigniter
164 | fi
165 |
166 | sed -i "s/APACHE_RUN_USER=www-data/APACHE_RUN_USER=vagrant/" /etc/apache2/envvars
167 | sed -i "s/APACHE_RUN_GROUP=www-data/APACHE_RUN_GROUP=vagrant/" /etc/apache2/envvars
168 | grep -q "Listen 81" /etc/apache2/ports.conf || sed -i "s/^Listen 80/Listen 80\\nListen 81\\nListen 82/" /etc/apache2/ports.conf
169 | sed -i "s/^display_errors = Off/display_errors = On/" /etc/php/7.4/apache2/php.ini
170 | sed -i "s/^display_startup_errors = Off/display_startup_errors = On/" /etc/php/7.4/apache2/php.ini
171 |
172 | echo "ServerName ${VIRTUALHOST}
173 |
174 | DirectoryIndex index.html index.php
175 | Options All
176 | AllowOverride All
177 |
178 |
179 | ServerAdmin vagrant@localhost
180 | DocumentRoot ${CODEIGNITER_PATH}/public
181 | ErrorLog ${CODEIGNITER_PATH}/writable/apache/error.log
182 | CustomLog ${CODEIGNITER_PATH}/writable/apache/custom.log combined
183 |
184 |
185 | DocumentRoot ${CODEIGNITER_PATH}/build/coverage-html
186 |
187 |
188 | DocumentRoot ${CODEIGNITER_PATH}/user_guide_src/build/html
189 |
190 | " > /etc/apache2/sites-available/codeigniter.conf
191 |
192 | a2enmod rewrite
193 | a2dissite 000-default.conf
194 | a2ensite codeigniter.conf
195 | systemctl restart apache2
196 |
197 | echo "================================================================================"
198 | echo "Services Status"
199 | echo "================================================================================"
200 | service --status-all
201 |
202 | SHELL
203 | end
204 |
--------------------------------------------------------------------------------