├── .github └── workflows │ ├── coding-standards.yml │ ├── phpunit.yml │ └── static-analysis.yml ├── .gitignore ├── README.md ├── app ├── .htaccess ├── Common.php ├── Config │ ├── App.php │ ├── Autoload.php │ ├── Boot │ │ ├── development.php │ │ ├── production.php │ │ └── testing.php │ ├── CURLRequest.php │ ├── Cache.php │ ├── Constants.php │ ├── ContentSecurityPolicy.php │ ├── Cookie.php │ ├── Database.php │ ├── DocTypes.php │ ├── Email.php │ ├── Encryption.php │ ├── Events.php │ ├── Exceptions.php │ ├── Feature.php │ ├── Filters.php │ ├── ForeignCharacters.php │ ├── Format.php │ ├── Generators.php │ ├── Honeypot.php │ ├── Images.php │ ├── Kint.php │ ├── Logger.php │ ├── Migrations.php │ ├── Mimes.php │ ├── Modules.php │ ├── Pager.php │ ├── Paths.php │ ├── Publisher.php │ ├── Routes.php │ ├── Routing.php │ ├── Security.php │ ├── Services.php │ ├── Session.php │ ├── Toolbar.php │ ├── UserAgents.php │ ├── Validation.php │ └── View.php ├── Controllers │ ├── BaseController.php │ └── Home.php ├── Database │ ├── Migrations │ │ └── .gitkeep │ └── Seeds │ │ └── .gitkeep ├── Filters │ └── .gitkeep ├── Helpers │ └── .gitkeep ├── Language │ ├── .gitkeep │ └── en │ │ └── Validation.php ├── Libraries │ └── .gitkeep ├── Models │ └── .gitkeep ├── ThirdParty │ └── .gitkeep ├── Views │ ├── errors │ │ ├── cli │ │ │ ├── error_404.php │ │ │ ├── error_exception.php │ │ │ └── production.php │ │ └── html │ │ │ ├── debug.css │ │ │ ├── debug.js │ │ │ ├── error_404.php │ │ │ ├── error_exception.php │ │ │ └── production.php │ └── welcome_message.php └── index.html ├── builds ├── composer.json ├── composer.lock ├── env ├── license.txt ├── phpcs.xml ├── phpmd.xml ├── phpstan.neon ├── phpunit.xml.dist ├── psalm.xml ├── public ├── .htaccess ├── favicon.ico ├── index.php └── robots.txt ├── spark ├── tests ├── README.md ├── _support │ ├── Database │ │ ├── Migrations │ │ │ └── 2020-02-22-222222_example_migration.php │ │ └── Seeds │ │ │ └── ExampleSeeder.php │ ├── Libraries │ │ └── ConfigReader.php │ └── Models │ │ └── ExampleModel.php ├── database │ └── ExampleDatabaseTest.php ├── session │ └── ExampleSessionTest.php └── unit │ └── HealthTest.php ├── vendor-bin └── tools │ ├── composer.json │ └── composer.lock └── writable ├── .htaccess ├── cache └── index.html ├── logs └── index.html ├── session └── index.html └── uploads └── index.html /.github/workflows/coding-standards.yml: -------------------------------------------------------------------------------- 1 | name: Coding Standards 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - develop 7 | paths: 8 | - '**.php' 9 | - phpcs.xml 10 | - .github/workflows/coding-standards.yml 11 | 12 | jobs: 13 | coding-standards: 14 | name: Coding Standards 15 | runs-on: ubuntu-latest 16 | if: "!contains(github.event.head_commit.message, '[ci skip]')" 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | 21 | - name: Setup PHP 22 | uses: shivammathur/setup-php@v2 23 | with: 24 | php-version: 7.4 25 | tools: cs2pr 26 | coverage: none 27 | 28 | - name: Get composer cache directory 29 | id: composer-cache 30 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 31 | 32 | - name: Cache dependencies 33 | uses: actions/cache@v2 34 | with: 35 | path: ${{ steps.composer-cache.outputs.dir }} 36 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 37 | restore-keys: ${{ runner.os }}-composer- 38 | 39 | - name: Install dependencies 40 | run: composer install --no-interaction --no-progress --prefer-dist 41 | 42 | - name: Validate composer.json 43 | run: composer validate --strict 44 | 45 | - name: Run PHP_CodeSniffer 46 | run: ./vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr 47 | -------------------------------------------------------------------------------- /.github/workflows/phpunit.yml: -------------------------------------------------------------------------------- 1 | name: PHPUnit 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - develop 7 | paths: 8 | - 'app/**.php' 9 | - 'tests/**.php' 10 | - 'composer.*' 11 | - phpunit.xml.dist 12 | - .github/workflows/phpunit.yml 13 | 14 | jobs: 15 | main: 16 | name: Build and test 17 | 18 | strategy: 19 | matrix: 20 | php-versions: ['7.3', '7.4'] 21 | db-platforms: ['MySQLi'] 22 | 23 | services: 24 | mysql: 25 | image: mysql:5.7 26 | env: 27 | MYSQL_ALLOW_EMPTY_PASSWORD: yes 28 | MYSQL_DATABASE: test 29 | ports: 30 | - 3306:3306 31 | options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 32 | 33 | runs-on: ubuntu-latest 34 | 35 | if: "!contains(github.event.head_commit.message, '[ci skip]')" 36 | 37 | steps: 38 | - name: Checkout 39 | uses: actions/checkout@v2 40 | 41 | - name: Setup PHP, with composer and extensions 42 | uses: shivammathur/setup-php@v2 43 | with: 44 | php-version: ${{ matrix.php-versions }} 45 | tools: composer, pecl, phpunit 46 | extensions: intl, json, mbstring, mysqlnd, xdebug, xml, sqlite3 47 | coverage: xdebug 48 | 49 | - name: Get composer cache directory 50 | id: composer-cache 51 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 52 | 53 | - name: Cache composer dependencies 54 | uses: actions/cache@v2 55 | with: 56 | path: ${{ steps.composer-cache.outputs.dir }} 57 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 58 | restore-keys: ${{ runner.os }}-composer- 59 | 60 | - name: Install dependencies 61 | run: composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader 62 | # To prevent rate limiting you may need to supply an OAuth token in Settings > Secrets 63 | # env: 64 | # https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens 65 | # COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }} 66 | 67 | - name: Test with PHPUnit 68 | run: script -e -c "vendor/bin/phpunit -v --coverage-text" 69 | env: 70 | DB: ${{ matrix.db-platforms }} 71 | TERM: xterm-256color 72 | -------------------------------------------------------------------------------- /.github/workflows/static-analysis.yml: -------------------------------------------------------------------------------- 1 | name: Static Analysis 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - develop 7 | paths: 8 | - 'app/**.php' 9 | - 'tests/**.php' 10 | - 'composer.*' 11 | - phpmd.xml 12 | - phpstan.neon 13 | - psalm.xml 14 | - .github/workflows/static-analysis.yml 15 | 16 | jobs: 17 | static-analysis-phpstan: 18 | name: Static Analysis with PHPStan 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v2 23 | 24 | - name: Setup PHP 25 | uses: shivammathur/setup-php@v2 26 | with: 27 | php-version: 7.4 28 | tools: cs2pr 29 | coverage: none 30 | 31 | - name: Get composer cache directory 32 | id: composer-cache 33 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 34 | 35 | - name: Cache dependencies 36 | uses: actions/cache@v2 37 | with: 38 | path: ${{ steps.composer-cache.outputs.dir }} 39 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 40 | restore-keys: ${{ runner.os }}-composer- 41 | 42 | - name: Install dependencies 43 | run: composer install --no-interaction --no-progress --prefer-dist 44 | 45 | - name: Run PHPStan 46 | run: ./vendor/bin/phpstan analyse -c phpstan.neon --no-progress --no-interaction --error-format=checkstyle | cs2pr 47 | 48 | static-analysis-psalm: 49 | name: Static Analysis with Psalm 50 | runs-on: ubuntu-latest 51 | steps: 52 | - name: Checkout 53 | uses: actions/checkout@v2 54 | 55 | - name: Setup PHP 56 | uses: shivammathur/setup-php@v2 57 | with: 58 | php-version: 7.4 59 | tools: cs2pr 60 | coverage: none 61 | 62 | - name: Get composer cache directory 63 | id: composer-cache 64 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 65 | 66 | - name: Cache dependencies 67 | uses: actions/cache@v2 68 | with: 69 | path: ${{ steps.composer-cache.outputs.dir }} 70 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 71 | restore-keys: ${{ runner.os }}-composer- 72 | 73 | - name: Install dependencies 74 | run: composer install --no-interaction --no-progress --prefer-dist 75 | 76 | - name: Run Psalm 77 | run: ./vendor/bin/psalm --show-info=false --output-format=checkstyle --shepherd | cs2pr 78 | 79 | static-analysis-phpmd: 80 | name: Static Analysis with PHPMD 81 | runs-on: ubuntu-latest 82 | steps: 83 | - name: Checkout 84 | uses: actions/checkout@v2 85 | 86 | - name: Setup PHP 87 | uses: shivammathur/setup-php@v2 88 | with: 89 | php-version: 7.4 90 | 91 | - name: Get composer cache directory 92 | id: composer-cache 93 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 94 | 95 | - name: Cache dependencies 96 | uses: actions/cache@v2 97 | with: 98 | path: ${{ steps.composer-cache.outputs.dir }} 99 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 100 | restore-keys: ${{ runner.os }}-composer- 101 | 102 | - name: Install dependencies 103 | run: composer install --no-interaction --no-progress --prefer-dist 104 | 105 | - name: Run PHP Mess Detector 106 | run: ./vendor/bin/phpmd app text ./phpmd.xml --exclude */app/Config,*/app/Views 107 | 108 | static-analysis-php-metrics: 109 | name: Static Analysis with PhpMetrics 110 | runs-on: ubuntu-latest 111 | steps: 112 | - name: Checkout 113 | uses: actions/checkout@v2 114 | 115 | - name: Setup PHP 116 | uses: shivammathur/setup-php@v2 117 | with: 118 | php-version: 7.4 119 | coverage: none 120 | 121 | - name: Get composer cache directory 122 | id: composer-cache 123 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 124 | 125 | - name: Cache dependencies 126 | uses: actions/cache@v2 127 | with: 128 | path: ${{ steps.composer-cache.outputs.dir }} 129 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 130 | restore-keys: ${{ runner.os }}-composer- 131 | 132 | - name: Install dependencies 133 | run: composer install --no-interaction --no-progress --prefer-dist 134 | 135 | - name: Run PhpMetrics 136 | run: ./vendor/bin/phpmetrics app --exclude='Config,Database,Language,ThirdParty,Views' 137 | 138 | # static-analysis-composer-require-checker: 139 | # name: Static Analysis with ComposerRequireChecker 140 | # runs-on: ubuntu-latest 141 | # steps: 142 | # - name: Checkout 143 | # uses: actions/checkout@v2 144 | # 145 | # - name: Setup PHP 146 | # uses: shivammathur/setup-php@v2 147 | # with: 148 | # php-version: 7.4 149 | # coverage: none 150 | # tools: composer-require-checker 151 | # 152 | # - name: Get composer cache directory 153 | # id: composer-cache 154 | # run: echo "::set-output name=dir::$(composer config cache-files-dir)" 155 | # 156 | # - name: Cache dependencies 157 | # uses: actions/cache@v2 158 | # with: 159 | # path: ${{ steps.composer-cache.outputs.dir }} 160 | # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 161 | # restore-keys: ${{ runner.os }}-composer- 162 | # 163 | # - name: Install dependencies 164 | # run: | 165 | # composer install --no-progress --no-scripts --no-dev 166 | # 167 | # - name: Run composer-require-checker 168 | # run: composer-require-checker check composer.json 169 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #------------------------- 2 | # Operating Specific Junk Files 3 | #------------------------- 4 | 5 | # OS X 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # OS X Thumbnails 11 | ._* 12 | 13 | # Windows image file caches 14 | Thumbs.db 15 | ehthumbs.db 16 | Desktop.ini 17 | 18 | # Recycle Bin used on file shares 19 | $RECYCLE.BIN/ 20 | 21 | # Windows Installer files 22 | *.cab 23 | *.msi 24 | *.msm 25 | *.msp 26 | 27 | # Windows shortcuts 28 | *.lnk 29 | 30 | # Linux 31 | *~ 32 | 33 | # KDE directory preferences 34 | .directory 35 | 36 | # Linux trash folder which might appear on any partition or disk 37 | .Trash-* 38 | 39 | #------------------------- 40 | # Environment Files 41 | #------------------------- 42 | # These should never be under version control, 43 | # as it poses a security risk. 44 | .env 45 | .vagrant 46 | Vagrantfile 47 | 48 | #------------------------- 49 | # Temporary Files 50 | #------------------------- 51 | writable/cache/* 52 | !writable/cache/index.html 53 | 54 | writable/logs/* 55 | !writable/logs/index.html 56 | 57 | writable/session/* 58 | !writable/session/index.html 59 | 60 | writable/uploads/* 61 | !writable/uploads/index.html 62 | 63 | writable/debugbar/* 64 | 65 | writable/revision/* 66 | 67 | php_errors.log 68 | 69 | #------------------------- 70 | # User Guide Temp Files 71 | #------------------------- 72 | user_guide_src/build/* 73 | user_guide_src/cilexer/build/* 74 | user_guide_src/cilexer/dist/* 75 | user_guide_src/cilexer/pycilexer.egg-info/* 76 | 77 | #------------------------- 78 | # Test Files 79 | #------------------------- 80 | tests/coverage* 81 | 82 | # Don't save phpunit under version control. 83 | phpunit 84 | 85 | #------------------------- 86 | # Composer 87 | #------------------------- 88 | vendor/ 89 | 90 | #------------------------- 91 | # IDE / Development Files 92 | #------------------------- 93 | 94 | # Modules Testing 95 | _modules/* 96 | 97 | # phpenv local config 98 | .php-version 99 | 100 | # Jetbrains editors (PHPStorm, etc) 101 | .idea/ 102 | *.iml 103 | 104 | # Netbeans 105 | nbproject/ 106 | build/ 107 | nbbuild/ 108 | dist/ 109 | nbdist/ 110 | nbactions.xml 111 | nb-configuration.xml 112 | .nb-gradle/ 113 | 114 | # Sublime Text 115 | *.tmlanguage.cache 116 | *.tmPreferences.cache 117 | *.stTheme.cache 118 | *.sublime-workspace 119 | *.sublime-project 120 | .phpintel 121 | /api/ 122 | 123 | # Visual Studio Code 124 | .vscode/ 125 | 126 | /results/ 127 | /phpunit*.xml 128 | /.phpunit.*.cache 129 | 130 | .phpcs-cache 131 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter 4 Application Template 2 | 3 | This template changes the default configuration of CI4 more secure. 4 | 5 | This repository includes: 6 | 7 | - [CodeIgniter](https://github.com/codeigniter4/CodeIgniter4) 4.4.5 8 | - [Translations for CodeIgniter 4 System Messages](https://github.com/codeigniter4/translations) dev-develop 9 | - [CodeIgniter DevKit](https://github.com/codeigniter4/devkit) 1.2.0 10 | - [PHPUnit](https://github.com/sebastianbergmann/phpunit) 9.6.16 11 | - [Tatter\Patches](https://github.com/tattersoftware/codeigniter4-patches) 2.1.0 12 | - [Liaison Revision](https://github.com/paulbalandan/liaison-revision) 1.1.0 13 | - [bear/qatools](https://github.com/bearsunday/BEAR.QATools) 1.10.0 14 | 15 | ## Requirements 16 | 17 | - [PHP 7.4](https://www.php.net/releases/7_4_0.php) or later 18 | - [intl](http://php.net/manual/en/intl.requirements.php) 19 | - [libcurl](http://php.net/manual/en/curl.requirements.php) if you plan to use the HTTP\CURLRequest library 20 | - json (enabled by default - don't turn it off) 21 | - [mbstring](http://php.net/manual/en/mbstring.installation.php) 22 | - [mysqlnd](http://php.net/manual/en/mysqlnd.install.php) if you plan to use MySQL 23 | - xml (enabled by default - don't turn it off) 24 | 25 | ## How to Install 26 | 27 | ### Composer 28 | 29 | ```sh-session 30 | $ composer create-project kenjis/ci4-app-template your-project 31 | ``` 32 | 33 | ### Git 34 | 35 | ```sh-session 36 | $ git clone https://github.com/kenjis/ci4-app-template.git your-project 37 | $ cd your-project/ 38 | $ composer install 39 | $ git checkout -b main 40 | ``` 41 | 42 | ## How to Update 43 | 44 | Update Composer packages: 45 | 46 | ```sh-session 47 | $ composer update 48 | ``` 49 | 50 | Update your CodeIgniter4 project files: 51 | 52 | ```sh-session 53 | $ php spark revision:update 54 | ``` 55 | 56 | ## How to Use 57 | 58 | ### Services 59 | 60 | - All Services must be manually added to `app/Config/Services.php`, even if third-party CI4 packages have their own Services. 61 | 62 | ### CSRF 63 | 64 | - You must set CSRF token field in your form manually. See https://codeigniter4.github.io/CodeIgniter4/libraries/security.html#html-forms 65 | 66 | ### CSP 67 | 68 | - You must set CSP when you need. See https://codeigniter4.github.io/CodeIgniter4/outgoing/response.html#content-security-policy 69 | - You need to use `csp_script_nonce()` and `csp_style_nonce()` for inline contents. See https://codeigniter4.github.io/CodeIgniter4/outgoing/response.html#inline-content 70 | 71 | ## Changes from the CI4 Default Configuration 72 | 73 | ### Services 74 | 75 | - Auto-Discovery of services is disabled. [app/Config/Modules.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Modules.php#L82). 76 | - `Config\Services` extends `CodeIgniter\Config\Services`. [app/Config/Services.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Services.php#L20). 77 | 78 | ### Configs 79 | 80 | - BaseURL's `index.php` is removed. 81 | - [app/Config/App.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/App.php#L43) 82 | - Auto Routing (Improved) is enabled. 83 | - [app/Config/Routing.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Routing.php#L93) and [app/Config/Feature.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Feature.php#L29) 84 | - See https://codeigniter4.github.io/CodeIgniter4/incoming/routing.html#auto-routing-improved 85 | - `Config\CURLRequest::$shareOptions` is disabled. (Since v4.4.0, this is set by default.) 86 | - [app/Config/CURLRequest.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/CURLRequest.php#L19). 87 | - See https://codeigniter4.github.io/CodeIgniter4/libraries/curlrequest.html#sharing-options 88 | - MySQLi's `numberNative` is enabled. 89 | - [app/Config/Database.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Database.php#L45) 90 | - See https://codeigniter4.github.io/CodeIgniter4/database/configuration.html#explanation-of-values 91 | - Using Session-based CSRF protection. 92 | - [app/Config/Security.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Security.php#L18). 93 | - See https://codeigniter4.github.io/CodeIgniter4/libraries/security.html#csrf-protection-methods 94 | - CSRF protection `$tokenRandomize` is enabled. 95 | - [app/Config/Security.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Security.php#L29). 96 | - See https://codeigniter4.github.io/CodeIgniter4/libraries/security.html#token-randomization 97 | - CSP is enabled. 98 | - [app/Config/App](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/App.php#L176). 99 | - See https://codeigniter4.github.io/CodeIgniter4/outgoing/response.html#turning-csp-on 100 | - CSP `$autoNonce` is disabled. 101 | - [app/Config/ContentSecurityPolicy](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/ContentSecurityPolicy.php#L175). 102 | - See https://codeigniter4.github.io/CodeIgniter4/outgoing/response.html#inline-content 103 | - Strict Validation Rules are used. (Since v4.3.0, this is set by default.) 104 | - [app/Config/Validation.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Validation.php#L24-L27). 105 | - See https://codeigniter4.github.io/CodeIgniter4/libraries/validation.html#traditional-and-strict-rules 106 | 107 | ### Filters 108 | 109 | - CSRF filter is enabled. 110 | - [app/Config/Filters.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Filters.php#L60-L63). 111 | - See https://codeigniter4.github.io/CodeIgniter4/libraries/security.html#enable-csrf-protection 112 | - InvalidChars filter is enabled. 113 | - [app/Config/Filters.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Filters.php#L39). 114 | - See https://codeigniter4.github.io/CodeIgniter4/incoming/filters.html#invalidchars 115 | - SecureHeaders filter is enabled. 116 | - [app/Config/Filters.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Filters.php#L44). 117 | - See https://codeigniter4.github.io/CodeIgniter4/incoming/filters.html#secureheaders 118 | 119 | ### Features 120 | 121 | - `Config\Feature::$multipleFilters` is enabled. 122 | - [app/Config/Feature.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Feature.php#L24). 123 | - See https://codeigniter4.github.io/CodeIgniter4/incoming/routing.html#applying-filters 124 | 125 | ### Others 126 | 127 | - Using `develop` version CI4. [app/Config/Paths.php](https://github.com/kenjis/ci4-app-template/blob/ci4-app-template/app/Config/Paths.php#L28). 128 | 129 | ## Available Commands 130 | 131 | ``` 132 | composer test // Run PHPUnit 133 | composer cs-fix // Fix the coding style 134 | composer cs // Check the coding style 135 | composer sa // Run static analysis 136 | composer run-script --list // List all commands 137 | ``` 138 | 139 | ## Related Projects for CodeIgniter 4.x 140 | 141 | ### Libraries 142 | 143 | - [CodeIgniter 3 to 4 Upgrade Helper](https://github.com/kenjis/ci3-to-4-upgrade-helper) 144 | - [CodeIgniter3-like Captcha](https://github.com/kenjis/ci3-like-captcha) 145 | - [PHPUnit Helper](https://github.com/kenjis/phpunit-helper) 146 | - [CodeIgniter4 Attribute Routes](https://github.com/kenjis/ci4-attribute-routes) 147 | - [CodeIgniter Simple and Secure Twig](https://github.com/kenjis/codeigniter-ss-twig) 148 | - [CodeIgniter4 Viewi Demo](https://github.com/kenjis/ci4-viewi-demo) 149 | 150 | ### Tutorials 151 | 152 | - [CodeIgniter 4 News Tutorial](https://github.com/kenjis/ci4-news) 153 | - [CodeIgniter 4 Validation Tutorial](https://github.com/kenjis/ci4-validation-tutorial) 154 | - [CodeIgniter4 Code Modules Test](https://github.com/kenjis/ci4-modules-test) 155 | - [CodeIgniter 4 File Upload](https://github.com/kenjis/ci4-file-upload) 156 | 157 | ### Building Development Environment 158 | 159 | - [CodeIgniter4 Application Template](https://github.com/kenjis/ci4-app-template) 160 | - [CodeIgniter4 Composer Installer](https://github.com/kenjis/ci4-composer-installer) 161 | - [docker-codeigniter-apache](https://github.com/kenjis/docker-codeigniter-apache) 162 | -------------------------------------------------------------------------------- /app/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Require all denied 3 | 4 | 5 | Deny from all 6 | 7 | -------------------------------------------------------------------------------- /app/Common.php: -------------------------------------------------------------------------------- 1 | 31 | */ 32 | public array $allowedHostnames = []; 33 | 34 | /** 35 | * -------------------------------------------------------------------------- 36 | * Index File 37 | * -------------------------------------------------------------------------- 38 | * 39 | * Typically this will be your index.php file, unless you've renamed it to 40 | * something else. If you are using mod_rewrite to remove the page set this 41 | * variable so that it is blank. 42 | */ 43 | public string $indexPage = ''; 44 | 45 | /** 46 | * -------------------------------------------------------------------------- 47 | * URI PROTOCOL 48 | * -------------------------------------------------------------------------- 49 | * 50 | * This item determines which server global should be used to retrieve the 51 | * URI string. The default setting of 'REQUEST_URI' works for most servers. 52 | * If your links do not seem to work, try one of the other delicious flavors: 53 | * 54 | * 'REQUEST_URI' Uses $_SERVER['REQUEST_URI'] 55 | * 'QUERY_STRING' Uses $_SERVER['QUERY_STRING'] 56 | * 'PATH_INFO' Uses $_SERVER['PATH_INFO'] 57 | * 58 | * WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! 59 | */ 60 | public string $uriProtocol = 'REQUEST_URI'; 61 | 62 | /** 63 | * -------------------------------------------------------------------------- 64 | * Default Locale 65 | * -------------------------------------------------------------------------- 66 | * 67 | * The Locale roughly represents the language and location that your visitor 68 | * is viewing the site from. It affects the language strings and other 69 | * strings (like currency markers, numbers, etc), that your program 70 | * should run under for this request. 71 | */ 72 | public string $defaultLocale = 'en'; 73 | 74 | /** 75 | * -------------------------------------------------------------------------- 76 | * Negotiate Locale 77 | * -------------------------------------------------------------------------- 78 | * 79 | * If true, the current Request object will automatically determine the 80 | * language to use based on the value of the Accept-Language header. 81 | * 82 | * If false, no automatic detection will be performed. 83 | */ 84 | public bool $negotiateLocale = false; 85 | 86 | /** 87 | * -------------------------------------------------------------------------- 88 | * Supported Locales 89 | * -------------------------------------------------------------------------- 90 | * 91 | * If $negotiateLocale is true, this array lists the locales supported 92 | * by the application in descending order of priority. If no match is 93 | * found, the first locale will be used. 94 | * 95 | * IncomingRequest::setLocale() also uses this list. 96 | * 97 | * @var string[] 98 | */ 99 | public array $supportedLocales = ['en']; 100 | 101 | /** 102 | * -------------------------------------------------------------------------- 103 | * Application Timezone 104 | * -------------------------------------------------------------------------- 105 | * 106 | * The default timezone that will be used in your application to display 107 | * dates with the date helper, and can be retrieved through app_timezone() 108 | * 109 | * @see https://www.php.net/manual/en/timezones.php for list of timezones supported by PHP. 110 | */ 111 | public string $appTimezone = 'UTC'; 112 | 113 | /** 114 | * -------------------------------------------------------------------------- 115 | * Default Character Set 116 | * -------------------------------------------------------------------------- 117 | * 118 | * This determines which character set is used by default in various methods 119 | * that require a character set to be provided. 120 | * 121 | * @see http://php.net/htmlspecialchars for a list of supported charsets. 122 | */ 123 | public string $charset = 'UTF-8'; 124 | 125 | /** 126 | * -------------------------------------------------------------------------- 127 | * Force Global Secure Requests 128 | * -------------------------------------------------------------------------- 129 | * 130 | * If true, this will force every request made to this application to be 131 | * made via a secure connection (HTTPS). If the incoming request is not 132 | * secure, the user will be redirected to a secure version of the page 133 | * and the HTTP Strict Transport Security header will be set. 134 | */ 135 | public bool $forceGlobalSecureRequests = false; 136 | 137 | /** 138 | * -------------------------------------------------------------------------- 139 | * Reverse Proxy IPs 140 | * -------------------------------------------------------------------------- 141 | * 142 | * If your server is behind a reverse proxy, you must whitelist the proxy 143 | * IP addresses from which CodeIgniter should trust headers such as 144 | * X-Forwarded-For or Client-IP in order to properly identify 145 | * the visitor's IP address. 146 | * 147 | * You need to set a proxy IP address or IP address with subnets and 148 | * the HTTP header for the client IP address. 149 | * 150 | * Here are some examples: 151 | * [ 152 | * '10.0.1.200' => 'X-Forwarded-For', 153 | * '192.168.5.0/24' => 'X-Real-IP', 154 | * ] 155 | * 156 | * @var array 157 | */ 158 | public array $proxyIPs = []; 159 | 160 | /** 161 | * -------------------------------------------------------------------------- 162 | * Content Security Policy 163 | * -------------------------------------------------------------------------- 164 | * 165 | * Enables the Response's Content Secure Policy to restrict the sources that 166 | * can be used for images, scripts, CSS files, audio, video, etc. If enabled, 167 | * the Response object will populate default values for the policy from the 168 | * `ContentSecurityPolicy.php` file. Controllers can always add to those 169 | * restrictions at run time. 170 | * 171 | * For a better understanding of CSP, see these documents: 172 | * 173 | * @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/ 174 | * @see http://www.w3.org/TR/CSP/ 175 | */ 176 | public bool $CSPEnabled = true; 177 | } 178 | -------------------------------------------------------------------------------- /app/Config/Autoload.php: -------------------------------------------------------------------------------- 1 | SYSTEMPATH, 41 | * 'App' => APPPATH 42 | * ]; 43 | * 44 | * @var array|string> 45 | */ 46 | public $psr4 = [ 47 | APP_NAMESPACE => APPPATH, // For custom app namespace 48 | 'Config' => APPPATH . 'Config', 49 | ]; 50 | 51 | /** 52 | * ------------------------------------------------------------------- 53 | * Class Map 54 | * ------------------------------------------------------------------- 55 | * The class map provides a map of class names and their exact 56 | * location on the drive. Classes loaded in this manner will have 57 | * slightly faster performance because they will not have to be 58 | * searched for within one or more directories as they would if they 59 | * were being autoloaded through a namespace. 60 | * 61 | * Prototype: 62 | * $classmap = [ 63 | * 'MyClass' => '/path/to/class/file.php' 64 | * ]; 65 | * 66 | * @var array 67 | */ 68 | public $classmap = []; 69 | 70 | /** 71 | * ------------------------------------------------------------------- 72 | * Files 73 | * ------------------------------------------------------------------- 74 | * The files array provides a list of paths to __non-class__ files 75 | * that will be autoloaded. This can be useful for bootstrap operations 76 | * or for loading functions. 77 | * 78 | * Prototype: 79 | * $files = [ 80 | * '/path/to/my/file.php', 81 | * ]; 82 | * 83 | * @var list 84 | */ 85 | public $files = []; 86 | 87 | /** 88 | * ------------------------------------------------------------------- 89 | * Helpers 90 | * ------------------------------------------------------------------- 91 | * Prototype: 92 | * $helpers = [ 93 | * 'form', 94 | * ]; 95 | * 96 | * @var list 97 | */ 98 | public $helpers = []; 99 | } 100 | -------------------------------------------------------------------------------- /app/Config/Boot/development.php: -------------------------------------------------------------------------------- 1 | 112 | */ 113 | public array $file = [ 114 | 'storePath' => WRITEPATH . 'cache/', 115 | 'mode' => 0640, 116 | ]; 117 | 118 | /** 119 | * ------------------------------------------------------------------------- 120 | * Memcached settings 121 | * ------------------------------------------------------------------------- 122 | * Your Memcached servers can be specified below, if you are using 123 | * the Memcached drivers. 124 | * 125 | * @see https://codeigniter.com/user_guide/libraries/caching.html#memcached 126 | * 127 | * @var array 128 | */ 129 | public array $memcached = [ 130 | 'host' => '127.0.0.1', 131 | 'port' => 11211, 132 | 'weight' => 1, 133 | 'raw' => false, 134 | ]; 135 | 136 | /** 137 | * ------------------------------------------------------------------------- 138 | * Redis settings 139 | * ------------------------------------------------------------------------- 140 | * Your Redis server can be specified below, if you are using 141 | * the Redis or Predis drivers. 142 | * 143 | * @var array 144 | */ 145 | public array $redis = [ 146 | 'host' => '127.0.0.1', 147 | 'password' => null, 148 | 'port' => 6379, 149 | 'timeout' => 0, 150 | 'database' => 0, 151 | ]; 152 | 153 | /** 154 | * -------------------------------------------------------------------------- 155 | * Available Cache Handlers 156 | * -------------------------------------------------------------------------- 157 | * 158 | * This is an array of cache engine alias' and class names. Only engines 159 | * that are listed here are allowed to be used. 160 | * 161 | * @var array> 162 | */ 163 | public array $validHandlers = [ 164 | 'dummy' => DummyHandler::class, 165 | 'file' => FileHandler::class, 166 | 'memcached' => MemcachedHandler::class, 167 | 'predis' => PredisHandler::class, 168 | 'redis' => RedisHandler::class, 169 | 'wincache' => WincacheHandler::class, 170 | ]; 171 | } 172 | -------------------------------------------------------------------------------- /app/Config/Constants.php: -------------------------------------------------------------------------------- 1 | ` element. 75 | * 76 | * Will default to self if not overridden 77 | * 78 | * @var string|string[]|null 79 | */ 80 | public $baseURI; 81 | 82 | /** 83 | * Lists the URLs for workers and embedded frame contents 84 | * 85 | * @var string|string[] 86 | */ 87 | public $childSrc = 'self'; 88 | 89 | /** 90 | * Limits the origins that you can connect to (via XHR, 91 | * WebSockets, and EventSource). 92 | * 93 | * @var string|string[] 94 | */ 95 | public $connectSrc = 'self'; 96 | 97 | /** 98 | * Specifies the origins that can serve web fonts. 99 | * 100 | * @var string|string[] 101 | */ 102 | public $fontSrc; 103 | 104 | /** 105 | * Lists valid endpoints for submission from `
` tags. 106 | * 107 | * @var string|string[] 108 | */ 109 | public $formAction = 'self'; 110 | 111 | /** 112 | * Specifies the sources that can embed the current page. 113 | * This directive applies to ``, `