diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..32d5339b --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +FUEL_ENV=development + +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=lefuel +DB_USERNAME=lefuel +DB_PASSWORD=secret diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..7f7640dc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,70 @@ +name: CI + +on: + push: + branches: ["**"] + pull_request: + branches: ["**"] + +jobs: + test: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: ["8.1", "8.2", "8.3"] + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: lefuel_test + ports: + - 3306:3306 + options: >- + --health-cmd="mysqladmin ping" + --health-interval=10s + --health-timeout=5s + --health-retries=5 + + steps: + - uses: actions/checkout@v4 + + - name: Set up PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: mbstring, pdo, pdo_mysql, xml + coverage: none + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: fuel/vendor + key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('composer.json') }} + restore-keys: | + ${{ runner.os }}-php-${{ matrix.php }}- + + - name: Install dependencies + run: composer install --no-scripts --prefer-dist --no-progress + + - name: Copy env + run: cp .env.example .env + + - name: Run tests + run: | + if [ -d fuel/app/tests ]; then + ./fuel/vendor/bin/phpunit --testdox fuel/app/tests + else + echo "No tests found yet — skipping." + fi + env: + FUEL_ENV: test + DB_HOST: 127.0.0.1 + DB_PORT: 3306 + DB_DATABASE: lefuel_test + DB_USERNAME: root + DB_PASSWORD: root diff --git a/.gitignore b/.gitignore index 19eae45d..467d8865 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,12 @@ desktop.ini /composer.lock /fuel/vendor +# composer binary (use system-installed composer instead) +composer.phar + +# environment files +.env + # any of the fuel packages installed by default /docs/ /fuel/core/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dc1f64c1..00000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: php -php: - - 5.3 - - 5.4 - - 5.5 - - 7.0 - -before_script: - - curl -s http://getcomposer.org/installer | php - - php composer.phar install --dev - -script: php oil test diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 00000000..5899035d --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,93 @@ +# LeFuel Architecture + +LeFuel is a fork of FuelPHP 1.8 targeting PHP 8.1+. This document describes every top-level folder and its purpose. + +--- + +## Root + +| Path | Purpose | +|------|---------| +| `composer.json` | Dependency manifest. Packages install into `fuel/vendor/` (third-party) and `fuel/core/`, `fuel/packages/*/` (FuelPHP packages). | +| `oil` | CLI entry-point. `php oil ` runs generators, migrations, tasks, and the built-in test runner. | +| `Dockerfile` | Single-stage `php:8.3-cli` image that serves the app on port 8000. | +| `docker-compose.yml` | Defines the `app` service (this image) and a `mysql:8.0` service with a persistent named volume. | +| `.env.example` | Template for the `.env` file that each environment copies and fills in. Never committed. | +| `.github/workflows/ci.yml` | GitHub Actions matrix CI — runs PHPUnit against PHP 8.1, 8.2, and 8.3 with a MySQL 8 sidecar. | + +--- + +## `fuel/` + +The entire PHP runtime lives here. Only `fuel/app/` is committed; everything else is Composer-installed and git-ignored. + +### `fuel/app/` + +Application code you write and own. + +| Sub-path | Purpose | +|----------|---------| +| `bootstrap.php` | Application bootstrap. Loaded by `public/index.php`; sets the app path and environment, then hands off to the FuelPHP kernel. | +| `classes/controller/` | HTTP controllers. Each file is a class named `Controller_` extending `Controller` (or a sub-type). Methods prefixed `action_` map to URL segments. | +| `classes/model/` | Data-layer models. Extend `\Orm\Model` for Active Record, or use raw `DB::` calls. | +| `classes/presenter/` | Presenter/ViewModel layer. Sits between controllers and views, keeps logic out of templates. | +| `config/` | Configuration files. `config.php` is the master config; `db.php` holds database DSNs. Sub-folders (`development/`, `production/`, `staging/`, `test/`) override settings per `FUEL_ENV`. `routes.php` maps URL patterns to controller/action pairs. | +| `lang/` | i18n strings, keyed by locale (`en/`, etc.). | +| `logs/` | Runtime log files (git-ignored below day level). | +| `cache/` | File-based cache output (git-ignored). | +| `migrations/` | Numbered migration files run via `php oil r migrate`. | +| `modules/` | Self-contained feature modules. Each module mirrors the `app/` structure and is loaded on demand. | +| `tasks/` | CLI task classes run via `php oil r `. `robots.php` is the bundled example. | +| `tests/` | PHPUnit test suites mirroring `classes/` (controller, model, presenter, view sub-directories). | +| `themes/` | Theme asset sets for the Theme package (optional). | +| `tmp/` | Transient working files (e.g. upload staging). Git-ignored. | +| `vendor/` | App-level Composer packages (distinct from `fuel/vendor/`). Rarely used directly. | +| `views/` | PHP view templates. Organised as `views//.php`. | + +### `fuel/core/` *(git-ignored, Composer-installed)* + +The FuelPHP kernel: autoloader, base classes, Input, Output, Request, Response, Session, Security, and all core helpers. Installed to `fuel/core/` via the `composer/installers` path rule. + +### `fuel/packages/` *(git-ignored, Composer-installed)* + +Optional first-party packages installed alongside core: + +| Package | Purpose | +|---------|---------| +| `auth/` | Authentication (login, ACL, hashing). | +| `email/` | Email sending abstraction. | +| `oil/` | CLI tool internals (generators, scaffolding). | +| `orm/` | Object-Relational Mapper (Active Record pattern). | +| `parser/` | Template engine bridge (Twig, Smarty, Mustache, etc.). | + +### `fuel/vendor/` *(git-ignored, Composer-installed)* + +All Composer third-party dependencies (e.g. `phpunit/phpunit`, `fuelphp/upload`). Managed entirely by Composer; never edit manually. + +--- + +## `public/` + +The web root. Point your web server's `document_root` here. + +| Sub-path | Purpose | +|----------|---------| +| `index.php` | Front controller. Sets `DOCROOT`, loads `fuel/app/bootstrap.php`, and dispatches the request. | +| `.htaccess` | Apache rewrite rules that funnel all requests to `index.php`. | +| `web.config` | IIS equivalent of `.htaccess`. | +| `assets/` | Static assets served directly: Bootstrap CSS/JS and Glyphicon fonts. Organised as `assets/{css,js,fonts,img}/`. | +| `favicon.ico` | Default favicon. | + +--- + +## Request Lifecycle (summary) + +``` +Browser → public/index.php + → fuel/app/bootstrap.php (env, paths) + → fuel/core (Request/Router) + → fuel/app/config/routes.php + → Controller_::action_() + → View::forge('folder/template') + → Response → Browser +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..9f2345bf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM php:8.3-cli + +RUN apt-get update && apt-get install -y \ + git \ + unzip \ + libzip-dev \ + libonig-dev \ + libxml2-dev \ + && docker-php-ext-install pdo pdo_mysql mbstring zip xml \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=composer:2 /usr/bin/composer /usr/bin/composer + +WORKDIR /app + +COPY composer.json ./ +RUN composer install --no-scripts --prefer-dist --no-progress + +COPY . . + +EXPOSE 8000 + +CMD ["php", "-S", "0.0.0.0:8000", "public/index.php"] diff --git a/composer.json b/composer.json index 61a9404d..6f695a1f 100644 --- a/composer.json +++ b/composer.json @@ -1,11 +1,11 @@ { - "name": "fuel/fuel", + "name": "leborn-dev/lefuel", "type": "project", "description" : "FuelPHP is a simple, flexible, community driven PHP 5.4+ framework, based on the best ideas of other frameworks, with a fresh start!", "keywords": ["application", "website", "development", "framework", "PHP", "PHP7"], "license": "MIT", "require": { - "php": ">=5.4", + "php": ">=8.1", "composer/installers": "~1.0", "fuel/core": "1.8.*", "fuel/auth": "1.8.*", @@ -16,7 +16,8 @@ "fuelphp/upload": "2.0.6" }, "require-dev": { - "fuel/docs": "1.8.*" + "fuel/docs": "1.8.*", + "phpunit/phpunit": "^10.0" }, "suggest": { "dwoo/dwoo" : "Allow Dwoo templating with the Parser package", @@ -28,7 +29,10 @@ "zordius/lightncandy": "Allow Handlebars templating with an extremely fast PHP implementation of handlebars" }, "config": { - "vendor-dir": "fuel/vendor" + "vendor-dir": "fuel/vendor", + "allow-plugins": { + "composer/installers": true + } }, "extra": { "installer-paths": { diff --git a/composer.phar b/composer.phar deleted file mode 100755 index 499114bb..00000000 Binary files a/composer.phar and /dev/null differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..1604125d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,37 @@ +services: + app: + build: . + ports: + - "8000:8000" + environment: + FUEL_ENV: development + DB_HOST: mysql + DB_PORT: 3306 + DB_DATABASE: lefuel + DB_USERNAME: lefuel + DB_PASSWORD: secret + volumes: + - .:/app + depends_on: + mysql: + condition: service_healthy + + mysql: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: rootsecret + MYSQL_DATABASE: lefuel + MYSQL_USER: lefuel + MYSQL_PASSWORD: secret + ports: + - "3306:3306" + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + mysql_data: diff --git a/fuel/app/classes/controller/hello.php b/fuel/app/classes/controller/hello.php new file mode 100644 index 00000000..6cb8190d --- /dev/null +++ b/fuel/app/classes/controller/hello.php @@ -0,0 +1,9 @@ + array(DOCROOT.'assets/'), +); diff --git a/fuel/app/config/routes.php b/fuel/app/config/routes.php index 4d4cfd2e..fb3dc71d 100644 --- a/fuel/app/config/routes.php +++ b/fuel/app/config/routes.php @@ -39,4 +39,6 @@ */ 'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'), + + 'helloworld' => 'hello/index', ); diff --git a/fuel/app/views/hello/index.php b/fuel/app/views/hello/index.php new file mode 100644 index 00000000..05efb9b6 --- /dev/null +++ b/fuel/app/views/hello/index.php @@ -0,0 +1,12 @@ + + + + + + Hello World - LeFuel + + +

Hello World!

+

Welcome to LeFuel.

+ + diff --git a/router.php b/router.php new file mode 100644 index 00000000..5026bd5d --- /dev/null +++ b/router.php @@ -0,0 +1,25 @@ +