Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
79c37ea
refactor: Migrate from doctrine/annotations to PHP 8 Attributes
koriym Nov 6, 2025
b52a804
Add annotation to attribute migration support
koriym Nov 8, 2025
34a5ef3
refactor: Remove doctrine/annotations remnants from attribute classes
koriym Nov 9, 2025
8891cd7
refactor: Remove koriym/attributes dependency and migrate to native P…
koriym Nov 9, 2025
c481743
Add post-install-cmd command to prevent PHP version conflict
koriym Nov 9, 2025
7e7a055
refactor: Complete removal of doctrine/annotations and doctrine/cache…
koriym Nov 9, 2025
c0898ac
refactor: Make ext-redis optional with @requires annotations
koriym Nov 9, 2025
12188d6
fix: Remove obsolete PHPStan ignoreErrors for deleted test code
koriym Nov 9, 2025
66182f9
refactor: Clean up demo files from doctrine/annotations remnants
koriym Nov 9, 2025
2be656d
update .scrutinizer.yml php 8.4
koriym Nov 9, 2025
fc18dae
refactor: Improve rector-migrate.php and migration guide for vendor i…
koriym Nov 10, 2025
683b2af
docs: Update CHANGELOG for rector-migrate.php improvements
koriym Nov 10, 2025
60da77e
chore: Use dev-fix-legacy-annotations branch for ray/psr-cache-module
koriym Nov 10, 2025
5339b16
chore: Update ray/psr-cache-module to ^1.5.1
koriym Nov 10, 2025
b1b246a
refactor: Remove legacy doctrine annotation docblock tags
koriym Nov 10, 2025
df51c58
refactor: Remove all docblock annotations from test fixtures
koriym Nov 10, 2025
28bc37e
refactor: Require PHP 8.2+ and clean up test fixtures
koriym Nov 10, 2025
f50ef0c
docs: Update CHANGELOG with PHP 8.2 requirement
koriym Nov 10, 2025
c8d977f
ci: Remove PHP 8.1 from test matrix
koriym Nov 10, 2025
b9e1584
chore: Update PHPCS target PHP version to 8.2
koriym Nov 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ jobs:
matrix:
include:
# Ubuntu: Test all PHP versions
- os: ubuntu-latest
php-version: "8.1"
dependencies: highest
- os: ubuntu-latest
php-version: "8.2"
dependencies: lowest
Expand Down
25 changes: 10 additions & 15 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
filter:
paths: ["src/*"]

tools:
php_sim: true
php_pdepend: true
php_analyzer: true
build:
image: default-bionic
nodes:
analysis:
tests:
override:
- php-scrutinizer-run --enable-security-analysis
image: default-jammy
environment:
redis: true
php:
version: 8.2
version: 8.4
pecl_extensions:
- redis
nodes:
analysis:
tests:
override:
- php-scrutinizer-run

filter:
paths: ["src/*"]
315 changes: 315 additions & 0 deletions ANNOTATION_TO_ATTRIBUTE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
# Migrating from Doctrine Annotations to PHP 8 Attributes

## Overview

BEAR.QueryRepository 1.13.0 has removed the dependency on `doctrine/annotations` and now exclusively uses native PHP 8 attributes. This guide will help you migrate your application code from Doctrine annotations to PHP 8 attributes.

## Why Migrate?

- **doctrine/annotations is Abandoned**: The `doctrine/annotations` package has been officially abandoned by its maintainers. Continuing to use it poses security and compatibility risks as it will no longer receive updates or security patches.
- **Native PHP Support**: PHP 8 attributes are a built-in language feature, providing first-class support without external dependencies
- **Better Performance**: No runtime annotation parsing overhead - attributes are compiled and cached by PHP itself
- **Modern Syntax**: Cleaner, more readable code that follows PHP 8+ best practices
- **No Extra Dependencies**: Eliminates the need for the abandoned doctrine/annotations package
- **Future-Proof**: Attributes are the official PHP standard for metadata, ensuring long-term compatibility

## Migration Steps

### Step 1: Install Rector (if not already installed)

Rector is an automated refactoring tool that can convert annotations to attributes:

```bash
composer require --dev rector/rector
```

### Step 2: Run Automated Migration

BEAR.QueryRepository provides a Rector configuration file for automated migration:

```bash
# Dry-run to preview changes
vendor/bin/rector process src --config=vendor/bear/query-repository/rector-migrate.php --dry-run

# Apply the changes
vendor/bin/rector process src --config=vendor/bear/query-repository/rector-migrate.php
```

If you have tests that use annotations:

```bash
vendor/bin/rector process tests --config=vendor/bear/query-repository/rector-migrate.php
```

### Step 3: Manual Review

Review the changes made by Rector and adjust if necessary. Pay special attention to:

- Multi-line annotations with complex values
- Annotations with custom parameters
- Import statements (Rector should handle these automatically)

### Step 4: Remove doctrine/annotations

After migration, you can safely remove the doctrine/annotations dependency:

```bash
composer remove doctrine/annotations
```

## Before and After Examples

### Cacheable Resource

**Before (Doctrine Annotation):**
```php
use BEAR\RepositoryModule\Annotation\Cacheable;

/**
* @Cacheable(expiry="short", type="value")
*/
class User extends ResourceObject
{
public function onGet($id)
{
// ...
}
}
```

**After (PHP 8 Attribute):**
```php
use BEAR\RepositoryModule\Annotation\Cacheable;

#[Cacheable(expiry: "short", type: "value")]
class User extends ResourceObject
{
public function onGet($id)
{
// ...
}
}
```

### HTTP Cache Headers

**Before (Doctrine Annotation):**
```php
use BEAR\RepositoryModule\Annotation\HttpCache;

/**
* @HttpCache(maxAge=60, sMaxAge=600)
*/
class News extends ResourceObject
{
public function onGet()
{
// ...
}
}
```

**After (PHP 8 Attribute):**
```php
use BEAR\RepositoryModule\Annotation\HttpCache;

#[HttpCache(maxAge: 60, sMaxAge: 600)]
class News extends ResourceObject
{
public function onGet()
{
// ...
}
}
```

### Cache Invalidation

**Before (Doctrine Annotation):**
```php
use BEAR\RepositoryModule\Annotation\Refresh;
use BEAR\RepositoryModule\Annotation\Purge;

class User extends ResourceObject
{
/**
* @Refresh(uri="app://self/users")
* @Purge(uri="app://self/user/{id}")
*/
public function onPut($id, $name)
{
// ...
}
}
```

**After (PHP 8 Attribute):**
```php
use BEAR\RepositoryModule\Annotation\Refresh;
use BEAR\RepositoryModule\Annotation\Purge;

class User extends ResourceObject
{
#[Refresh(uri: "app://self/users")]
#[Purge(uri: "app://self/user/{id}")]
public function onPut($id, $name)
{
// ...
}
}
```

### Complex Cache Configuration

**Before (Doctrine Annotation):**
```php
use BEAR\RepositoryModule\Annotation\Cacheable;
use BEAR\RepositoryModule\Annotation\HttpCache;

/**
* @Cacheable(expiry="medium", expirySecond=3600, type="view", update=true)
* @HttpCache(maxAge=60, sMaxAge=600, isPrivate=false, mustRevalidate=true)
*/
class Article extends ResourceObject
{
// ...
}
```

**After (PHP 8 Attribute):**
```php
use BEAR\RepositoryModule\Annotation\Cacheable;
use BEAR\RepositoryModule\Annotation\HttpCache;

#[Cacheable(expiry: "medium", expirySecond: 3600, type: "view", update: true)]
#[HttpCache(maxAge: 60, sMaxAge: 600, isPrivate: false, mustRevalidate: true)]
class Article extends ResourceObject
{
// ...
}
```

### Donut Caching

**Before (Doctrine Annotation):**
```php
use BEAR\RepositoryModule\Annotation\DonutCache;

class Page extends ResourceObject
{
/**
* @DonutCache
*/
public function onGet()
{
// ...
}
}
```

**After (PHP 8 Attribute):**
```php
use BEAR\RepositoryModule\Annotation\DonutCache;

class Page extends ResourceObject
{
#[DonutCache]
public function onGet()
{
// ...
}
}
```

## Supported Annotations

The following BEAR.QueryRepository annotations are automatically converted:

- `@Cacheable` → `#[Cacheable]` - Resource caching configuration
- `@HttpCache` → `#[HttpCache]` - HTTP cache control headers
- `@NoHttpCache` → `#[NoHttpCache]` - Disable HTTP caching
- `@Refresh` → `#[Refresh]` - Invalidate dependent caches
- `@Purge` → `#[Purge]` - Purge specific cache entries
- `@DonutCache` → `#[DonutCache]` - Donut caching pattern
- `@RefreshCache` → `#[RefreshCache]` - Refresh cache after command
- `@Commands` → `#[Commands]` - Cache invalidation commands

**Note**: This migration tool only handles BEAR.QueryRepository annotations. For Ray.Di annotations (such as `@Inject`, `@Named`, etc.), please refer to the [Ray.Di migration guide](https://github.com/ray-di/Ray.Di).

## Key Differences

1. **Syntax Change**: Use `#[AttributeName]` instead of `@AttributeName` in docblocks
2. **Named Parameters**: Use colons for parameters (e.g., `expiry: "short"` instead of `expiry="short"`)
3. **Placement**: Attributes go before the class/method declaration, not in docblocks
4. **Import Statements**: Add proper `use` statements for all attributes
5. **Multiple Attributes**: Stack multiple attributes on separate lines or combine with commas

## Troubleshooting

### Rector doesn't find annotations

Make sure your code is using fully qualified class names in `use` statements:

```php
// Correct
use BEAR\RepositoryModule\Annotation\Cacheable;

// Incorrect - Rector won't recognize this
use BEAR\RepositoryModule\Annotation as Cache;
```

### Import statements not updated

Rector should automatically update import statements, but if it doesn't:

1. Manually verify `use` statements are present
2. Run your IDE's "Optimize Imports" feature
3. Use tools like PHP-CS-Fixer to clean up unused imports

### Complex annotation values

For annotations with complex array values, you may need to manually adjust the syntax:

**Before:**
```php
/**
* @HttpCache(etag={"id", "updated_at"})
*/
```

**After:**
```php
#[HttpCache(etag: ["id", "updated_at"])]
```

### Testing the migration

After migration, ensure all tests pass:

```bash
vendor/bin/phpunit
```

## Manual Migration

If you prefer not to use Rector, you can manually convert annotations:

1. Replace `/** @AnnotationName */` with `#[AnnotationName]`
2. Move attributes from docblocks to the line before the method/property/class
3. Convert parameter syntax from `key="value"` to `key: "value"`
4. Ensure all necessary `use` statements are present
5. For multiple attributes, place each on a new line or combine: `#[Attr1, Attr2]`

## Need Help?

If you encounter issues during migration:

1. Check the [BEAR.QueryRepository documentation](https://github.com/bearsunday/BEAR.QueryRepository)
2. Review the [PHP 8 Attributes documentation](https://www.php.net/manual/en/language.attributes.php)
3. [Open an issue](https://github.com/bearsunday/BEAR.QueryRepository/issues) on GitHub

## References

- [PHP 8 Attributes RFC](https://wiki.php.net/rfc/attributes_v2)
- [Rector Documentation](https://github.com/rectorphp/rector)
- [BEAR.Sunday Documentation](https://bearsunday.github.io/)
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.13.0] - 2025-10-21

### Added
- **Migration Tools**: Added `rector-migrate.php` for automated annotation-to-attribute migration
- **Migration Guide**: Added `ANNOTATION_TO_ATTRIBUTE.md` with comprehensive migration instructions
- Add CLAUDE.md with comprehensive codebase architecture and development guide
- Add marshaller configuration support for Redis with compression options (deflate)
- Add `MarshallerType` enum for type-safe marshaller selection
Expand All @@ -25,6 +25,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add PHP 8.5 support to CI workflow

### Changed
- **PHP 8 Attributes Migration**: Removed `doctrine/annotations` and `doctrine/cache` dependencies, migrated to native PHP 8 attributes
- **Minimum PHP Version**: Updated requirement from PHP 8.1 to PHP 8.2
- Improve `rector-migrate.php` to support vendor installation by removing hardcoded paths
- Update `ANNOTATION_TO_ATTRIBUTE.md` migration guide following Ray.AuraSqlModule pattern
- Improve marshaller provider error handling with better exception messages
- Enhance Memcached module with TagAwareAdapter support
- Update Symfony Cache to support version ^7.3
Expand Down
4 changes: 3 additions & 1 deletion composer-require-checker.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"static", "self", "parent",
"array", "string", "int", "float", "bool", "iterable", "callable", "void", "object",
"Attribute", "Memcached", "Redis", "RedisException",
"Doctrine\\Common\\Cache\\ArrayCache", "Doctrine\\Common\\Cache\\MemcachedCache", "Doctrine\\Common\\Cache\\RedisCache",
"Doctrine\\Common\\Cache\\CacheProvider",
"Doctrine\\Common\\Cache\\MemcachedCache",
"Doctrine\\Common\\Cache\\RedisCache",
"BEAR\\FastlyModule\\FastlyCachePurgerInterface", "BEAR\\FastlyModule\\FastlyPurgeModule",
"Detection\\MobileDetect"
]
Expand Down
Loading
Loading