diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3751c13 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,58 @@ +name: Release + +on: + push: + branches: + - master + +permissions: + contents: write + +jobs: + release: + name: Create Release + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[skip release]')" + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Extract DMZ_VERSION + id: version + run: | + VERSION=$(grep -oP "define\('DMZ_VERSION',\s*'\K[^']+" application/libraries/datamapper.php) + if [ -z "$VERSION" ]; then + echo "ERROR: Could not extract DMZ_VERSION from application/libraries/datamapper.php" + exit 1 + fi + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "Extracted DMZ_VERSION: ${VERSION}" + + - name: Check if release tag already exists + id: check_tag + run: | + TAG="v${{ steps.version.outputs.version }}" + if git rev-parse "${TAG}" >/dev/null 2>&1; then + echo "Tag ${TAG} already exists — skipping release." + echo "exists=true" >> $GITHUB_OUTPUT + else + echo "Tag ${TAG} does not exist — will create release." + echo "exists=false" >> $GITHUB_OUTPUT + fi + + - name: Create tag + if: steps.check_tag.outputs.exists == 'false' + run: | + TAG="v${{ steps.version.outputs.version }}" + git tag "${TAG}" + git push origin "${TAG}" + + - name: Create GitHub Release + if: steps.check_tag.outputs.exists == 'false' + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ steps.version.outputs.version }} + name: v${{ steps.version.outputs.version }} + generate_release_notes: true + prerelease: ${{ contains(steps.version.outputs.version, 'alpha') || contains(steps.version.outputs.version, 'beta') || contains(steps.version.outputs.version, 'rc') }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 77c013d..1cc087f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to DataMapper ORM will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [2.0.0] - 2026-07-09 ### Added - Laravel-style mass-assignment protection: `$fillable`, `$guarded`, `fill()`, `force_fill()`, `unguard()` helpers, and a static `create()` convenience method. @@ -29,9 +29,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security - Hardened `_unserialize()` with `allowed_classes => FALSE` to prevent PHP object injection. -### Deprecated -- `join_related()` now emits an `E_USER_DEPRECATED` notice. Use `include_related()` instead. - ### Fixed - Fixed dead documentation links in extension headers (overzealous.com → github.com/P2GR/datamapper2). - Fixed typo in rowindex.php header (`worIndex` → `rowindex`). diff --git a/README.md b/README.md index 5896925..9a369ac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# DataMapper ORM v2.0.0-beta1 +# DataMapper ORM v2.0.0 [![CI](https://img.shields.io/github/actions/workflow/status/P2GR/datamapper/ci.yml?branch=2.0.0-beta1&label=CI&logo=github)](https://github.com/P2GR/datamapper/actions/workflows/ci.yml) [![PHP Version](https://img.shields.io/badge/PHP-7.4--8.5%2B-blue)](https://php.net) diff --git a/application/libraries/datamapper.php b/application/libraries/datamapper.php index 2a2c529..d01336b 100644 --- a/application/libraries/datamapper.php +++ b/application/libraries/datamapper.php @@ -12,7 +12,7 @@ * @author Phil DeJarnett (up to v1.7.1) * @author Simon Stenhouse (up to v1.6.0) * @link http://datamapper.wanwizard.eu/ - * @version 2.0.0-beta1 + * @version 2.0.0 */ /** @@ -23,7 +23,7 @@ /** * DMZ version */ -define('DMZ_VERSION', '2.0.0-beta1'); +define('DMZ_VERSION', '2.0.0'); // Define APPPATH when running outside of CodeIgniter bootstrap (e.g., CLI tooling) if (!defined('APPPATH')) { @@ -6662,12 +6662,15 @@ public function include_related($related_field, $fields = NULL, $append_name = T } /** - * Legacy version of include_related - * @deprecated 2.0.0 Use include_related() instead. Will be removed in a future release. + * Join a related model into the current query as extra columns. + * + * @param mixed $related_field Related field or object + * @param mixed $fields Fields to include (NULL = all) + * @param bool $append_name Whether to prefix column names with the relationship name + * @return DataMapper Returns self for method chaining. */ public function join_related($related_field, $fields = NULL, $append_name = TRUE) { - trigger_error('join_related() is deprecated. Use include_related() instead.', E_USER_DEPRECATED); return $this->include_related($related_field, $fields, $append_name); } diff --git a/application/third_party/datamapper/bootstrap.php b/application/third_party/datamapper/bootstrap.php index c1a650b..1bbaaad 100644 --- a/application/third_party/datamapper/bootstrap.php +++ b/application/third_party/datamapper/bootstrap.php @@ -9,7 +9,7 @@ * @category DataMapper ORM * @author Harro "WanWizard" Verton * @link http://datamapper.wanwizard.eu/ - * @version 2.0.0-dev + * @version 2.0.0 */ // make sure we have a DATAMAPPERPATH diff --git a/docs/guide/datamapper-2/advanced-query-building.md b/docs/guide/datamapper-2/advanced-query-building.md index 9bb7f9d..8488985 100644 --- a/docs/guide/datamapper-2/advanced-query-building.md +++ b/docs/guide/datamapper-2/advanced-query-building.md @@ -238,7 +238,21 @@ $users = (new UserSearch())->apply($filters)->get(); ## Notes on Scopes -Laravel-style `scope_active()` discovery and `add_global_scope()` are not part of the current DataMapper 2.0 implementation. Use explicit model methods, `when()`/`unless()`, soft-delete helpers, or eager-loading constraints instead. +DataMapper 2.0 supports **local query scopes** via the `scope_` prefix convention. Define a method like `scope_published()` on your model, then call `$model->published()` — the `__call()` magic method discovers and invokes it, returning `$this` for chaining. + +```php +class Post extends DataMapper { + public function scope_published() { + return $this->where('status', 'published'); + } +} + +(new Post())->published()->get(); +``` + +**Global scopes** (`add_global_scope()`) are not yet implemented. For reusable cross-model query constraints, use explicit model methods, `when()`/`unless()`, soft-delete helpers, or eager-loading constraints instead. + +See [Local Query Scopes](/guide/datamapper-2/#local-query-scopes) for more examples. ## See Also diff --git a/docs/help/changelog.md b/docs/help/changelog.md index 4a2efe1..8376d94 100644 --- a/docs/help/changelog.md +++ b/docs/help/changelog.md @@ -5,25 +5,7 @@ All notable changes to DataMapper ORM will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] - -### Added -- Mass-assignment protection (`$fillable`, `$guarded`, `fill()`, `force_fill()`, `Model::create()`) with full documentation and examples. -- CI/CD workflows: PHP test matrix (8.1–8.5) and VitePress docs deployment via SSH. - -### Changed -- `join_related()` now emits an `E_USER_DEPRECATED` notice. Use `include_related()` instead. - -### Removed -- Removed camelCase aliases `toArray()` and `applyOperations()` from `DMZ_LazyCollection`. Use `to_array()` and `apply_operations()` instead. - -### Security -- Hardened `_unserialize()` with `allowed_classes => FALSE` to prevent PHP object injection. - -### Fixed -- Removed `@` error suppression on querybuilder auto-loading. - -## [2.0.0] - 2024-12-15 +## [2.0.0] - 2026-07-09 ### Added - Major Features @@ -46,6 +28,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Streaming Results** - Memory-efficient result processing - **Advanced Query Building** - Subqueries, relationship filters, grouping, aggregates, and raw expressions - **Better Error Messages** - More descriptive validation and query errors +- **Mass-Assignment Protection** - `$fillable`, `$guarded`, `fill()`, `force_fill()`, `Model::create()` +- **CI/CD Workflows** - PHP test matrix (8.1–8.5) and VitePress docs deployment via SSH + +### Security +- Hardened `_unserialize()` with `allowed_classes => FALSE` to prevent PHP object injection ### Changed - Breaking Changes @@ -55,6 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Validation errors now use associative array format - New `Model::create()` helper is static—replace instance calls like `$user->create()` with `User::create()` +### Removed +- Removed camelCase aliases `toArray()` and `applyOperations()` from `DMZ_LazyCollection` — use `to_array()` and `apply_operations()` + +### Fixed +- Removed `@` error suppression on querybuilder auto-loading + ### Improved - Performance - Eager loading reduces repeated relationship queries when used on relations that will be accessed diff --git a/package.json b/package.json index 52cfe91..493e2fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "datamapper", - "version": "1.0.0", + "version": "2.0.0", "description": "[![PHP Version](https://img.shields.io/badge/PHP-7.4--8.5%2B-blue)](https://php.net) [![CodeIgniter](https://img.shields.io/badge/CodeIgniter-3.x-orange)](https://codeigniter.com) [![License](https://img.shields.io/badge/License-MIT-green)](license.txt) [![GitHub](https://img.shields.io/badge/GitHub-P2GR%2Fdatamapper-blue)](https://github.com/P2GR/datamapper)", "main": "index.js", "directories": {