From 3a9b90fc20884802021563c2ce1dfd5ba16a3d83 Mon Sep 17 00:00:00 2001 From: Caio Fernandes Date: Wed, 9 Jul 2025 11:00:32 -0300 Subject: [PATCH 1/6] Remove outdated documentation and scripts related to the PivotPHP Cycle ORM project - Deleted CYCLE_ORM_UPDATE_STATUS.md as it is no longer relevant. - Removed PACKAGIST_MIGRATION_REPORT.md which is obsolete after migration. - Eliminated PHPSTAN_FIXES_SUMMARY.md as fixes are now integrated. - Removed composer.json.local and composer.json.production files as they are no longer needed. - Deleted composer.scripts.json since its content is now part of composer.json. - Removed examples of usage patterns in valida-conceito-patterns.md as they are outdated. - Deleted metodos-corretos-helixphp.md for being redundant. - Removed update_composer_for_production.sh and update_dependencies.sh scripts as they are no longer necessary. --- .gitignore | 1 + .php-cs-fixer.cache | 1 - CYCLE_ORM_UPDATE_STATUS.md | 48 --- PACKAGIST_MIGRATION_REPORT.md | 92 ----- PHPSTAN_FIXES_SUMMARY.md | 39 -- composer.json.local | 86 ----- composer.json.production | 80 ---- composer.scripts.json | 23 -- docs/examples/valida-conceito-patterns.md | 438 ---------------------- docs/index.md | 1 - docs/metodos-corretos-helixphp.md | 77 ---- update_composer_for_production.sh | 109 ------ update_dependencies.sh | 49 --- 13 files changed, 1 insertion(+), 1043 deletions(-) delete mode 100644 .php-cs-fixer.cache delete mode 100644 CYCLE_ORM_UPDATE_STATUS.md delete mode 100644 PACKAGIST_MIGRATION_REPORT.md delete mode 100644 PHPSTAN_FIXES_SUMMARY.md delete mode 100644 composer.json.local delete mode 100644 composer.json.production delete mode 100644 composer.scripts.json delete mode 100644 docs/examples/valida-conceito-patterns.md delete mode 100644 docs/metodos-corretos-helixphp.md delete mode 100755 update_composer_for_production.sh delete mode 100755 update_dependencies.sh diff --git a/.gitignore b/.gitignore index 882b41a..b6ce056 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ vendor/ #User CLAUDE.md .claude +*.cache diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache deleted file mode 100644 index 60b80a9..0000000 --- a/.php-cs-fixer.cache +++ /dev/null @@ -1 +0,0 @@ -{"php":"8.4.8","version":"3.80.0:v3.80.0#e49ed46b8f7adcc451d4cd2ed34eaae33372bc60","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"single_space","operators":{"=>":null}},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_anonymous_functions":true,"allow_single_line_empty_anonymous_classes":true},"class_definition":{"single_line":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":{"anonymous_class":false},"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["curly_brace_block","extra","parenthesis_brace_block","square_brace_block","throw","use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":true,"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"alpha"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":true,"single_space_around_construct":true,"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":true,"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":true,"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":{"stick_comment_to_next_continuous_control_statement":true},"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"blank_line_before_statement":{"statements":["return"]},"combine_consecutive_issets":true,"combine_consecutive_unsets":true,"empty_loop_body":true,"explicit_indirect_variable":true,"explicit_string_variable":true,"fully_qualified_strict_types":{"import_symbols":true},"heredoc_to_nowdoc":true,"method_chaining_indentation":true,"multiline_comment_opening_closing":true,"multiline_whitespace_before_semicolons":{"strategy":"new_line_for_chained_calls"},"no_superfluous_elseif":true,"no_superfluous_phpdoc_tags":{"allow_mixed":true,"remove_inheritdoc":true},"no_unneeded_control_parentheses":true,"no_useless_else":true,"no_useless_return":true,"no_whitespace_before_comma_in_array":true,"operator_linebreak":true,"ordered_types":true,"php_unit_data_provider_method_order":true,"php_unit_internal_class":true,"php_unit_test_class_requires_covers":true,"phpdoc_add_missing_param_annotation":true,"phpdoc_no_empty_return":true,"phpdoc_order_by_value":true,"phpdoc_types_order":true,"phpdoc_var_annotation_correct_order":true,"protected_to_private":true,"return_assignment":true,"self_static_accessor":true,"single_line_comment_style":{"comment_types":["hash"]},"single_line_empty_body":true,"string_implicit_backslashes":true,"trailing_comma_in_multiline":{"elements":["arrays"]},"whitespace_after_comma_in_array":true,"array_indentation":true,"array_syntax":{"syntax":"short"},"cast_spaces":true,"concat_space":{"spacing":"one"},"align_multiline_comment":true,"backtick_to_shell_exec":true,"class_attributes_separation":{"elements":{"method":"one","property":"one"}},"class_reference_name_casing":true,"clean_namespace":true,"declare_parentheses":true,"echo_tag_syntax":true,"empty_loop_condition":true,"general_phpdoc_tag_rename":{"replacements":{"inheritDocs":"inheritDoc"}},"global_namespace_import":{"import_classes":false,"import_constants":false,"import_functions":false},"include":true,"increment_style":{"style":"post"},"integer_literal_case":true,"lambda_not_used_import":true,"linebreak_after_opening_tag":true,"magic_constant_casing":true,"magic_method_casing":true,"native_function_casing":true,"native_type_declaration_casing":true,"no_alias_language_construct_call":true,"no_alternative_syntax":true,"no_binary_string":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":{"use":"echo"},"no_multiline_whitespace_around_double_arrow":true,"no_null_property_initialization":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_trailing_comma_in_singleline":true,"no_unneeded_braces":{"namespaces":true},"no_unneeded_import_alias":true,"no_unset_cast":true,"no_unused_imports":true,"no_useless_concat_operator":true,"no_useless_nullsafe_operator":true,"normalize_index_brace":true,"nullable_type_declaration":true,"nullable_type_declaration_for_default_null_value":true,"object_operator_without_whitespace":true,"php_unit_fqcn_annotation":true,"php_unit_method_casing":true,"phpdoc_align":true,"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag_normalizer":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":true,"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_order":{"order":["param","return","throws"]},"phpdoc_return_self_reference":true,"phpdoc_scalar":true,"phpdoc_separation":true,"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_tag_type":{"tags":{"inheritDoc":"inline"}},"phpdoc_to_comment":true,"phpdoc_trim":true,"phpdoc_trim_consecutive_blank_line_separation":true,"phpdoc_types":true,"phpdoc_var_without_name":true,"semicolon_after_instruction":true,"simple_to_complex_string_variable":true,"single_line_comment_spacing":true,"single_quote":true,"space_after_semicolon":true,"standardize_increment":true,"standardize_not_equals":true,"switch_continue_to_break":true,"trim_array_spaces":true,"type_declaration_spaces":true,"types_spaces":true,"yoda_style":true,"function_typehint_space":true,"new_with_braces":true,"no_trailing_comma_in_list_call":true,"no_trailing_comma_in_singleline_array":true,"self_accessor":true,"simplified_null_return":true},"hashes":{"src\/Http\/CycleRequest.php":"d61806ca6efca3afdb064249f279ff77","src\/Monitoring\/PerformanceProfiler.php":"4c1e039d02da2c519996139444dd81a5","src\/Monitoring\/QueryLogger.php":"866051e7dfb4a57b048c6df1cbd9ea3d","src\/Monitoring\/MetricsCollector.php":"2997e8f21098b1642b617ac5e1f07b6a","src\/Health\/CycleHealthCheck.php":"45602bfd939d6238d37cca487731ed09","src\/Health\/HealthCheckMiddleware.php":"51a441f0ff000b04996adf3380667dc0","src\/CycleServiceProvider.php":"bd7d96497ba0ba179b702eb3313a770f","src\/Exceptions\/CycleException.php":"d5fde34e57486991f306f0d1220d5a1c","src\/Exceptions\/EntityNotFoundException.php":"2909274150e5981e377cf7a073867f97","src\/Exceptions\/CycleORMException.php":"8005db967ba33160ae79cb78cf15cd22","src\/RepositoryFactory.php":"7d501db706eccb285317dc9869b9a01f","src\/Helpers\/CycleHelpers.php":"7c3ea84a16649cb2c863ec28218e9130","src\/Helpers\/app_path.php":"1f7a2e7d65e3dfba56a970c0416d7943","src\/Helpers\/config.php":"ac722a6526ae43990372c7f965509a74","src\/Helpers\/EnvironmentHelper.php":"72177e9474eeef6430b030ba620a78b9","src\/Helpers\/env.php":"defe8ad233122c33e67b9e2e170cbf45","src\/Helpers\/cycle.php":"e735c89ef976fe2d63e46da763c43ede","src\/Middleware\/TransactionMiddleware.php":"65daefaae7cf087f0b0964818193fb07","src\/Middleware\/EntityValidationMiddleware.php":"ca63e794d725e123289ccbea2d9b22f3","src\/Middleware\/CycleMiddleware.php":"0f5811b083460241fe8586d8b18fdd63","src\/Commands\/CommandRegistry.php":"06e5e8e8d50106b1f27354622399a090","src\/Commands\/BaseCommand.php":"7465b4b8f4de0f3c52aa34788d19b6b9","src\/Commands\/CommandNotFoundException.php":"9ca1b96f3cae7179c6a45f383d553967","src\/Commands\/EntityCommand.php":"6ce9405884f196685d5643dbe7321a80","src\/Commands\/StatusCommand.php":"e58804ba6dc1e0ca84887a7717bd4a96","src\/Commands\/MigrateCommand.php":"1ca06e1f0f9f697656f6c14c22f83c65","src\/Commands\/SchemaCommand.php":"2e893f38a13c0f311760dacc45047efb","tests\/Mocks\/MockApplication.php":"df13a41372151ad45c4482fb83105309","tests\/Mocks\/MockContainer.php":"21f565b4d2885df754d5dd3853bca30a","tests\/Mocks\/SimpleTestApp.php":"1ebe203af2a2f613337832ba31c5f4c1","tests\/Entities\/User.php":"6af4fa732cc63bf0e24683fe86859ac4","tests\/Entities\/Post.php":"844e7b455ec67e478888ef4544510927","tests\/Support\/TestApplication.php":"77a0e67dc5d98e730055d19118844ceb","tests\/Database\/DatabaseOperationsTest.php":"44529f74f6a693546f1a7d24c720c93a","tests\/Unit\/CycleServiceProviderUnitTest.php":"25adc1580131dd9bd553c46c5f5697af","tests\/Unit\/MonitoringUnitTest.php":"bece2c3a0f358cd7ab8651fdaa7ad0cb","tests\/Unit\/RepositoryFactoryUnitTest.php":"f15388de479d3a9d969bbd019d7181d1","tests\/TestCase.php":"0229b46fe55385b7f357308ae20b5d7f","tests\/Feature\/RepositoryFactoryTest.php":"22160cf61252d21486fb012147359dad","tests\/Feature\/CycleRequestTest.php":"0e733c5a9c694ad959c7a2d681ef3980","tests\/Feature\/MonitoringTest.php":"7df80c5c37f232af9a3c178ccbb2e0ec","tests\/Integration\/HelixIntegrationTest.php":"53da0417cd78f01777376c6b83239eec"}} \ No newline at end of file diff --git a/CYCLE_ORM_UPDATE_STATUS.md b/CYCLE_ORM_UPDATE_STATUS.md deleted file mode 100644 index 3978d76..0000000 --- a/CYCLE_ORM_UPDATE_STATUS.md +++ /dev/null @@ -1,48 +0,0 @@ -# PivotPHP Cycle ORM Update Status - v1.0.0 - -## ✅ Updates Applied - -All files have been updated to reflect the PivotPHP branding: - -### Framework References -- Updated from "Express PHP" to "PivotPHP" -- Updated from "PivotPHP" to "PivotPHP" -- Updated namespace references to `PivotPHP\CycleORM\` - -### Documentation Structure -- Fixed typo: "techinical" → "technical" -- Updated all documentation references -- Fixed namespace examples in docs - -### Version References -- All version references updated to v1.0.0 -- Updated README and CHANGELOG - -### Package Information -- ✅ Package name: `pivotphp/cycle-orm` -- ✅ Namespace: `PivotPHP\CycleORM\` -- ✅ Framework dependency: `pivotphp/core` - -### Files Updated -- ✅ Documentation (docs/) -- ✅ Scripts (scripts/) -- ✅ Legacy files removed -- ✅ README.md -- ✅ CHANGELOG.md - -## Verification -Run the following commands to verify all updates: - -```bash -# Run tests -composer test - -# Check PSR-12 compliance -composer cs:check - -# Run static analysis -composer phpstan -``` - ---- -*Updated on: $(date)* diff --git a/PACKAGIST_MIGRATION_REPORT.md b/PACKAGIST_MIGRATION_REPORT.md deleted file mode 100644 index cbcd85e..0000000 --- a/PACKAGIST_MIGRATION_REPORT.md +++ /dev/null @@ -1,92 +0,0 @@ -# PivotPHP Cycle ORM - Packagist Migration Report - -## ✅ Migration Successful! - -### 📊 Summary - -The `pivotphp/cycle-orm` package has been successfully updated to use the published version of `pivotphp/core` from Packagist instead of a local path dependency. - -### 🔧 Changes Made - -#### composer.json Updates -```diff -- "repositories": [ -- { -- "type": "path", -- "url": "../pivotphp-core" -- } -- ], - "require": { - "php": "^8.1", -- "pivotphp/core": "@dev", -+ "pivotphp/core": "^1.0", - "cycle/orm": "^2.10", - ... - }, -- "minimum-stability": "dev", -+ "minimum-stability": "stable", -``` - -### ✅ Test Results - -``` -PHPUnit 10.5.47 -Tests: 67, Assertions: 242 -Status: ✅ ALL TESTS PASSING -``` - -### 📦 Dependencies Installed - -- **pivotphp/core**: v1.0.0 (from Packagist) -- **cycle/orm**: v2.10.1 -- **All other dependencies**: Successfully resolved - -### 🎯 Benefits - -1. **Production Ready**: No longer depends on local development paths -2. **CI/CD Compatible**: Works in any environment without local dependencies -3. **Version Stability**: Uses stable versioning constraints -4. **Packagist Integration**: Fully integrated with PHP package ecosystem - -### 📋 Files Created - -1. **composer.json.production** - Production-ready composer.json template -2. **composer.json.local** - Backup of local development configuration -3. **update_composer_for_production.sh** - Script to switch to production config -4. **update_dependencies.sh** - Script to update dependencies cleanly - -### 🔄 Switching Between Environments - -#### For Production/CI: -```bash -# Already configured - uses Packagist -composer install -``` - -#### For Local Development: -```bash -# Restore local path configuration -cp composer.json.local composer.json -composer update -``` - -### ✅ Ready for Publication - -The package is now ready to be: -1. Published to Packagist as `pivotphp/cycle-orm` -2. Used in production environments -3. Integrated into CI/CD pipelines -4. Installed by end users without issues - -### 🚀 Next Steps - -1. **Tag Release**: Create v1.0.0 tag -2. **Publish to Packagist**: Submit package -3. **Update Documentation**: Add installation instructions -4. **Announce Release**: Notify community - ---- - -**Date**: $(date) -**Package**: pivotphp/cycle-orm -**Status**: ✅ Ready for Packagist Publication diff --git a/PHPSTAN_FIXES_SUMMARY.md b/PHPSTAN_FIXES_SUMMARY.md deleted file mode 100644 index 6d7cb24..0000000 --- a/PHPSTAN_FIXES_SUMMARY.md +++ /dev/null @@ -1,39 +0,0 @@ -# PHPStan Fixes Summary - -This document summarizes the changes made to fix PHPStan errors in the pivotphp-cycle-orm project. - -## Issues Fixed - -1. **Private/Protected Property Access**: Fixed direct access to private properties of `PivotPHP\Core\Http\Request` -2. **Type Mismatch**: Resolved issues with `CycleRequest` vs `Request` type compatibility -3. **Namespace References**: Updated old namespace references to `PivotPHP\Core` - -## Files Modified - -### 1. `/src/Health/HealthCheckMiddleware.php` -- Replaced direct property access (`$req->path`, `$req->pathCallable`) with public method `$req->getPathCallable()` -- Replaced direct query property access (`$req->query`) with public method `$req->get('detailed', false)` -- Fixed code style issue (removed space before semicolon) - -### 2. `/src/Middleware/CycleMiddleware.php` -- Changed middleware to pass the original `Request` object instead of `CycleRequest` wrapper -- Added `cycleRequest` as an attribute on the original request for compatibility -- This ensures type compatibility with the middleware chain - -### 3. `/src/Middleware/TransactionMiddleware.php` -- Removed `CycleRequest` type hints, now only accepts `Request` -- Removed unused `CycleRequest` import -- Updated `getRouteInfo()` method to use public methods `$req->getMethod()` and `$req->getPathCallable()` -- Simplified middleware logic by removing CycleRequest instance checks - -### 4. `/phpstan.neon` -- Updated namespace patterns in configuration -- Updated `universalObjectCratesClasses` to `PivotPHP\Core\*` namespaces - -## Result - -All PHPStan errors have been resolved. The code now: -- Passes PHPStan analysis at Level 9 (highest level) -- Adheres to PSR-12 coding standards -- Properly uses public API methods instead of accessing private properties -- Has consistent type handling throughout the middleware chain \ No newline at end of file diff --git a/composer.json.local b/composer.json.local deleted file mode 100644 index cd0752a..0000000 --- a/composer.json.local +++ /dev/null @@ -1,86 +0,0 @@ -{ - "name": "pivotphp/cycle-orm", - "description": "Robust and well-tested Cycle ORM integration for PivotPHP microframework with type safety and comprehensive testing", - "keywords": [ - "pivotphp", - "cycle-orm", - "database", - "orm", - "microframework", - "type-safe", - "phpstan", - "repository-pattern", - "monitoring", - "middleware" - ], - "type": "library", - "license": "MIT", - "authors": [ - { - "name": "Caio Alberto Fernandes", - "homepage": "https://github.com/CAFernandes" - } - ], - "repositories": [ - { - "type": "path", - "url": "../pivotphp-core" - } - ], - "require": { - "php": "^8.1", - "pivotphp/core": "@dev", - "cycle/orm": "^2.10", - "cycle/annotated": "^4.3", - "cycle/migrations": "^4.2.5", - "cycle/schema-builder": "^2.0", - "spiral/tokenizer": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "phpstan/phpstan": "^1.0", - "squizlabs/php_codesniffer": "^3.13", - "friendsofphp/php-cs-fixer": "^3.76" - }, - "autoload": { - "psr-4": { - "Helix\\CycleORM\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Helix\\CycleORM\\Tests\\": "tests/", - "Cycle\\ORM\\Select\\": "tests/Mocks/Cycle/ORM/Select/" - } - }, - "scripts": { - "test": "phpunit", - "test:unit": "phpunit --testsuite=Unit", - "test:feature": "phpunit --testsuite=Feature", - "test:integration": "phpunit --testsuite=Integration", - "test:database": "phpunit --testsuite=Database", - "test-coverage": "phpunit --coverage-html coverage", - "phpstan": "phpstan analyse src --level=9", - "cs:check": "phpcs --standard=phpcs.xml --report=full", - "cs:check:summary": "phpcs --standard=phpcs.xml --report=summary", - "cs:check:diff": "phpcs --standard=phpcs.xml --report=diff", - "cs:fix": "phpcbf --standard=phpcs.xml", - "cs:fix:dry": "phpcbf --standard=phpcs.xml --dry-run", - "psr12:validate": [ - "@cs:check:summary", - "echo 'PSR-12 validation completed!'" - ], - "psr12:fix": [ - "@cs:fix", - "@cs:check:summary", - "echo 'PSR-12 auto-fix completed!'" - ], - "quality:psr12": [ - "@psr12:validate", - "@phpstan", - "echo 'Quality check with PSR-12 completed!'" - ] - }, - "minimum-stability": "dev", - "prefer-stable": true -} diff --git a/composer.json.production b/composer.json.production deleted file mode 100644 index b444561..0000000 --- a/composer.json.production +++ /dev/null @@ -1,80 +0,0 @@ -{ - "name": "pivotphp/cycle-orm", - "description": "Robust and well-tested Cycle ORM integration for PivotPHP microframework with type safety and comprehensive testing", - "keywords": [ - "pivotphp", - "cycle-orm", - "database", - "orm", - "microframework", - "type-safe", - "phpstan", - "repository-pattern", - "monitoring", - "middleware" - ], - "type": "library", - "license": "MIT", - "authors": [ - { - "name": "Caio Alberto Fernandes", - "homepage": "https://github.com/CAFernandes" - } - ], - "require": { - "php": "^8.1", - "pivotphp/core": "^1.0", - "cycle/orm": "^2.10", - "cycle/annotated": "^4.3", - "cycle/migrations": "^4.2.5", - "cycle/schema-builder": "^2.0", - "spiral/tokenizer": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "phpstan/phpstan": "^1.0", - "squizlabs/php_codesniffer": "^3.13", - "friendsofphp/php-cs-fixer": "^3.76" - }, - "autoload": { - "psr-4": { - "Helix\\CycleORM\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Helix\\CycleORM\\Tests\\": "tests/", - "Cycle\\ORM\\Select\\": "tests/Mocks/Cycle/ORM/Select/" - } - }, - "scripts": { - "test": "phpunit", - "test:unit": "phpunit --testsuite=Unit", - "test:feature": "phpunit --testsuite=Feature", - "test:integration": "phpunit --testsuite=Integration", - "test:database": "phpunit --testsuite=Database", - "test-coverage": "phpunit --coverage-html coverage", - "phpstan": "phpstan analyse src --level=9", - "cs:check": "phpcs --standard=phpcs.xml --report=full", - "cs:check:summary": "phpcs --standard=phpcs.xml --report=summary", - "cs:check:diff": "phpcs --standard=phpcs.xml --report=diff", - "cs:fix": "phpcbf --standard=phpcs.xml", - "cs:fix:dry": "phpcbf --standard=phpcs.xml --dry-run", - "psr12:validate": [ - "@cs:check:summary", - "echo 'PSR-12 validation completed!'" - ], - "psr12:fix": [ - "@cs:fix", - "@cs:check:summary", - "echo 'PSR-12 auto-fix completed!'" - ], - "quality:psr12": [ - "@psr12:validate", - "@phpstan", - "echo 'Quality check with PSR-12 completed!'" - ] - }, - "minimum-stability": "stable", - "prefer-stable": true -} diff --git a/composer.scripts.json b/composer.scripts.json deleted file mode 100644 index 592f095..0000000 --- a/composer.scripts.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "scripts": { - "cs:check": "phpcs --standard=phpcs.xml --report=full", - "cs:check:summary": "phpcs --standard=phpcs.xml --report=summary", - "cs:check:diff": "phpcs --standard=phpcs.xml --report=diff", - "cs:fix": "phpcbf --standard=phpcs.xml", - "cs:fix:dry": "phpcbf --standard=phpcs.xml --dry-run", - "psr12:validate": [ - "@cs:check:summary", - "echo 'PSR-12 validation completed!'" - ], - "psr12:fix": [ - "@cs:fix", - "@cs:check:summary", - "echo 'PSR-12 auto-fix completed!'" - ], - "quality:psr12": [ - "@psr12:validate", - "@phpstan", - "echo 'Quality check with PSR-12 completed!'" - ] - } -} diff --git a/docs/examples/valida-conceito-patterns.md b/docs/examples/valida-conceito-patterns.md deleted file mode 100644 index 64b4795..0000000 --- a/docs/examples/valida-conceito-patterns.md +++ /dev/null @@ -1,438 +0,0 @@ -# Padrões de Uso - Projeto valida_conceito - -Este documento descreve os padrões de implementação encontrados no projeto `valida_conceito`, que demonstra o uso prático da extensão PivotPHP Cycle ORM. - -## Visão Geral - -O projeto `valida_conceito` apresenta duas abordagens distintas para implementar uma API CRUD: - -1. **Abordagem Básica** (`index.php`): Acesso direto ao banco de dados -2. **Abordagem Clean Architecture** (`index_clean.php`): Separação completa de camadas - -## Configuração Inicial - -### 1. Configuração do Ambiente - -```php -// Definir variáveis de ambiente -$_ENV['DB_CONNECTION'] = 'sqlite'; -$_ENV['DB_DATABASE'] = __DIR__ . '/database/database.sqlite'; -$_ENV['APP_DEBUG'] = 'true'; - -// Registrar o Service Provider -$app->register(new CycleServiceProvider($app)); -``` - -### 2. Estrutura de Configuração - -O projeto utiliza dois arquivos de configuração: - -**config/database.php** - Configuração simples: -```php -return [ - 'default' => 'sqlite', - 'connections' => [ - 'sqlite' => [ - 'driver' => 'sqlite', - 'database' => __DIR__ . '/../database/database.sqlite', - ], - ], -]; -``` - -**config/cycle.php** - Configuração completa: -```php -return [ - 'default' => env('DB_CONNECTION', 'sqlite'), - 'connections' => [ - 'sqlite' => [...], - 'mysql' => [...], - ], - 'entities' => [ - 'directories' => [ - __DIR__ . '/../src/Domain/Entities', - ], - ], - 'cache' => [ - 'enabled' => true, - 'directory' => __DIR__ . '/../storage/cache/cycle', - ], -]; -``` - -## Padrão Básico - Acesso Direto - -### Características -- Usa diretamente o serviço `cycle.database` -- Queries SQL diretas -- Mapeamento manual de resultados -- Ideal para projetos simples ou prototipagem - -### Exemplo de Implementação - -```php -// Listar todos os usuários -$app->get('/api/users', function ($req, $res) use ($app) { - try { - $database = $app->make('cycle.database'); - $users = $database->database()->query('SELECT * FROM users')->fetchAll(); - - return $res->json([ - 'status' => 'success', - 'data' => $users - ]); - } catch (\Exception $e) { - return $res->json([ - 'status' => 'error', - 'message' => $e->getMessage() - ], 500); - } -}); - -// Criar usuário -$app->post('/api/users', function ($req, $res) use ($app) { - try { - $database = $app->make('cycle.database'); - $data = $req->getParsedBody(); - - // Validação básica - if (empty($data['name']) || empty($data['email'])) { - return $res->json([ - 'status' => 'error', - 'message' => 'Name and email are required' - ], 400); - } - - // Inserir usando query builder - $database->database()->insert('users')->values([ - 'name' => $data['name'], - 'email' => $data['email'], - 'created_at' => date('Y-m-d H:i:s'), - 'updated_at' => date('Y-m-d H:i:s') - ])->run(); - - $lastInsertId = $database->database()->lastInsertID(); - - return $res->json([ - 'status' => 'success', - 'data' => ['id' => $lastInsertId] - ], 201); - } catch (\Exception $e) { - return $res->json([ - 'status' => 'error', - 'message' => $e->getMessage() - ], 500); - } -}); -``` - -## Padrão Clean Architecture - -### Características -- Separação completa de camadas -- Domain-Driven Design (DDD) -- Inversão de dependência -- Testável e escalável - -### Estrutura de Diretórios - -``` -src/ -├── Domain/ -│ ├── Entities/ -│ │ └── User.php -│ ├── ValueObjects/ -│ │ ├── Email.php -│ │ └── Name.php -│ └── Repositories/ -│ └── UserRepositoryInterface.php -├── Infrastructure/ -│ ├── Container/ -│ │ └── DIContainer.php -│ └── Repositories/ -│ └── UserRepository.php -└── Application/ - ├── Controllers/ - │ └── UserController.php - ├── UseCases/ - │ ├── CreateUserUseCase.php - │ └── ListUsersUseCase.php - └── DTOs/ - ├── ApiResponse.php - └── UserDTO.php -``` - -### Implementação das Camadas - -#### 1. Entidade de Domínio - -```php -namespace App\Domain\Entities; - -class User -{ - private ?int $id; - private Name $name; - private Email $email; - private \DateTimeImmutable $createdAt; - private \DateTimeImmutable $updatedAt; - - private function __construct( - Name $name, - Email $email, - ?int $id = null, - ?\DateTimeImmutable $createdAt = null, - ?\DateTimeImmutable $updatedAt = null - ) { - $this->name = $name; - $this->email = $email; - $this->id = $id; - $this->createdAt = $createdAt ?? new \DateTimeImmutable(); - $this->updatedAt = $updatedAt ?? new \DateTimeImmutable(); - } - - public static function create(string $name, string $email): self - { - return new self( - new Name($name), - new Email($email) - ); - } -} -``` - -#### 2. Repositório - -```php -namespace App\Infrastructure\Repositories; - -use Cycle\Database\DatabaseInterface; - -class UserRepository implements UserRepositoryInterface -{ - public function __construct( - private DatabaseInterface $database - ) {} - - public function findById(int $id): ?User - { - $result = $this->database->query( - 'SELECT * FROM users WHERE id = ?', - [$id] - )->fetch(); - - return $result ? $this->mapToEntity($result) : null; - } - - public function save(User $user): void - { - $data = $this->mapToArray($user); - - if ($user->getId()) { - $this->database->update('users', $data, ['id' => $user->getId()])->run(); - } else { - $this->database->insert('users')->values($data)->run(); - } - } - - private function mapToEntity(array $data): User - { - return User::fromArray($data); - } -} -``` - -#### 3. Use Case - -```php -namespace App\Application\UseCases; - -class CreateUserUseCase -{ - public function __construct( - private UserRepositoryInterface $userRepository, - private ValidatorInterface $validator - ) {} - - public function execute(CreateUserDTO $dto): Result - { - // Validar dados - $errors = $this->validator->validate($dto); - if (!empty($errors)) { - return Result::failure($errors); - } - - // Criar entidade - $user = User::create($dto->name, $dto->email); - - // Persistir - try { - $this->userRepository->save($user); - return Result::success($user); - } catch (\Exception $e) { - return Result::failure(['error' => 'Failed to save user']); - } - } -} -``` - -#### 4. Controller - -```php -namespace App\Application\Controllers; - -class UserController -{ - public function __construct( - private CreateUserUseCase $createUserUseCase, - private ListUsersUseCase $listUsersUseCase - ) {} - - public function store(Request $request): ApiResponse - { - $dto = CreateUserDTO::fromArray($request->getParsedBody()); - $result = $this->createUserUseCase->execute($dto); - - if ($result->isSuccess()) { - return ApiResponse::success($result->getData(), 201); - } - - return ApiResponse::error($result->getErrors(), 400); - } -} -``` - -### Container de Injeção de Dependência - -```php -// Configuração do container -$container = new DIContainer(); - -// Registrar serviços do Cycle -$container->bind('cycle.database', function () use ($app) { - return $app->make('cycle.database'); -}); - -// Registrar repositórios -$container->bind(UserRepositoryInterface::class, function ($container) { - return new UserRepository($container->get('cycle.database')); -}); - -// Registrar use cases -$container->bind(CreateUserUseCase::class, function ($container) { - return new CreateUserUseCase( - $container->get(UserRepositoryInterface::class), - $container->get(ValidatorInterface::class) - ); -}); - -// Registrar controllers -$container->bind(UserController::class, function ($container) { - return new UserController( - $container->get(CreateUserUseCase::class), - $container->get(ListUsersUseCase::class) - ); -}); -``` - -## Sincronização de Schema - -O projeto utiliza comandos do Cycle para gerenciar o banco de dados: - -```bash -# Sincronizar schema -php bin/console cycle:schema:sync - -# Executar migrações -php bin/console cycle:migrate - -# Verificar status -php bin/console cycle:status -``` - -## Tratamento de Erros - -Ambos os padrões implementam tratamento consistente de erros: - -```php -// Middleware de erro global -$app->use(function ($req, $res, $next) { - try { - return $next($req, $res); - } catch (\Exception $e) { - return $res->json([ - 'status' => 'error', - 'message' => $e->getMessage(), - 'code' => $e->getCode() - ], 500); - } -}); -``` - -## Validação de Dados - -### Padrão Básico -```php -// Validação inline -if (empty($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { - return $res->json(['error' => 'Invalid email'], 400); -} -``` - -### Padrão Clean Architecture -```php -// Validação em Value Objects -class Email -{ - public function __construct(private string $value) - { - if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { - throw new InvalidArgumentException('Invalid email format'); - } - } -} -``` - -## Testes - -O projeto suporta testes em ambos os padrões: - -```php -// Teste do padrão básico -public function testCreateUser() -{ - $response = $this->client->post('/api/users', [ - 'json' => [ - 'name' => 'Test User', - 'email' => 'test@example.com' - ] - ]); - - $this->assertEquals(201, $response->getStatusCode()); -} - -// Teste do padrão Clean Architecture -public function testCreateUserUseCase() -{ - $repository = $this->createMock(UserRepositoryInterface::class); - $useCase = new CreateUserUseCase($repository); - - $result = $useCase->execute(new CreateUserDTO('Test', 'test@example.com')); - - $this->assertTrue($result->isSuccess()); -} -``` - -## Considerações de Performance - -1. **Cache de Repositórios**: Reutilizar instâncias via container -2. **Queries Otimizadas**: Usar índices apropriados -3. **Lazy Loading**: Carregar relações apenas quando necessário -4. **Connection Pooling**: Configurar pool de conexões para produção - -## Conclusão - -O projeto `valida_conceito` demonstra que a extensão PivotPHP Cycle ORM é flexível o suficiente para suportar tanto implementações simples quanto arquiteturas complexas. A escolha entre os padrões depende dos requisitos do projeto: - -- Use o **Padrão Básico** para: MVPs, prototipagem, APIs simples -- Use o **Padrão Clean Architecture** para: Aplicações empresariais, sistemas complexos, quando testabilidade é crucial diff --git a/docs/index.md b/docs/index.md index aeba56b..0f12aef 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,7 +9,6 @@ - [Implementação Básica](./implementions/usage_basic.md) - [Implementação com Middleware](./implementions/usage_with_middleware.md) - [Middleware Customizado](./implementions/usage_with_custom_middleware.md) -- [Padrões Valida Conceito](./examples/valida-conceito-patterns.md) ## 🔧 Documentação Técnica diff --git a/docs/metodos-corretos-helixphp.md b/docs/metodos-corretos-helixphp.md deleted file mode 100644 index 0aba56a..0000000 --- a/docs/metodos-corretos-helixphp.md +++ /dev/null @@ -1,77 +0,0 @@ -# Métodos Corretos do PivotPHP - -## Request - -### Propriedades Principais -- `$req->params` - Parâmetros de rota (stdClass) - - Ex: `/users/:id` -> `$req->params->id` -- `$req->query` - Parâmetros da query string (stdClass) - - Ex: `/users?name=John` -> `$req->query->name` -- `$req->body()` - Retorna o corpo da requisição como stdClass - - Ex: POST com JSON -> `$req->body()->name` - -### Métodos Auxiliares -- `$req->input($key, $default = null)` - Busca valor no body com fallback -- `$req->header($key)` - Obtém header específico -- `$req->getMethod()` - Obtém método HTTP (GET, POST, etc) -- `$req->getUri()` - Obtém URI da requisição - -### Atributos Dinâmicos (com Cycle ORM Extension) -- `$req->orm` - Instância do ORM -- `$req->em` - Entity Manager -- `$req->db` - Database -- `$req->repository` - Repository Factory - -## Response - -### Métodos Principais -- `$res->json($data, $status = 200)` - Resposta JSON -- `$res->send($content, $status = 200)` - Resposta texto -- `$res->status($code)` - Define status HTTP -- `$res->header($key, $value)` - Define header - -### Exemplos Corretos - -```php -// Rota com parâmetro -$app->get('/users/:id', function ($req, $res) { - $id = $req->params->id; - return $res->json(['id' => $id]); -}); - -// Query string -$app->get('/users', function ($req, $res) { - $name = $req->query->name ?? 'all'; - $page = (int)($req->query->page ?? 1); - return $res->json(['filter' => $name, 'page' => $page]); -}); - -// Body da requisição -$app->post('/users', function ($req, $res) { - $data = $req->body(); - $name = $data->name; - $email = $data->email; - - // Ou usando input() - $name = $req->input('name', 'Anonymous'); - - return $res->json(['created' => true], 201); -}); - -// Múltiplos parâmetros de rota -$app->get('/users/:userId/posts/:postId', function ($req, $res) { - $userId = $req->params->userId; - $postId = $req->params->postId; - return $res->json(['user' => $userId, 'post' => $postId]); -}); -``` - -## Observações Importantes - -1. **Não existe** `getParsedBody()` - use `body()` -2. **Não existe** `getQueryParams()` - use `$req->query` -3. **Não existe** `getAttribute()` - use `$req->params->paramName` -4. **Não existe** `getQueryParam()` - use `$req->query->paramName` -5. **Rotas com parâmetros** usam `:param` não `{param}` -6. **body()** retorna stdClass, não array -7. **query** é uma propriedade stdClass, não um método diff --git a/update_composer_for_production.sh b/update_composer_for_production.sh deleted file mode 100755 index eb7a0b6..0000000 --- a/update_composer_for_production.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/bash - -echo "=== Updating composer.json for Production (Packagist) ===" -echo "" - -cd /home/cfernandes/pivotphp/pivotphp-cycle-orm || exit 1 - -# Backup current composer.json -cp composer.json composer.json.local - -# Update composer.json to use Packagist version -cat > composer.json << 'EOF' -{ - "name": "pivotphp/cycle-orm", - "description": "Robust and well-tested Cycle ORM integration for PivotPHP microframework with type safety and comprehensive testing", - "keywords": [ - "pivotphp", - "cycle-orm", - "database", - "orm", - "microframework", - "type-safe", - "phpstan", - "repository-pattern", - "monitoring", - "middleware" - ], - "type": "library", - "license": "MIT", - "authors": [ - { - "name": "Caio Alberto Fernandes", - "homepage": "https://github.com/CAFernandes" - } - ], - "require": { - "php": "^8.1", - "pivotphp/core": "^1.0", - "cycle/orm": "^2.10", - "cycle/annotated": "^4.3", - "cycle/migrations": "^4.2.5", - "cycle/schema-builder": "^2.0", - "spiral/tokenizer": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "phpstan/phpstan": "^1.0", - "squizlabs/php_codesniffer": "^3.13", - "friendsofphp/php-cs-fixer": "^3.76" - }, - "autoload": { - "psr-4": { - "PivotPHP\\CycleORM\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "PivotPHP\\CycleORM\\Tests\\": "tests/", - "Cycle\\ORM\\Select\\": "tests/Mocks/Cycle/ORM/Select/" - } - }, - "scripts": { - "test": "phpunit", - "test:unit": "phpunit --testsuite=Unit", - "test:feature": "phpunit --testsuite=Feature", - "test:integration": "phpunit --testsuite=Integration", - "test:database": "phpunit --testsuite=Database", - "test-coverage": "phpunit --coverage-html coverage", - "phpstan": "phpstan analyse src --level=9", - "cs:check": "phpcs --standard=phpcs.xml --report=full", - "cs:check:summary": "phpcs --standard=phpcs.xml --report=summary", - "cs:check:diff": "phpcs --standard=phpcs.xml --report=diff", - "cs:fix": "phpcbf --standard=phpcs.xml", - "cs:fix:dry": "phpcbf --standard=phpcs.xml --dry-run", - "psr12:validate": [ - "@cs:check:summary", - "echo 'PSR-12 validation completed!'" - ], - "psr12:fix": [ - "@cs:fix", - "@cs:check:summary", - "echo 'PSR-12 auto-fix completed!'" - ], - "quality:psr12": [ - "@psr12:validate", - "@phpstan", - "echo 'Quality check with PSR-12 completed!'" - ] - }, - "minimum-stability": "stable", - "prefer-stable": true -} -EOF - -echo "✅ composer.json updated to use Packagist dependencies" -echo "" -echo "📊 Changes made:" -echo " • Removed local path repository" -echo " • Changed pivotphp/core from @dev to ^1.0" -echo " • Changed minimum-stability from dev to stable" -echo " • Backup saved as composer.json.local" -echo "" -echo "🔄 Next steps:" -echo " 1. Remove composer.lock: rm -f composer.lock" -echo " 2. Update dependencies: composer update" -echo " 3. Run tests: composer test" -echo "" -echo "💡 To restore local development setup:" -echo " cp composer.json.local composer.json" diff --git a/update_dependencies.sh b/update_dependencies.sh deleted file mode 100755 index b66d079..0000000 --- a/update_dependencies.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -echo "=== Updating PivotPHP Cycle ORM Dependencies ===" -echo "" - -# Change to the script's directory -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$SCRIPT_DIR" - -echo "Working directory: $(pwd)" -echo "" - -# Check if composer.json exists -if [ ! -f "composer.json" ]; then - echo "❌ Error: composer.json not found!" - exit 1 -fi - -echo "📋 Current composer.json requires:" -grep -A1 '"pivotphp/core"' composer.json -echo "" - -# Remove composer.lock if it exists -if [ -f "composer.lock" ]; then - echo "🗑️ Removing composer.lock..." - rm -f composer.lock -fi - -# Update dependencies -echo "📦 Updating dependencies from Packagist..." -/usr/local/bin/composer update --no-interaction - -if [ $? -eq 0 ]; then - echo "" - echo "✅ Dependencies updated successfully!" - echo "" - echo "🎯 Next steps:" - echo " 1. Run tests: composer test" - echo " 2. Check PSR-12: composer cs:check" - echo " 3. Run PHPStan: composer phpstan" -else - echo "" - echo "❌ Error updating dependencies!" - echo "" - echo "💡 Troubleshooting:" - echo " • Check if pivotphp/core is published on Packagist" - echo " • Verify network connectivity" - echo " • Try: composer update -vvv for verbose output" -fi From f8eb4afb13835fb5f60c8f48e2d4d5fa10ea7207 Mon Sep 17 00:00:00 2001 From: Caio Fernandes Date: Wed, 9 Jul 2025 11:25:52 -0300 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20Atualiza=20.gitignore=20para=20incl?= =?UTF-8?q?uir=20diret=C3=B3rio=20de=20cobertura=20e=20ajusta=20composer.j?= =?UTF-8?q?son=20para=20vers=C3=A3o=20espec=C3=ADfica=20do=20pivotphp/core?= =?UTF-8?q?;=20modifica=20phpunit.xml=20para=20desativar=20falhas=20em=20d?= =?UTF-8?q?eprecia=C3=A7=C3=B5es=20e=20altera=20MetricsCollector=20para=20?= =?UTF-8?q?logar=20falhas=20de=20consulta=20apenas=20fora=20do=20ambiente?= =?UTF-8?q?=20de=20teste?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + composer.json | 10 ++-------- phpunit.xml | 11 +++++------ src/Monitoring/MetricsCollector.php | 12 +++++++++++- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index b6ce056..61893da 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ # Testing .phpunit.cache/ +coverage/ coverage-html/ coverage.xml junit.xml diff --git a/composer.json b/composer.json index 932305d..44bebe2 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,6 @@ { "name": "pivotphp/cycle-orm", "description": "Robust and well-tested Cycle ORM integration for PivotPHP microframework with type safety and comprehensive testing", - "repositories": [ - { - "type": "path", - "url": "../pivotphp-core" - } - ], "keywords": [ "pivotphp", "cycle-orm", @@ -29,7 +23,7 @@ ], "require": { "php": "^8.1", - "pivotphp/core": "*@dev", + "pivotphp/core": "^1.1.0", "cycle/orm": "^2.10", "cycle/annotated": "^4.3", "cycle/migrations": "^4.2.5", @@ -59,7 +53,7 @@ "test:feature": "phpunit --testsuite=Feature", "test:integration": "phpunit --testsuite=Integration", "test:database": "phpunit --testsuite=Database", - "test-coverage": "phpunit --coverage-html coverage", + "test-coverage": "XDEBUG_MODE=coverage phpunit --coverage-html coverage --coverage-clover coverage.xml", "phpstan": "phpstan analyse src --level=9", "cs:check": "phpcs --standard=phpcs.xml --report=full", "cs:check:summary": "phpcs --standard=phpcs.xml --report=summary", diff --git a/phpunit.xml b/phpunit.xml index 8359466..dabaa3d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -4,6 +4,7 @@ colors="true" failOnWarning="false" failOnRisky="false" + failOnDeprecation="false" stopOnFailure="false" cacheDirectory=".phpunit.cache" executionOrder="depends,defects" @@ -29,19 +30,17 @@ - + + src/ - - - - - + + diff --git a/src/Monitoring/MetricsCollector.php b/src/Monitoring/MetricsCollector.php index abc2a30..bfa8e49 100644 --- a/src/Monitoring/MetricsCollector.php +++ b/src/Monitoring/MetricsCollector.php @@ -76,7 +76,17 @@ public static function recordQueryTime(string $query, float $timeMs): void public static function recordQueryFailure(string $query): void { self::$metrics['queries_failed']++; - error_log('Cycle ORM Query Failed: Query: ' . substr($query, 0, 100)); + + // Only log to error_log if not in testing environment + $isTestingEnv = ( + (isset($_ENV['APP_ENV']) && $_ENV['APP_ENV'] === 'testing') || + (isset($_SERVER['APP_ENV']) && $_SERVER['APP_ENV'] === 'testing') || + defined('PHPUNIT_RUNNING') + ); + + if (!$isTestingEnv) { + error_log('Cycle ORM Query Failed: Query: ' . substr($query, 0, 100)); + } } /** From 3bb6e2e14f963127608ac38449c88fc2eba6fdc9 Mon Sep 17 00:00:00 2001 From: Caio Fernandes Date: Wed, 9 Jul 2025 11:27:47 -0300 Subject: [PATCH 3/6] fix: Remove unnecessary whitespace in recordQueryFailure method and improve logging condition --- src/Monitoring/MetricsCollector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Monitoring/MetricsCollector.php b/src/Monitoring/MetricsCollector.php index bfa8e49..2bed04f 100644 --- a/src/Monitoring/MetricsCollector.php +++ b/src/Monitoring/MetricsCollector.php @@ -76,14 +76,14 @@ public static function recordQueryTime(string $query, float $timeMs): void public static function recordQueryFailure(string $query): void { self::$metrics['queries_failed']++; - + // Only log to error_log if not in testing environment $isTestingEnv = ( (isset($_ENV['APP_ENV']) && $_ENV['APP_ENV'] === 'testing') || (isset($_SERVER['APP_ENV']) && $_SERVER['APP_ENV'] === 'testing') || defined('PHPUNIT_RUNNING') ); - + if (!$isTestingEnv) { error_log('Cycle ORM Query Failed: Query: ' . substr($query, 0, 100)); } From 23515df0782fc1ea6797fe65e1d59d6a62dfad17 Mon Sep 17 00:00:00 2001 From: Caio Fernandes Date: Wed, 9 Jul 2025 11:30:40 -0300 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20Melhora=20a=20verifica=C3=A7=C3=A3o?= =?UTF-8?q?=20do=20ambiente=20de=20testes=20na=20classe=20MetricsCollector?= =?UTF-8?q?=20e=20atualiza=20a=20l=C3=B3gica=20de=20registro=20de=20falhas?= =?UTF-8?q?=20de=20consulta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Helpers/EnvironmentHelper.php | 23 ++++++++++++++++++++++- src/Monitoring/MetricsCollector.php | 10 +++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Helpers/EnvironmentHelper.php b/src/Helpers/EnvironmentHelper.php index 6580435..b557c92 100644 --- a/src/Helpers/EnvironmentHelper.php +++ b/src/Helpers/EnvironmentHelper.php @@ -22,10 +22,31 @@ public static function isDevelopment(): bool /** * Verifica se o ambiente é de testes. + * Considera múltiplas fontes: APP_ENV, PHPUnit e variáveis de servidor. */ public static function isTesting(): bool { - return in_array(env('APP_ENV', ''), ['testing', 'test'], true); + // Check APP_ENV from multiple sources + $envSources = [ + $_ENV['APP_ENV'] ?? '', + $_SERVER['APP_ENV'] ?? '', + ]; + + // Add env() function result if available + if (function_exists('env')) { + $envSources[] = env('APP_ENV', ''); + } + + foreach ($envSources as $envValue) { + if (in_array($envValue, ['testing', 'test'], true)) { + return true; + } + } + + // Check if running under PHPUnit + return defined('PHPUNIT_RUNNING') || + (isset($_ENV['PHPUNIT_RUNNING']) && $_ENV['PHPUNIT_RUNNING']) || + (isset($_SERVER['PHPUNIT_RUNNING']) && $_SERVER['PHPUNIT_RUNNING']); } /** diff --git a/src/Monitoring/MetricsCollector.php b/src/Monitoring/MetricsCollector.php index 2bed04f..8f42594 100644 --- a/src/Monitoring/MetricsCollector.php +++ b/src/Monitoring/MetricsCollector.php @@ -2,6 +2,8 @@ namespace PivotPHP\CycleORM\Monitoring; +use PivotPHP\CycleORM\Helpers\EnvironmentHelper; + /** * Coletor de métricas para Cycle ORM. */ @@ -78,13 +80,7 @@ public static function recordQueryFailure(string $query): void self::$metrics['queries_failed']++; // Only log to error_log if not in testing environment - $isTestingEnv = ( - (isset($_ENV['APP_ENV']) && $_ENV['APP_ENV'] === 'testing') || - (isset($_SERVER['APP_ENV']) && $_SERVER['APP_ENV'] === 'testing') || - defined('PHPUNIT_RUNNING') - ); - - if (!$isTestingEnv) { + if (!EnvironmentHelper::isTesting()) { error_log('Cycle ORM Query Failed: Query: ' . substr($query, 0, 100)); } } From 72e4fb0f71f149cb9e59e54e6bd630d049256fd9 Mon Sep 17 00:00:00 2001 From: Caio Fernandes Date: Wed, 9 Jul 2025 11:38:30 -0300 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20Adiciona=20suporte=20a=20scripts=20?= =?UTF-8?q?de=20cobertura=20de=20testes=20multiplataforma=20e=20melhora=20?= =?UTF-8?q?o=20cache=20nas=20verifica=C3=A7=C3=B5es=20de=20ambiente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 ++++++- composer.json | 2 +- scripts/benchmark-environment-helper.php | 38 ++++++++++++++++ scripts/test-coverage.bat | 5 +++ scripts/test-coverage.php | 28 ++++++++++++ scripts/test-coverage.ps1 | 4 ++ scripts/test-coverage.sh | 5 +++ src/Helpers/EnvironmentHelper.php | 57 ++++++++++++++++++++---- 8 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 scripts/benchmark-environment-helper.php create mode 100644 scripts/test-coverage.bat create mode 100644 scripts/test-coverage.php create mode 100644 scripts/test-coverage.ps1 create mode 100755 scripts/test-coverage.sh diff --git a/README.md b/README.md index cd48c31..38a7b99 100644 --- a/README.md +++ b/README.md @@ -266,10 +266,25 @@ composer test:unit composer test:feature composer test:integration -# Run with coverage +# Run with coverage (cross-platform) composer test-coverage + +# Platform-specific alternatives: +# Unix/Linux/macOS +./scripts/test-coverage.sh +# Windows CMD +scripts\test-coverage.bat +# PowerShell +scripts\test-coverage.ps1 ``` +### Cross-Platform Compatibility + +The project includes cross-platform scripts for coverage testing: +- **Primary method**: `composer test-coverage` (works on all platforms) +- **Alternative scripts**: Platform-specific scripts in `scripts/` directory +- **Windows support**: Both CMD and PowerShell scripts included + ## 📚 Documentation - [Integration Guide](docs/integration-guide.md) diff --git a/composer.json b/composer.json index 44bebe2..3bb00a5 100644 --- a/composer.json +++ b/composer.json @@ -53,7 +53,7 @@ "test:feature": "phpunit --testsuite=Feature", "test:integration": "phpunit --testsuite=Integration", "test:database": "phpunit --testsuite=Database", - "test-coverage": "XDEBUG_MODE=coverage phpunit --coverage-html coverage --coverage-clover coverage.xml", + "test-coverage": "php scripts/test-coverage.php", "phpstan": "phpstan analyse src --level=9", "cs:check": "phpcs --standard=phpcs.xml --report=full", "cs:check:summary": "phpcs --standard=phpcs.xml --report=summary", diff --git a/scripts/benchmark-environment-helper.php b/scripts/benchmark-environment-helper.php new file mode 100644 index 0000000..77cef50 --- /dev/null +++ b/scripts/benchmark-environment-helper.php @@ -0,0 +1,38 @@ + Date: Wed, 9 Jul 2025 11:45:44 -0300 Subject: [PATCH 6/6] feat: Adiciona script de teste para funcionalidade de limpeza de cache do EnvironmentHelper e melhora o gerenciamento de cache --- scripts/test-cache-clearing.php | 50 +++++++++++++++++++++++++++++ src/Helpers/EnvironmentHelper.php | 53 ++++++++++++++++--------------- 2 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 scripts/test-cache-clearing.php diff --git a/scripts/test-cache-clearing.php b/scripts/test-cache-clearing.php new file mode 100644 index 0000000..34e99dc --- /dev/null +++ b/scripts/test-cache-clearing.php @@ -0,0 +1,50 @@ + + */ + private static array $cache = []; /** * Verifica se o ambiente é produção. * Resultado é cached para melhor performance. */ public static function isProduction(): bool { - static $cachedResult = null; - if ($cachedResult !== null) { - return $cachedResult; + if (isset(self::$cache['isProduction'])) { + return (bool) self::$cache['isProduction']; } $env = function_exists('env') ? env('APP_ENV', 'production') : ($_ENV['APP_ENV'] ?? 'production'); - $cachedResult = in_array($env, ['production', 'prod'], true); - return $cachedResult; + self::$cache['isProduction'] = in_array($env, ['production', 'prod'], true); + return (bool) self::$cache['isProduction']; } /** @@ -26,14 +31,13 @@ public static function isProduction(): bool */ public static function isDevelopment(): bool { - static $cachedResult = null; - if ($cachedResult !== null) { - return $cachedResult; + if (isset(self::$cache['isDevelopment'])) { + return (bool) self::$cache['isDevelopment']; } $env = function_exists('env') ? env('APP_ENV', 'development') : ($_ENV['APP_ENV'] ?? 'development'); - $cachedResult = in_array($env, ['development', 'dev', 'local'], true); - return $cachedResult; + self::$cache['isDevelopment'] = in_array($env, ['development', 'dev', 'local'], true); + return (bool) self::$cache['isDevelopment']; } /** @@ -43,9 +47,8 @@ public static function isDevelopment(): bool */ public static function isTesting(): bool { - static $cachedResult = null; - if ($cachedResult !== null) { - return $cachedResult; + if (isset(self::$cache['isTesting'])) { + return (bool) self::$cache['isTesting']; } // Check APP_ENV from multiple sources @@ -61,17 +64,17 @@ public static function isTesting(): bool foreach ($envSources as $envValue) { if (in_array($envValue, ['testing', 'test'], true)) { - $cachedResult = true; - return $cachedResult; + self::$cache['isTesting'] = true; + return (bool) self::$cache['isTesting']; } } // Check if running under PHPUnit - $cachedResult = defined('PHPUNIT_RUNNING') || - (isset($_ENV['PHPUNIT_RUNNING']) && $_ENV['PHPUNIT_RUNNING']) || - (isset($_SERVER['PHPUNIT_RUNNING']) && $_SERVER['PHPUNIT_RUNNING']); + self::$cache['isTesting'] = defined('PHPUNIT_RUNNING') || + (isset($_ENV['PHPUNIT_RUNNING']) && $_ENV['PHPUNIT_RUNNING']) || + (isset($_SERVER['PHPUNIT_RUNNING']) && $_SERVER['PHPUNIT_RUNNING']); - return $cachedResult; + return (bool) self::$cache['isTesting']; } /** @@ -80,14 +83,13 @@ public static function isTesting(): bool */ public static function getEnvironment(): string { - static $cachedResult = null; - if ($cachedResult !== null) { - return $cachedResult; + if (isset(self::$cache['getEnvironment'])) { + return (string) self::$cache['getEnvironment']; } $env = function_exists('env') ? env('APP_ENV', 'production') : ($_ENV['APP_ENV'] ?? 'production'); - $cachedResult = is_string($env) ? $env : 'production'; - return $cachedResult; + self::$cache['getEnvironment'] = is_string($env) ? $env : 'production'; + return (string) self::$cache['getEnvironment']; } /** @@ -96,7 +98,6 @@ public static function getEnvironment(): string */ public static function clearCache(): void { - // Reset all static caches by calling each method with a flag - // This is a simple approach - in production the cache should rarely need clearing + self::$cache = []; } }