diff --git a/.build/php-cs-fixer/.php-cs-fixer.cache b/.build/php-cs-fixer/.php-cs-fixer.cache new file mode 100644 index 0000000..29b1b89 --- /dev/null +++ b/.build/php-cs-fixer/.php-cs-fixer.cache @@ -0,0 +1 @@ +{"php":"8.4.13","version":"3.88.2:v3.88.2#a8d15584bafb0f0d9d938827840060fd4a3ebc99","indent":" ","lineEnding":"\n","rules":{"ErickSkrauch\/line_break_after_statements":true,"PhpCsFixerCustomFixers\/multiline_comment_opening_closing_alone":true,"PhpCsFixerCustomFixers\/no_duplicated_array_key":{"ignore_expressions":true},"PhpCsFixerCustomFixers\/no_duplicated_imports":true,"PhpCsFixerCustomFixers\/php_unit_requires_constraint":true,"PhpCsFixerCustomFixers\/phpdoc_types_comma_spaces":true,"align_multiline_comment":{"comment_type":"all_multiline"},"array_indentation":true,"array_push":true,"array_syntax":{"syntax":"short"},"assign_null_coalescing_to_coalesce_equal":true,"backtick_to_shell_exec":true,"binary_operator_spaces":{"default":"single_space","operators":[]},"blank_line_after_namespace":true,"blank_line_after_opening_tag":true,"blank_line_before_statement":{"statements":["break","continue","declare","default","do","exit","for","foreach","goto","if","include","include_once","require","require_once","return","switch","throw","try","while"]},"blank_lines_before_namespace":{"max_line_breaks":2,"min_line_breaks":2},"braces_position":{"allow_single_line_anonymous_functions":false,"allow_single_line_empty_anonymous_classes":false,"anonymous_classes_opening_brace":"same_line","anonymous_functions_opening_brace":"same_line","classes_opening_brace":"next_line_unless_newline_at_signature_end","control_structures_opening_brace":"same_line","functions_opening_brace":"next_line_unless_newline_at_signature_end"},"cast_spaces":{"space":"single"},"class_attributes_separation":{"elements":{"const":"only_if_meta","property":"only_if_meta","trait_import":"none","case":"none"}},"class_definition":{"inline_constructor_arguments":true,"multi_line_extends_each_single_line":false,"single_item_single_line":false,"single_line":false,"space_before_parenthesis":false},"class_reference_name_casing":true,"clean_namespace":true,"combine_consecutive_issets":true,"combine_consecutive_unsets":true,"combine_nested_dirname":true,"comment_to_phpdoc":{"ignored_tags":[]},"compact_nullable_type_declaration":true,"concat_space":{"spacing":"none"},"constant_case":{"case":"lower"},"control_structure_braces":true,"control_structure_continuation_position":{"position":"same_line"},"date_time_create_from_format_call":true,"declare_equal_normalize":{"space":"none"},"declare_parentheses":true,"declare_strict_types":true,"dir_constant":true,"doctrine_annotation_array_assignment":{"ignored_tags":["abstract","access","after","afterClass","api","author","backupGlobals","backupStaticAttributes","before","beforeClass","category","code","codeCoverageIgnore","codeCoverageIgnoreEnd","codeCoverageIgnoreStart","copyright","covers","coversDefaultClass","coversNothing","dataProvider","depends","deprec","deprecated","encode","enduml","example","exception","expectedException","expectedExceptionCode","expectedExceptionMessage","expectedExceptionMessageRegExp","filesource","final","fix","FIXME","fixme","global","group","ignore","ingroup","inheritdoc","inheritDoc","internal","large","license","link","magic","medium","method","name","noinspection","override","package","package_version","param","preserveGlobalState","private","property","property-read","property-write","requires","return","runInSeparateProcess","runTestsInSeparateProcesses","see","since","small","source","startuml","static","staticvar","staticVar","subpackage","SuppressWarnings","template","test","testdox","throw","throws","ticket","toc","todo","TODO","tutorial","usedBy","uses","uses","var","version"],"operator":":"},"doctrine_annotation_braces":{"ignored_tags":["abstract","access","after","afterClass","api","author","backupGlobals","backupStaticAttributes","before","beforeClass","category","code","codeCoverageIgnore","codeCoverageIgnoreEnd","codeCoverageIgnoreStart","copyright","covers","coversDefaultClass","coversNothing","dataProvider","depends","deprec","deprecated","encode","enduml","example","exception","expectedException","expectedExceptionCode","expectedExceptionMessage","expectedExceptionMessageRegExp","filesource","final","fix","FIXME","fixme","global","group","ignore","ingroup","inheritdoc","inheritDoc","internal","large","license","link","magic","medium","method","name","noinspection","override","package","package_version","param","preserveGlobalState","private","property","property-read","property-write","requires","return","runInSeparateProcess","runTestsInSeparateProcesses","see","since","small","source","startuml","static","staticvar","staticVar","subpackage","SuppressWarnings","template","test","testdox","throw","throws","ticket","toc","todo","TODO","tutorial","usedBy","uses","uses","var","version"],"syntax":"without_braces"},"doctrine_annotation_indentation":{"ignored_tags":["abstract","access","after","afterClass","api","author","backupGlobals","backupStaticAttributes","before","beforeClass","category","code","codeCoverageIgnore","codeCoverageIgnoreEnd","codeCoverageIgnoreStart","copyright","covers","coversDefaultClass","coversNothing","dataProvider","depends","deprec","deprecated","encode","enduml","example","exception","expectedException","expectedExceptionCode","expectedExceptionMessage","expectedExceptionMessageRegExp","filesource","final","fix","FIXME","fixme","global","group","ignore","ingroup","inheritdoc","inheritDoc","internal","large","license","link","magic","medium","method","name","noinspection","override","package","package_version","param","preserveGlobalState","private","property","property-read","property-write","requires","return","runInSeparateProcess","runTestsInSeparateProcesses","see","since","small","source","startuml","static","staticvar","staticVar","subpackage","SuppressWarnings","template","test","testdox","throw","throws","ticket","toc","todo","TODO","tutorial","usedBy","uses","uses","var","version"],"indent_mixed_lines":false},"doctrine_annotation_spaces":{"after_argument_assignments":false,"after_array_assignments_colon":true,"after_array_assignments_equals":false,"around_commas":true,"around_parentheses":true,"before_argument_assignments":false,"before_array_assignments_colon":false,"before_array_assignments_equals":false,"ignored_tags":["abstract","access","after","afterClass","api","author","backupGlobals","backupStaticAttributes","before","beforeClass","category","code","codeCoverageIgnore","codeCoverageIgnoreEnd","codeCoverageIgnoreStart","copyright","covers","coversDefaultClass","coversNothing","dataProvider","depends","deprec","deprecated","encode","enduml","example","exception","expectedException","expectedExceptionCode","expectedExceptionMessage","expectedExceptionMessageRegExp","filesource","final","fix","FIXME","fixme","global","group","ignore","ingroup","inheritdoc","inheritDoc","internal","large","license","link","magic","medium","method","name","noinspection","override","package","package_version","param","preserveGlobalState","private","property","property-read","property-write","requires","return","runInSeparateProcess","runTestsInSeparateProcesses","see","since","small","source","startuml","static","staticvar","staticVar","subpackage","SuppressWarnings","template","test","testdox","throw","throws","ticket","toc","todo","TODO","tutorial","usedBy","uses","uses","var","version"]},"echo_tag_syntax":{"format":"long","long_function":"echo","shorten_simple_statements_only":true},"elseif":true,"empty_loop_body":{"style":"braces"},"empty_loop_condition":{"style":"while"},"encoding":true,"ereg_to_preg":true,"explicit_indirect_variable":true,"explicit_string_variable":true,"final_internal_class":{"consider_absent_docblock_as_internal_class":false,"exclude":["@Entity","@final","@Mapping\\Entity","@ORM\\Entity","@ORM\\Mapping\\Entity"],"include":["@internal"]},"fopen_flag_order":true,"fopen_flags":{"b_mode":true},"full_opening_tag":true,"function_declaration":{"closure_fn_spacing":"one","closure_function_spacing":"one","trailing_comma_single_line":false},"function_to_constant":{"functions":["get_called_class","get_class","php_sapi_name","phpversion","pi"]},"general_phpdoc_tag_rename":{"case_sensitive":false,"fix_annotation":true,"fix_inline":true,"replacements":{"inheritdoc":"inheritdoc","inheritdocs":"inheritdoc"}},"get_class_to_class_keyword":true,"global_namespace_import":{"import_classes":false,"import_constants":false,"import_functions":false},"header_comment":{"comment_type":"PHPDoc","header":"This file is part of the EaseCore package.\n\n(c) V\u00edt\u011bzslav Dvo\u0159\u00e1k \n\nFor the full copyright and license information, please view the LICENSE\nfile that was distributed with this source code.","location":"after_declare_strict","separate":"both"},"heredoc_to_nowdoc":true,"implode_call":true,"include":true,"increment_style":{"style":"pre"},"indentation_type":true,"integer_literal_case":true,"is_null":true,"lambda_not_used_import":true,"line_ending":true,"linebreak_after_opening_tag":true,"list_syntax":{"syntax":"short"},"logical_operators":true,"long_to_shorthand_operator":true,"lowercase_cast":true,"lowercase_keywords":true,"lowercase_static_reference":true,"magic_constant_casing":true,"magic_method_casing":true,"method_argument_space":{"after_heredoc":false,"attribute_placement":"standalone","keep_multiple_spaces_after_comma":false,"on_multiline":"ensure_fully_multiline"},"method_chaining_indentation":true,"modernize_strpos":{"modernize_stripos":true},"modernize_types_casting":true,"modifier_keywords":{"elements":["const","method","property"]},"multiline_comment_opening_closing":true,"multiline_promoted_properties":{"keep_blank_lines":false,"minimum_number_of_parameters":2},"multiline_string_to_heredoc":true,"multiline_whitespace_before_semicolons":{"strategy":"no_multi_line"},"native_constant_invocation":{"exclude":["false","null","true"],"fix_built_in":true,"include":[],"scope":"all","strict":false},"native_function_casing":true,"native_function_invocation":{"exclude":["sprintf"],"include":["@compiler_optimized"],"scope":"all","strict":false},"native_type_declaration_casing":true,"new_with_parentheses":{"anonymous_class":true,"named_class":true},"no_alias_functions":{"sets":["@all"]},"no_alias_language_construct_call":true,"no_alternative_syntax":{"fix_non_monolithic_code":true},"no_binary_string":true,"no_blank_lines_after_class_opening":true,"no_blank_lines_after_phpdoc":true,"no_break_comment":{"comment_text":"no break"},"no_closing_tag":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_blank_lines":{"tokens":["attribute","break","case","comma","continue","curly_brace_block","default","extra","parenthesis_brace_block","return","square_brace_block","switch","throw","use"]},"no_homoglyph_names":true,"no_leading_import_slash":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":{"use":"echo"},"no_multiline_whitespace_around_double_arrow":true,"no_multiple_statements_per_line":true,"no_null_property_initialization":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_spaces_around_offset":{"positions":["inside","outside"]},"no_superfluous_elseif":true,"no_superfluous_phpdoc_tags":{"allow_hidden_params":false,"allow_mixed":true,"allow_unused_params":false,"remove_inheritdoc":false},"no_trailing_comma_in_singleline":{"elements":["arguments","array","array_destructuring","group_import"]},"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"no_trailing_whitespace_in_string":true,"no_unneeded_braces":{"namespaces":true},"no_unneeded_control_parentheses":{"statements":["break","clone","continue","echo_print","negative_instanceof","others","return","switch_case","yield","yield_from"]},"no_unneeded_final_method":{"private_methods":true},"no_unneeded_import_alias":true,"no_unreachable_default_argument_value":true,"no_unset_cast":true,"no_unset_on_property":true,"no_unused_imports":true,"no_useless_concat_operator":{"juggle_simple_strings":true},"no_useless_else":true,"no_useless_nullsafe_operator":true,"no_useless_printf":true,"no_useless_return":true,"no_useless_sprintf":true,"no_whitespace_before_comma_in_array":{"after_heredoc":false},"no_whitespace_in_blank_line":true,"non_printable_character":{"use_escape_sequences_in_strings":false},"normalize_index_brace":true,"nullable_type_declaration":{"syntax":"question_mark"},"nullable_type_declaration_for_default_null_value":true,"object_operator_without_whitespace":true,"octal_notation":true,"operator_linebreak":{"only_booleans":true,"position":"beginning"},"ordered_attributes":{"order":[],"sort_algorithm":"alpha"},"ordered_class_elements":{"case_sensitive":false,"order":["use_trait","case","constant_public","constant_protected","constant_private","property_public","property_protected","property_private","construct","destruct","magic","phpunit","method_public","method_protected","method_private"],"sort_algorithm":"none"},"ordered_imports":{"case_sensitive":false,"imports_order":["class","const","function"],"sort_algorithm":"alpha"},"ordered_interfaces":{"case_sensitive":false,"direction":"ascend","order":"alpha"},"ordered_types":{"case_sensitive":false,"null_adjustment":"always_first","sort_algorithm":"alpha"},"php_unit_construct":{"assertions":["assertEquals","assertNotEquals","assertNotSame","assertSame"]},"php_unit_data_provider_method_order":{"placement":"after"},"php_unit_data_provider_return_type":true,"php_unit_data_provider_static":{"force":false},"php_unit_dedicate_assert":{"target":"newest"},"php_unit_dedicate_assert_internal_type":{"target":"newest"},"php_unit_expectation":{"target":"newest"},"php_unit_fqcn_annotation":true,"php_unit_method_casing":{"case":"camel_case"},"php_unit_mock":{"target":"newest"},"php_unit_mock_short_will_return":true,"php_unit_namespaced":{"target":"newest"},"php_unit_no_expectation_annotation":{"target":"newest","use_class_const":true},"php_unit_set_up_tear_down_visibility":true,"php_unit_test_annotation":{"style":"prefix"},"phpdoc_add_missing_param_annotation":{"only_untyped":true},"phpdoc_align":{"align":"vertical","spacing":1,"tags":["method","param","property","property-read","property-write","return","throws","type","var"]},"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag_normalizer":{"tags":["example","id","inheritdoc","inheritdocs","internal","link","source","toc","tutorial"]},"phpdoc_line_span":{"const":"multi","method":"multi","property":"multi"},"phpdoc_no_access":true,"phpdoc_no_alias_tag":{"replacements":{"link":"see","property-read":"property","property-write":"property","type":"var"}},"phpdoc_no_empty_return":true,"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_order":{"order":["deprecated","internal","covers","uses","dataProvider","param","throws","return"]},"phpdoc_order_by_value":{"annotations":["author","covers","coversNothing","dataProvider","depends","group","internal","method","mixin","property","property-read","property-write","requires","throws","uses"]},"phpdoc_param_order":true,"phpdoc_return_self_reference":{"replacements":{"$self":"self","$static":"static","@self":"self","@static":"static","@this":"$this","this":"$this"}},"phpdoc_scalar":{"types":["boolean","callback","double","integer","real","str"]},"phpdoc_separation":{"groups":[["deprecated"],["link","see","since"],["author","copyright","license"],["category","package","subpackage"],["property","property-read","property-write"]],"skip_unlisted_annotations":false},"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_tag_casing":{"tags":["inheritDoc"]},"phpdoc_tag_type":{"tags":{"inheritdoc":"inline"}},"phpdoc_to_property_type":{"scalar_types":true,"types_map":[],"union_types":true},"phpdoc_trim":true,"phpdoc_trim_consecutive_blank_line_separation":true,"phpdoc_types":{"groups":["alias","meta","simple"]},"phpdoc_types_order":{"case_sensitive":false,"null_adjustment":"always_first","sort_algorithm":"alpha"},"phpdoc_var_annotation_correct_order":true,"phpdoc_var_without_name":true,"pow_to_exponentiation":true,"protected_to_private":true,"psr_autoloading":{"dir":null},"random_api_migration":{"replacements":{"getrandmax":"mt_getrandmax","rand":"mt_rand","srand":"mt_srand"}},"regular_callable_call":true,"return_assignment":true,"return_type_declaration":{"space_before":"none"},"self_accessor":true,"self_static_accessor":true,"semicolon_after_instruction":true,"set_type_to_cast":true,"short_scalar_cast":true,"simple_to_complex_string_variable":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["const","property"]},"single_import_per_statement":{"group_to_single_imports":true},"single_line_after_imports":true,"single_line_comment_spacing":true,"single_line_comment_style":{"comment_types":["hash"]},"single_quote":{"strings_containing_single_quote_chars":false},"single_space_around_construct":{"constructs_contain_a_single_space":["yield_from"],"constructs_followed_by_a_single_space":["abstract","as","attribute","break","case","catch","class","clone","comment","const","const_import","continue","do","echo","else","elseif","enum","extends","final","finally","for","foreach","function","function_import","global","goto","if","implements","include","include_once","instanceof","insteadof","interface","match","named_argument","namespace","new","open_tag_with_echo","php_doc","php_open","print","private","protected","public","readonly","require","require_once","return","static","switch","throw","trait","try","type_colon","use","use_lambda","use_trait","var","while","yield","yield_from"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"space_after_semicolon":{"remove_in_empty_for_expressions":false},"spaces_inside_parentheses":{"space":"none"},"standardize_increment":true,"standardize_not_equals":true,"statement_indentation":{"stick_comment_to_next_continuous_control_statement":false},"static_lambda":true,"static_private_method":true,"strict_comparison":true,"strict_param":true,"string_implicit_backslashes":{"double_quoted":"escape","heredoc":"escape","single_quoted":"ignore"},"string_length_to_empty":true,"string_line_ending":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"switch_continue_to_break":true,"ternary_operator_spaces":true,"ternary_to_elvis_operator":true,"ternary_to_null_coalescing":true,"trailing_comma_in_multiline":{"after_heredoc":false,"elements":["arguments","array_destructuring","arrays","match","parameters"]},"trim_array_spaces":true,"type_declaration_spaces":{"elements":["constant","function","property"]},"types_spaces":{"space":"none","space_multiple_catch":"none"},"unary_operator_spaces":{"only_dec_inc":false},"void_return":true,"whitespace_after_comma_in_array":{"ensure_single_space":true}},"hashes":{"tests\/Queries\/CommonTest.php":"8ad8dec7a945ff3dbfbc8ef8f7c86eaf","tests\/_resources\/init.php":"83768ef674cd61267b4371fff20b2553","\/home\/vitex\/Projects\/VitexSoftware\/php-vitexsoftware-fluentpdo\/.php-cs-fixer.dist.php":"3177cb95719cf6d4c0f4a0e8dae81229","src\/Structure.php":"59ce9704a50bbded92bf8b60d244610e","src\/Regex.php":"adab89e94b1dfc35fbb6f92cf307c056","src\/Utilities.php":"f1e09b971af6b70d17f92993a41615a4","src\/Exception.php":"c6b0a74b886e899d7e09d37f83fe86c8","src\/Query.php":"427d9b9cbcba946c63db851c45f347cf","src\/Literal.php":"0c426a399ef95bc2c3bccedf502e106c","src\/Queries\/Common.php":"6298aa616141fa78b7007246c6810724","src\/Queries\/Delete.php":"1ee5ab0f19fb2da294d8b479faafe49f","src\/Queries\/Update.php":"a5df65da2943c90cc1f21456c75710d4","src\/Queries\/Select.php":"725ab00d77b4f24707493d70d112e76b","src\/Queries\/Base.php":"5af655b6e57be15ce327fec6c1f53614","src\/Queries\/Json.php":"11e8a883f2d36f10fe3a0f3b8566d990","src\/Queries\/Insert.php":"81be972e139ace8300a84fba46616cc7","tests\/RegexTest.php":"81cb4b332c2dae7b9f2a8db3711910c2","tests\/UtilitiesTest.php":"19d25aecce6b2446fd3ed243e1039cb8","tests\/StructureTest.php":"fbb1191659253ddb81de194c50bd3a55","tests\/Queries\/DeleteTest.php":"327658563233eee74b74c079c96b47e0","tests\/Queries\/SelectTest.php":"0ae3c14e0e4518ea93afc1c34334bd2d","tests\/Queries\/UpdateTest.php":"11698bca67bad8911d54da167cf60f03","tests\/Queries\/InsertTest.php":"3aae78edceac150a12f6cef6afb09437"}} \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..a12c4dc --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: VitexSoftware +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..c80b6ce --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,43 @@ + + +All code comments should be written in English. + +All messages, including error messages, should be written in English. + +All code should be written in PHP 8.4 or later. + +All code should follow the PSR-12 coding standard. + +When writing code, always include a docblock for functions and classes, describing their purpose, parameters, and return types. + +When writing tests, use PHPUnit and follow the PSR-12 coding standard. + +When writing documentation, use MarkDown format. + +When writing commit messages, use the imperative mood and keep them concise. + +When writing code comments, use complete sentences and proper grammar. + +When writing code, always use meaningful variable names that describe their purpose. + +When writing code, avoid using magic numbers or strings; instead, define constants for them. + +When writing code, always handle exceptions properly and provide meaningful error messages. + +When writing code, always include type hints for function parameters and return types. + +We are using the i18n library for internationalization, so always use the _() functions for strings that need to be translated. + +When writing code, always ensure that it is secure and does not expose any sensitive information. + +When writing code, always consider performance and optimize where necessary. + +When writing code, always ensure that it is compatible with the latest version of PHP and the libraries we are using. + +When writing code, always ensure that it is well-tested and includes unit tests where applicable. + +When writing code, always ensure that it is maintainable and follows best practices. + +When create new class or update existing class, always create or update its phpunit test files. + +After every single edit to a PHP file, always run `php -l` on the edited file to lint it and ensure code sanity before proceeding further. This is mandatory for all PHP code changes. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a9f4ba3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + versioning-strategy: increase + commit-message: + prefix: "composer" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml new file mode 100644 index 0000000..d195b3c --- /dev/null +++ b/.github/workflows/testing.yml @@ -0,0 +1,21 @@ +name: PHPUnit + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@master + env: + DEBIAN_FRONTEND: "noninteractive" + LC_ALL: "en_US.UTF-8" + LANG: "en_US.UTF-8" + - name: Prepare Environment + run: | + sudo apt-get install -y composer exim4 + composer update + - name: Run tests + run: make phpunit diff --git a/.gitignore b/.gitignore index f7f8ac3..b228ad7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ /.idea/ /vendor/ +/nbproject/ +/debian/debhelper-build-stamp +/debian/php-vitexsoftware-fluentpdo.debhelper.log +/debian/php-vitexsoftware-fluentpdo.substvars +/debian/.debhelper/ +/debian/php-vitexsoftware-fluentpdo/ diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..05c151c --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Ergebnis\PhpCsFixer\Config\Factory; +use Ergebnis\PhpCsFixer\Config\Rules; +use Ergebnis\PhpCsFixer\Config\RuleSet\Php81; + +$header = <<<'HEADER' +This file is part of the EaseCore package. + +(c) Vítězslav Dvořák + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +HEADER; + +$ruleSet = Php81::create()->withHeader($header)->withRules(Rules::fromArray([ + 'blank_line_before_statement' => [ + 'statements' => [ + 'break', + 'continue', + 'declare', + 'default', + 'do', + 'exit', + 'for', + 'foreach', + 'goto', + 'if', + 'include', + 'include_once', + 'require', + 'require_once', + 'return', + 'switch', + 'throw', + 'try', + 'while', + ], + ], + 'concat_space' => [ + 'spacing' => 'none', + ], + 'date_time_immutable' => false, + 'error_suppression' => false, + 'final_class' => false, + 'mb_str_functions' => false, + 'native_function_invocation' => [ + 'exclude' => [ + 'sprintf', + ], + 'include' => [ + '@compiler_optimized', + ], + 'scope' => 'all', + 'strict' => false, + ], + 'php_unit_internal_class' => false, + 'php_unit_test_annotation' => [ + 'style' => 'prefix', + ], + 'php_unit_test_class_requires_covers' => false, + 'return_to_yield_from' => false, + 'phpdoc_array_type' => false, + 'phpdoc_list_type' => false, + 'attribute_empty_parentheses' => false, + 'final_public_method_for_abstract_class' => false, + 'class_attributes_separation' => [ + 'elements' => [ + 'const' => 'only_if_meta', + 'property' => 'only_if_meta', + 'trait_import' => 'none', + 'case' => 'none', + ], + ], + 'yoda_style' => false, + 'php_unit_test_case_static_method_calls' => false, +])); + +$config = Factory::fromRuleSet($ruleSet)->setUnsupportedPhpVersionAllowed(true); + +$config->getFinder() + ->append([ + __DIR__.'/.php-cs-fixer.dist.php', + ]) + ->append([ + __DIR__.'/rector.php', + ]) + ->in('src') + ->in('tests'); + +$config->setCacheFile(__DIR__.'/.build/php-cs-fixer/.php-cs-fixer.cache'); + +return $config; diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cddbb74 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,23 @@ +{ + "php.version": "8.2", + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#225d9c", + "activityBar.background": "#225d9c", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "activityBarBadge.background": "#dd629d", + "activityBarBadge.foreground": "#15202b", + "commandCenter.border": "#e7e7e799", + "sash.hoverBorder": "#225d9c", + "statusBar.background": "#194472", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#225d9c", + "statusBarItem.remoteBackground": "#194472", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeBackground": "#194472", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#19447299", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#194472" +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6fe51ba --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,51 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [3.0.0] - 2025-01-21 + +### Added +- **PHP 8.1+ Support**: Complete modernization for PHP 8.1 and higher +- **Strict Type Declarations**: All files now use `declare(strict_types=1)` +- **Modern Type System**: Full use of PHP 8.1+ type declarations including: + - Union types (e.g., `string|null`, `array|string|null`) + - Mixed types for flexible parameters + - Proper return type declarations + - Typed properties throughout the codebase +- **Array Parameter Handling**: Automatic JSON serialization of array parameters +- **Enhanced IDE Support**: Better autocomplete and error detection with proper type hints +- **Updated Dependencies**: Modern development tools and PHPUnit 12.4+ + +### Changed +- **Breaking**: Minimum PHP version increased from 7.3 to 8.1 +- **Package Name**: Changed from `envms/fluentpdo` to `vitexsoftware/fluentpdo` +- **Type Safety**: All method signatures updated with proper type declarations +- **Error Handling**: Improved error messages and debugging capabilities +- **Performance**: Better memory usage through strict typing + +### Fixed +- **Array to String Conversion**: Fixed PHP warnings when arrays are passed as parameters +- **Type Compatibility**: Resolved all PHP 8.1+ compatibility issues +- **Method Signatures**: Updated all method signatures to match modern PHP standards + +### Removed +- **PHP < 8.1 Support**: No longer supports PHP versions below 8.1 + +## About This Fork + +This is a modernized fork of the original [envms/fluentpdo](https://github.com/envms/fluentpdo) project. The original project has been inactive since 2021, with the last commit being 3+ years old. This fork aims to: + +- Provide PHP 8.1+ compatibility with modern features +- Maintain API compatibility with the original project +- Add enhanced type safety and developer experience improvements +- Keep the library up-to-date with current PHP best practices + +## Migration from Original FluentPDO + +If you're migrating from the original `envms/fluentpdo`, the API remains compatible, but you'll need: + +1. PHP 8.1 or higher +2. Update your composer requirement to `vitexsoftware/fluentpdo` +3. Optionally add `declare(strict_types=1)` to your files for better performance + +The core API and functionality remain unchanged, so your existing code should work without modifications. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..24852a5 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +# vim: set tabstop=8 softtabstop=8 noexpandtab: +.PHONY: help +help: ## Displays this list of targets with descriptions + @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: cs +cs: vendor ## Normalizes composer.json with ergebnis/composer-normalize and fixes code style issues with friendsofphp/php-cs-fixer + mkdir -p .build/php-cs-fixer + vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --diff --verbose + +phpdoc: clean ## Generate PHPDoc + mkdir -p docs + phpdoc --defaultpackagename=MainPackage + mv .phpdoc/build/* docs + +apigen: ## Build Apigen documentation + rm -rfv docs ; mkdir docs + VERSION=`cat debian/composer.json | grep version | awk -F'"' '{print $4}'`; \ + apigen generate --destination=docs --title "FluentPDO ${VERSION}" --charset UTF-8 --access-levels public --access-levels protected --php --tree -- src/ diff --git a/WARP.md b/WARP.md new file mode 100644 index 0000000..2bb1be7 --- /dev/null +++ b/WARP.md @@ -0,0 +1,99 @@ +# WARP.md + +This file provides guidance to WARP (warp.dev) when working with code in this repository. + +## Project Overview + +FluentPDO - PHP 8.1+ Edition is a modernized fork of the original FluentPDO project. It's a PHP SQL query builder library using PDO with a smart join builder that automatically creates table joins. This version (3.x) requires PHP 8.1+ and includes modern type declarations, strict typing, and enhanced features. + +## Common Development Commands + +### Testing +```bash +# Run all tests +phpunit --configuration phpunit.xml + +# Install dependencies first if needed +composer install + +# Set up test database (for local development) +mysql -u $DB_USER < tests/_resources/fluentdb.sql +``` + +### Development Setup +```bash +# Install dependencies +composer install + +# For testing, you need a MySQL database named 'fluentdb' +# Check tests/_resources/init.php for database configuration +``` + +## Code Architecture + +### Core Classes Structure +- `Query` - Main entry point, creates query objects (SELECT, INSERT, UPDATE, DELETE) +- `Structure` - Handles table relationships, primary/foreign key conventions +- `Base` - Abstract base class for all query types, handles execution and parameters +- `Common` - Shared functionality for SELECT/UPDATE/DELETE queries (WHERE, JOIN clauses) + +### Query Types (src/Queries/) +- `Select` - SELECT query builder with smart joins, implements Countable +- `Insert` - INSERT query builder +- `Update` - UPDATE query builder +- `Delete` - DELETE query builder +- `Json` - JSON query support + +### Key Features +- **Smart Join Builder**: Automatically creates JOINs based on column references (e.g., `user.name` auto-joins user table) +- **Fluent Interface**: Method chaining for building queries +- **PDO Integration**: Built on top of PDO for database portability +- **Type Conversion**: Optional type conversion for read/write operations + +### Database Conventions +- Primary keys default to 'id' +- Foreign keys follow pattern '%s_id' (e.g., `user_id` for user table) +- These conventions can be customized via `Structure` class + +### Usage Patterns +```php +// Basic setup +$fluent = new \Envms\FluentPDO\Query($pdo); + +// Smart joins automatically created +$query = $fluent->from('comment') + ->where('article.published_at > ?', $date) // Auto-joins article table + ->orderBy('published_at DESC'); + +// Shorthand methods for single-row operations +$user = $fluent->from('user', 1)->fetch(); // WHERE id = 1 +$fluent->update('article', $data, 1)->execute(); // WHERE id = 1 +``` + +## Testing Environment + +Tests use MySQL with database 'fluentdb'. Test configuration: +- Travis CI: Uses root user with no password +- Local development: Uses 'vagrant'/'vagrant' credentials +- Database schema: `tests/_resources/fluentdb.sql` +- Test initialization: `tests/_resources/init.php` + +## Development Notes + +- **Modern PHP 8.1+**: This fork requires PHP 8.1+ with strict typing throughout +- **Type Safety**: All classes use `declare(strict_types=1)` and proper type declarations +- **Array Handling**: Arrays are automatically converted to JSON strings for database storage +- **Union Types**: Uses modern PHP union types where appropriate (e.g., `mixed`, `string|null`) +- **PSR-4 Autoloading**: Namespace remains `Envms\FluentPDO` for compatibility +- **Iterator Support**: All query builders implement `IteratorAggregate` for direct iteration +- **Debugging**: Debug mode available via `$fluent->debug` property (mixed type) +- **Error Handling**: Exception handling configurable via `exceptionOnError` property +- **Fetch Modes**: Supports both object and array fetch modes with enhanced type safety + +## Fork Information + +This is a modernized fork of [envms/fluentpdo](https://github.com/envms/fluentpdo) (inactive since 2021). Changes include: +- PHP 8.1+ compatibility with modern type system +- Fixed array parameter handling (JSON serialization) +- Enhanced IDE support with proper type hints +- Updated development dependencies and tools diff --git a/composer.json b/composer.json index 8b2c70f..33b3d4f 100644 --- a/composer.json +++ b/composer.json @@ -1,26 +1,63 @@ { - "name": "envms/fluentpdo", - "description": "FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.", - "keywords": ["db", "database", "dbal", "pdo", "fluent", "query", "builder", "mysql", "oracle"], - "homepage": "https://github.com/envms/fluentpdo", - "license": ["Apache-2.0", "GPL-2.0+"], - "authors": [ - { - "name": "envms", - "homepage": "https://env.ms" - } - ], - "autoload": { - "psr-4": { - "Envms\\FluentPDO\\": "src/" - } - }, + "name": "vitexsoftware/fluentpdo", + "description": "FluentPDO - PHP 8.1+ Edition. A modernized fork with strict typing, union types, and enhanced features. Quick and light PHP library for rapid query building with smart join builder.", + "type": "library", + "keywords": [ + "db", + "database", + "dbal", + "pdo", + "fluent", + "query", + "builder", + "mysql", + "oracle", + "mssql", + "php8", + "php81", + "strict-types", + "union-types", + "modern-php" + ], + "homepage": "https://github.com/VitexSoftware/php-vitexsoftware-fluentpdo", + "license": [ + "Apache-2.0", + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "envms", + "homepage": "https://env.ms" + }, + { + "name": "vitex", + "homepage": "https://vitexsoftware.com" + } + ], + "autoload": { + "psr-4": { + "Envms\\FluentPDO\\": "src/" + } + }, "require": { - "php": ">=7.1", + "php": ">=8.1", "ext-pdo": "*" }, - "require-dev": { - "phpunit/phpunit": "^8.0", - "envms/fluent-test": "^1.0" - } + "require-dev": { + "phpunit/phpunit": "^12.4", + "envms/fluent-test": "^1.0", + "roave/security-advisories": "dev-latest", + "phpstan/phpstan": "*", + "friendsofphp/php-cs-fixer": "^3.87", + "ergebnis/composer-normalize": "^2.48", + "ergebnis/php-cs-fixer-config": "^6.54" + }, + "config": { + "allow-plugins": { + "ergebnis/composer-normalize": true + } + }, + "replace": { + "envms/fluentpdo": "^2.2" + } } diff --git a/composer.lock b/composer.lock index 7143cb3..7378959 100644 --- a/composer.lock +++ b/composer.lock @@ -4,44 +4,35 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "43294b3845978b000b9d0d3002f2c3d3", + "content-hash": "80ad202d044bf390369c3e5409a17e28", "packages": [], "packages-dev": [ { - "name": "doctrine/instantiator", - "version": "1.3.1", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": ">=5.3", + "react/stream": "^1.2" }, "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "Clue\\React\\NDJson\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -50,255 +41,358 @@ ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "name": "Christian Lück", + "email": "christian@clue.engineering" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", "keywords": [ - "constructor", - "instantiate" + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, "funding": [ { - "url": "https://www.doctrine-project.org/sponsorship.html", + "url": "https://clue.engineering/support", "type": "custom" }, { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" + "url": "https://github.com/clue", + "type": "github" } ], - "time": "2020-05-29T17:27:14+00:00" + "time": "2022-12-23T10:58:28+00:00" }, { - "name": "envms/fluent-test", - "version": "v1.0.1", + "name": "composer/pcre", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/envms/fluent-test.git", - "reference": "2db2a96ce65f64b7c6328040b7da5d2240782f23" + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/envms/fluent-test/zipball/2db2a96ce65f64b7c6328040b7da5d2240782f23", - "reference": "2db2a96ce65f64b7c6328040b7da5d2240782f23", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { - "Envms\\FluentTest\\": "src/" + "Composer\\Pcre\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "Apache-2.0", - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "envms", - "homepage": "http://env.ms" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" } ], - "description": "A library for testing FluentPDO with mock data and classes", - "homepage": "https://github.com/envms/fluent-test", + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", "keywords": [ - "fluentpdo", - "library", - "test" + "PCRE", + "preg", + "regex", + "regular expression" ], - "time": "2018-08-23T17:42:04+00:00" + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.10.1", + "name": "composer/semver", + "version": "3.4.4", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "replace": { - "myclabs/deep-copy": "self.version" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] + "Composer\\Semver\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "semantic", + "semver", + "validation", + "versioning" ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" } ], - "time": "2020-06-29T13:22:24+00:00" + "time": "2025-08-20T19:15:30+00:00" }, { - "name": "phar-io/manifest", - "version": "1.0.3", + "name": "composer/xdebug-handler", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, + "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "url": "https://github.com/composer", + "type": "github" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2018-07-08T19:23:20+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { - "name": "phar-io/version", - "version": "2.0.1", + "name": "envms/fluent-test", + "version": "v1.0.1", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "url": "https://github.com/envms/fluent-test.git", + "reference": "2db2a96ce65f64b7c6328040b7da5d2240782f23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/envms/fluent-test/zipball/2db2a96ce65f64b7c6328040b7da5d2240782f23", + "reference": "2db2a96ce65f64b7c6328040b7da5d2240782f23", "shasum": "" }, - "require": { - "php": "^5.6 || ^7.0" - }, "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Envms\\FluentTest\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "Apache-2.0", + "GPL-2.0+" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "envms", + "homepage": "http://env.ms" } ], - "description": "Library for handling version information and constraints", - "time": "2018-07-08T19:19:57+00:00" + "description": "A library for testing FluentPDO with mock data and classes", + "homepage": "https://github.com/envms/fluent-test", + "keywords": [ + "fluentpdo", + "library", + "test" + ], + "support": { + "issues": "https://github.com/envms/fluent-test/issues", + "source": "https://github.com/envms/fluent-test/tree/v1.0.1" + }, + "time": "2018-08-23T17:42:04+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", + "name": "ergebnis/composer-normalize", + "version": "2.48.2", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + "url": "https://github.com/ergebnis/composer-normalize.git", + "reference": "86dc9731b8320f49e9be9ad6d8e4de9b8b0e9b8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/86dc9731b8320f49e9be9ad6d8e4de9b8b0e9b8b", + "reference": "86dc9731b8320f49e9be9ad6d8e4de9b8b0e9b8b", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "composer-plugin-api": "^2.0.0", + "ergebnis/json": "^1.4.0", + "ergebnis/json-normalizer": "^4.9.0", + "ergebnis/json-printer": "^3.7.0", + "ext-json": "*", + "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", + "localheinz/diff": "^1.3.0", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, - "type": "library", + "require-dev": { + "composer/composer": "^2.8.3", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.53.0", + "ergebnis/phpstan-rules": "^2.11.0", + "ergebnis/phpunit-slow-test-detector": "^2.20.0", + "fakerphp/faker": "^1.24.1", + "infection/infection": "~0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.17", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.7", + "phpstan/phpstan-strict-rules": "^2.0.6", + "phpunit/phpunit": "^9.6.20", + "rector/rector": "^2.1.4", + "symfony/filesystem": "^5.4.41" + }, + "type": "composer-plugin", "extra": { + "class": "Ergebnis\\Composer\\Normalize\\NormalizePlugin", "branch-alias": { - "dev-2.x": "2.x-dev" + "dev-main": "2.49-dev" + }, + "plugin-optional": true, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src/" + "Ergebnis\\Composer\\Normalize\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -307,54 +401,74 @@ ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "Provides a composer plugin for normalizing composer.json.", + "homepage": "https://github.com/ergebnis/composer-normalize", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" + "composer", + "normalize", + "normalizer", + "plugin" ], - "time": "2020-06-27T09:03:43+00:00" + "support": { + "issues": "https://github.com/ergebnis/composer-normalize/issues", + "security": "https://github.com/ergebnis/composer-normalize/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/composer-normalize" + }, + "time": "2025-09-06T11:42:34+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "5.2.1", + "name": "ergebnis/json", + "version": "1.6.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" + "url": "https://github.com/ergebnis/json.git", + "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", + "url": "https://api.github.com/repos/ergebnis/json/zipball/7b56d2b5d9e897e75b43e2e753075a0904c921b1", + "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1", "shasum": "" }, "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" + "ext-json": "*", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "mockery/mockery": "~1.3.2" + "ergebnis/composer-normalize": "^2.44.0", + "ergebnis/data-provider": "^3.3.0", + "ergebnis/license": "^2.5.0", + "ergebnis/php-cs-fixer-config": "^6.37.0", + "ergebnis/phpstan-rules": "^2.11.0", + "ergebnis/phpunit-slow-test-detector": "^2.16.1", + "fakerphp/faker": "^1.24.0", + "infection/infection": "~0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.22", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.7", + "phpstan/phpstan-strict-rules": "^2.0.6", + "phpunit/phpunit": "^9.6.24", + "rector/rector": "^2.1.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.x-dev" + "dev-main": "1.7-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src" + "Ergebnis\\Json\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -363,47 +477,79 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-08-15T11:14:08+00:00" + "description": "Provides a Json value object for representing a valid JSON string.", + "homepage": "https://github.com/ergebnis/json", + "keywords": [ + "json" + ], + "support": { + "issues": "https://github.com/ergebnis/json/issues", + "security": "https://github.com/ergebnis/json/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/json" + }, + "time": "2025-09-06T09:08:45+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "1.3.0", + "name": "ergebnis/json-normalizer", + "version": "4.10.1", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + "url": "https://github.com/ergebnis/json-normalizer.git", + "reference": "77961faf2c651c3f05977b53c6c68e8434febf62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/77961faf2c651c3f05977b53c6c68e8434febf62", + "reference": "77961faf2c651c3f05977b53c6c68e8434febf62", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "ergebnis/json": "^1.2.0", + "ergebnis/json-pointer": "^3.4.0", + "ergebnis/json-printer": "^3.5.0", + "ergebnis/json-schema-validator": "^4.2.0", + "ext-json": "*", + "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "ext-tokenizer": "*" + "composer/semver": "^3.4.3", + "ergebnis/composer-normalize": "^2.44.0", + "ergebnis/data-provider": "^3.3.0", + "ergebnis/license": "^2.5.0", + "ergebnis/php-cs-fixer-config": "^6.37.0", + "ergebnis/phpunit-slow-test-detector": "^2.16.1", + "fakerphp/faker": "^1.24.0", + "infection/infection": "~0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.10", + "phpstan/phpstan-deprecation-rules": "^1.2.1", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.1", + "phpunit/phpunit": "^9.6.19", + "rector/rector": "^1.2.10" + }, + "suggest": { + "composer/semver": "If you want to use ComposerJsonNormalizer or VersionConstraintNormalizer" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-main": "4.11-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src" + "Ergebnis\\Json\\Normalizer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -412,47 +558,70 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-27T10:12:23+00:00" + "description": "Provides generic and vendor-specific normalizers for normalizing JSON documents.", + "homepage": "https://github.com/ergebnis/json-normalizer", + "keywords": [ + "json", + "normalizer" + ], + "support": { + "issues": "https://github.com/ergebnis/json-normalizer/issues", + "security": "https://github.com/ergebnis/json-normalizer/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/json-normalizer" + }, + "time": "2025-09-06T09:18:13+00:00" }, { - "name": "phpspec/prophecy", - "version": "1.11.1", + "name": "ergebnis/json-pointer", + "version": "3.7.1", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" + "url": "https://github.com/ergebnis/json-pointer.git", + "reference": "43bef355184e9542635e35dd2705910a3df4c236" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", + "url": "https://api.github.com/repos/ergebnis/json-pointer/zipball/43bef355184e9542635e35dd2705910a3df4c236", + "reference": "43bef355184e9542635e35dd2705910a3df4c236", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2", - "phpdocumentor/reflection-docblock": "^5.0", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0" + "ergebnis/composer-normalize": "^2.43.0", + "ergebnis/data-provider": "^3.2.0", + "ergebnis/license": "^2.4.0", + "ergebnis/php-cs-fixer-config": "^6.32.0", + "ergebnis/phpunit-slow-test-detector": "^2.15.0", + "fakerphp/faker": "^1.23.1", + "infection/infection": "~0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.10", + "phpstan/phpstan-deprecation-rules": "^1.2.1", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.1", + "phpunit/phpunit": "^9.6.19", + "rector/rector": "^1.2.10" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-main": "3.8-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" } }, "autoload": { "psr-4": { - "Prophecy\\": "src/Prophecy" + "Ergebnis\\Json\\Pointer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -461,567 +630,676 @@ ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", + "description": "Provides an abstraction of a JSON pointer.", + "homepage": "https://github.com/ergebnis/json-pointer", "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" + "RFC6901", + "json", + "pointer" ], - "time": "2020-07-08T12:44:21+00:00" + "support": { + "issues": "https://github.com/ergebnis/json-pointer/issues", + "security": "https://github.com/ergebnis/json-pointer/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/json-pointer" + }, + "time": "2025-09-06T09:28:19+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "7.0.10", + "name": "ergebnis/json-printer", + "version": "3.8.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" + "url": "https://github.com/ergebnis/json-printer.git", + "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", + "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/211d73fc7ec6daf98568ee6ed6e6d133dee8503e", + "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.2", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.1.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^4.2.2", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1.3" + "ext-json": "*", + "ext-mbstring": "*", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "phpunit/phpunit": "^8.2.2" - }, - "suggest": { - "ext-xdebug": "^2.7.2" + "ergebnis/composer-normalize": "^2.44.0", + "ergebnis/data-provider": "^3.3.0", + "ergebnis/license": "^2.5.0", + "ergebnis/php-cs-fixer-config": "^6.37.0", + "ergebnis/phpunit-slow-test-detector": "^2.16.1", + "fakerphp/faker": "^1.24.0", + "infection/infection": "~0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.10", + "phpstan/phpstan-deprecation-rules": "^1.2.1", + "phpstan/phpstan-phpunit": "^1.4.1", + "phpstan/phpstan-strict-rules": "^1.6.1", + "phpunit/phpunit": "^9.6.21", + "rector/rector": "^1.2.10" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "7.0-dev" + "dev-main": "3.9-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Ergebnis\\Json\\Printer\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "Provides a JSON printer, allowing for flexible indentation.", + "homepage": "https://github.com/ergebnis/json-printer", "keywords": [ - "coverage", - "testing", - "xunit" + "formatter", + "json", + "printer" ], - "time": "2019-11-20T13:55:58+00:00" + "support": { + "issues": "https://github.com/ergebnis/json-printer/issues", + "security": "https://github.com/ergebnis/json-printer/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/json-printer" + }, + "time": "2025-09-06T09:59:26+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "2.0.2", + "name": "ergebnis/json-schema-validator", + "version": "4.5.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" + "url": "https://github.com/ergebnis/json-schema-validator.git", + "reference": "b739527a480a9e3651360ad351ea77e7e9019df2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", + "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/b739527a480a9e3651360ad351ea77e7e9019df2", + "reference": "b739527a480a9e3651360ad351ea77e7e9019df2", "shasum": "" }, "require": { - "php": "^7.1" + "ergebnis/json": "^1.2.0", + "ergebnis/json-pointer": "^3.4.0", + "ext-json": "*", + "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "ergebnis/composer-normalize": "^2.44.0", + "ergebnis/data-provider": "^3.3.0", + "ergebnis/license": "^2.5.0", + "ergebnis/php-cs-fixer-config": "^6.37.0", + "ergebnis/phpunit-slow-test-detector": "^2.16.1", + "fakerphp/faker": "^1.24.0", + "infection/infection": "~0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.10", + "phpstan/phpstan-deprecation-rules": "^1.2.1", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.1", + "phpunit/phpunit": "^9.6.20", + "rector/rector": "^1.2.10" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "4.6-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Ergebnis\\Json\\SchemaValidator\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "description": "Provides a JSON schema validator, building on top of justinrainbow/json-schema.", + "homepage": "https://github.com/ergebnis/json-schema-validator", "keywords": [ - "filesystem", - "iterator" + "json", + "schema", + "validator" ], - "time": "2018-09-13T20:33:42+00:00" + "support": { + "issues": "https://github.com/ergebnis/json-schema-validator/issues", + "security": "https://github.com/ergebnis/json-schema-validator/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/json-schema-validator" + }, + "time": "2025-09-06T11:37:35+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "ergebnis/php-cs-fixer-config", + "version": "6.55.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/ergebnis/php-cs-fixer-config.git", + "reference": "e43a11451c844ca2cbcb826c7d3e14553f914532" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/ergebnis/php-cs-fixer-config/zipball/e43a11451c844ca2cbcb826c7d3e14553f914532", + "reference": "e43a11451c844ca2cbcb826c7d3e14553f914532", "shasum": "" }, "require": { - "php": ">=5.3.3" + "erickskrauch/php-cs-fixer-custom-fixers": "~1.3.0", + "ext-filter": "*", + "friendsofphp/php-cs-fixer": "~3.88.2", + "kubawerlos/php-cs-fixer-custom-fixers": "~3.35.1", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.48.2", + "ergebnis/data-provider": "^3.6.0", + "ergebnis/license": "^2.7.0", + "ergebnis/phpstan-rules": "^2.12.0", + "ergebnis/phpunit-slow-test-detector": "^2.20.0", + "ergebnis/rector-rules": "^1.6.0", + "fakerphp/faker": "^1.24.1", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.29", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.7", + "phpstan/phpstan-strict-rules": "^2.0.7", + "phpunit/phpunit": "^9.6.22", + "rector/rector": "^2.1.7", + "symfony/filesystem": "^5.0.0 || ^6.0.0", + "symfony/process": "^5.0.0 || ^6.0.0" }, "type": "library", + "extra": { + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Ergebnis\\PhpCsFixer\\Config\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" + "description": "Provides a configuration factory and rule set factories for friendsofphp/php-cs-fixer.", + "homepage": "https://github.com/ergebnis/php-cs-fixer-config", + "support": { + "issues": "https://github.com/ergebnis/php-cs-fixer-config/issues", + "security": "https://github.com/ergebnis/php-cs-fixer-config/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/php-cs-fixer-config" + }, + "time": "2025-10-01T13:54:12+00:00" }, { - "name": "phpunit/php-timer", - "version": "2.1.2", + "name": "erickskrauch/php-cs-fixer-custom-fixers", + "version": "1.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + "url": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers.git", + "reference": "36fb7f8204c1e17d9b8a24910e2147d0a3973b9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "url": "https://api.github.com/repos/erickskrauch/php-cs-fixer-custom-fixers/zipball/36fb7f8204c1e17d9b8a24910e2147d0a3973b9c", + "reference": "36fb7f8204c1e17d9b8a24910e2147d0a3973b9c", "shasum": "" }, "require": { - "php": "^7.1" + "friendsofphp/php-cs-fixer": "^3", + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "ely/php-code-style": "^1", + "ergebnis/composer-normalize": "^2.28", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "phpspec/prophecy": "^1.15", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan": "^1.11.x-dev", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.5", + "phpunitgoodpractices/traits": "^1.9.1", + "symfony/phpunit-bridge": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "1.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "ErickSkrauch\\PhpCsFixer\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "ErickSkrauch", + "email": "erickskrauch@ely.by" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "A set of custom fixers for PHP-CS-Fixer", + "homepage": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers", "keywords": [ - "timer" + "Code style", + "dev", + "php-cs-fixer" ], - "time": "2019-06-07T04:22:29+00:00" + "support": { + "issues": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers/issues", + "source": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers/tree/1.3.0" + }, + "time": "2024-06-21T20:19:52+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "3.1.1", + "name": "evenement/evenement", + "version": "v3.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.1" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9 || ^6" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Evenement\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "Événement is a very simple event dispatching library for PHP", "keywords": [ - "tokenizer" + "event-dispatcher", + "event-emitter" ], - "abandoned": true, - "time": "2019-09-17T06:23:10+00:00" + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" }, { - "name": "phpunit/phpunit", - "version": "8.5.8", + "name": "fidry/cpu-core-counter", + "version": "1.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997" + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997", - "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2.0", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.9.1", - "phar-io/manifest": "^1.0.3", - "phar-io/version": "^2.0.1", - "php": "^7.2", - "phpspec/prophecy": "^1.8.1", - "phpunit/php-code-coverage": "^7.0.7", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1.2", - "sebastian/comparator": "^3.0.2", - "sebastian/diff": "^3.0.2", - "sebastian/environment": "^4.2.2", - "sebastian/exporter": "^3.1.1", - "sebastian/global-state": "^3.0.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0.1", - "sebastian/type": "^1.1.3", - "sebastian/version": "^2.0.1" + "php": "^7.2 || ^8.0" }, "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0.0" + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" }, - "bin": [ - "phpunit" - ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "8.5-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "Tiny utility to get the number of CPU cores.", "keywords": [ - "phpunit", - "testing", - "xunit" + "CPU", + "core" ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, "funding": [ { - "url": "https://phpunit.de/donate.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/theofidry", "type": "github" } ], - "time": "2020-06-22T07:06:58+00:00" + "time": "2025-08-14T07:29:31+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "name": "friendsofphp/php-cs-fixer", + "version": "v3.88.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a8d15584bafb0f0d9d938827840060fd4a3ebc99", + "reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "clue/ndjson-react": "^1.3", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.5", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.3", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.6", + "react/event-loop": "^1.5", + "react/promise": "^3.3", + "react/socket": "^1.16", + "react/stream": "^1.4", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", + "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/polyfill-mbstring": "^1.33", + "symfony/polyfill-php80": "^1.33", + "symfony/polyfill-php81": "^1.33", + "symfony/polyfill-php84": "^1.33", + "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2", + "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "facile-it/paraunit": "^1.3.1 || ^2.7", + "infection/infection": "^0.31.0", + "justinrainbow/json-schema": "^6.5", + "keradus/cli-executor": "^2.2", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.8", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", + "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34", + "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2", + "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", "autoload": { - "classmap": [ - "src/" + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.88.2" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "time": "2025-09-27T00:24:15+00:00" }, { - "name": "sebastian/comparator", - "version": "3.0.2", + "name": "justinrainbow/json-schema", + "version": "6.6.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + "url": "https://github.com/jsonrainbow/json-schema.git", + "reference": "68ba7677532803cc0c5900dd5a4d730537f2b2f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/68ba7677532803cc0c5900dd5a4d730537f2b2f3", + "reference": "68ba7677532803cc0c5900dd5a4d730537f2b2f3", "shasum": "" }, "require": { - "php": "^7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" + "ext-json": "*", + "marc-mabe/php-enum": "^4.0", + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "friendsofphp/php-cs-fixer": "3.3.0", + "json-schema/json-schema-test-suite": "^23.2", + "marc-mabe/php-enum-phpstan": "^2.0", + "phpspec/prophecy": "^1.19", + "phpstan/phpstan": "^1.12", + "phpunit/phpunit": "^8.5" }, + "bin": [ + "bin/validate-json" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "6.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" }, { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", + "description": "A library to validate a json schema.", + "homepage": "https://github.com/jsonrainbow/json-schema", "keywords": [ - "comparator", - "compare", - "equality" + "json", + "schema" ], - "time": "2018-07-12T15:12:46+00:00" + "support": { + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/6.6.0" + }, + "time": "2025-10-10T11:34:09+00:00" }, { - "name": "sebastian/diff", - "version": "3.0.2", + "name": "kubawerlos/php-cs-fixer-custom-fixers", + "version": "v3.35.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + "url": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers.git", + "reference": "2a35f80ae24ca77443a7af1599c3a3db1b6bd395" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/2a35f80ae24ca77443a7af1599c3a3db1b6bd395", + "reference": "2a35f80ae24ca77443a7af1599c3a3db1b6bd395", "shasum": "" }, "require": { - "php": "^7.1" + "ext-filter": "*", + "ext-tokenizer": "*", + "friendsofphp/php-cs-fixer": "^3.87", + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" + "phpunit/phpunit": "^9.6.24 || ^10.5.51 || ^11.5.32" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PhpCsFixerCustomFixers\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Kuba Werłos", + "email": "werlos@gmail.com" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" + "description": "A set of custom fixers for PHP CS Fixer", + "support": { + "issues": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/issues", + "source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.35.1" + }, + "funding": [ + { + "url": "https://github.com/kubawerlos", + "type": "github" + } ], - "time": "2019-02-04T06:01:07+00:00" + "time": "2025-09-28T18:43:35+00:00" }, { - "name": "sebastian/environment", - "version": "4.2.3", + "name": "localheinz/diff", + "version": "1.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + "url": "https://github.com/localheinz/diff.git", + "reference": "33bd840935970cda6691c23fc7d94ae764c0734c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "url": "https://api.github.com/repos/localheinz/diff/zipball/33bd840935970cda6691c23fc7d94ae764c0734c", + "reference": "33bd840935970cda6691c23fc7d94ae764c0734c", "shasum": "" }, "require": { - "php": "^7.1" + "php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "phpunit/phpunit": "^7.5" - }, - "suggest": { - "ext-posix": "*" + "phpunit/phpunit": "^7.5.0 || ^8.5.23", + "symfony/process": "^4.2 || ^5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "classmap": [ "src/" @@ -1035,48 +1313,63 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "description": "Fork of sebastian/diff for use with ergebnis/composer-normalize", + "homepage": "https://github.com/localheinz/diff", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2019-11-20T08:46:58+00:00" + "support": { + "issues": "https://github.com/localheinz/diff/issues", + "source": "https://github.com/localheinz/diff/tree/1.3.0" + }, + "time": "2025-08-30T09:44:18+00:00" }, { - "name": "sebastian/exporter", - "version": "3.1.2", + "name": "marc-mabe/php-enum", + "version": "v4.7.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + "url": "https://github.com/marc-mabe/php-enum.git", + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/bb426fcdd65c60fb3638ef741e8782508fda7eef", + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" + "ext-reflection": "*", + "php": "^7.1 | ^8.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpbench/phpbench": "^0.16.10 || ^1.0.4", + "phpstan/phpstan": "^1.3.1", + "phpunit/phpunit": "^7.5.20 | ^8.5.22 | ^9.5.11", + "vimeo/psalm": "^4.17.0 | ^5.26.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-3.x": "3.2-dev", + "dev-master": "4.7-dev" } }, "autoload": { + "psr-4": { + "MabeEnum\\": "src/" + }, "classmap": [ - "src/" + "stubs/Stringable.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1085,120 +1378,131 @@ ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Marc Bennewitz", + "email": "dev@mabe.berlin", + "homepage": "https://mabe.berlin/", + "role": "Lead" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "description": "Simple and fast implementation of enumerations with native PHP", + "homepage": "https://github.com/marc-mabe/php-enum", "keywords": [ - "export", - "exporter" + "enum", + "enum-map", + "enum-set", + "enumeration", + "enumerator", + "enummap", + "enumset", + "map", + "set", + "type", + "type-hint", + "typehint" ], - "time": "2019-09-14T09:02:43+00:00" + "support": { + "issues": "https://github.com/marc-mabe/php-enum/issues", + "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.2" + }, + "time": "2025-09-14T11:18:39+00:00" }, { - "name": "sebastian/global-state", - "version": "3.0.0", + "name": "myclabs/deep-copy", + "version": "1.13.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { - "php": "^7.2", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": "^7.1 || ^8.0" }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^8.0" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, - "suggest": { - "ext-uopz": "*" + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "description": "Create deep copies (clones) of your objects", "keywords": [ - "global state" + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } ], - "time": "2019-02-01T05:30:01+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "3.0.3", + "name": "nikic/php-parser", + "version": "v5.6.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "3a454ca033b9e06b63282ce19562e892747449bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb", + "reference": "3a454ca033b9e06b63282ce19562e892747449bb", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1206,38 +1510,46 @@ ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nikita Popov" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2" + }, + "time": "2025-10-21T19:32:17+00:00" }, { - "name": "sebastian/object-reflector", - "version": "1.1.1", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1250,41 +1562,53 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { - "name": "sebastian/recursion-context", - "version": "3.0.0", + "name": "phar-io/version", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" + "php": "^7.2 || ^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, "autoload": { "classmap": [ "src/" @@ -1296,88 +1620,120 @@ ], "authors": [ { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" }, { - "name": "sebastian/resource-operations", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" - }, + "name": "phpstan/phpstan", + "version": "2.1.31", "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ead89849d879fe203ce9292c6ef5e7e76f867b96", + "reference": "ead89849d879fe203ce9292c6ef5e7e76f867b96", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.4|^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } + "conflict": { + "phpstan/phpstan-shim": "*" }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", "autoload": { - "classmap": [ - "src/" + "files": [ + "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" + "time": "2025-10-10T14:14:11+00:00" }, { - "name": "sebastian/type", - "version": "1.1.3", + "name": "phpunit/php-code-coverage", + "version": "12.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c", + "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c", "shasum": "" }, "require": { - "php": "^7.2" + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.6.1", + "php": ">=8.3", + "phpunit/php-file-iterator": "^6.0", + "phpunit/php-text-template": "^5.0", + "sebastian/complexity": "^5.0", + "sebastian/environment": "^8.0.3", + "sebastian/lines-of-code": "^4.0", + "sebastian/version": "^6.0", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^8.2" + "phpunit/phpunit": "^12.3.7" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-main": "12.4.x-dev" } }, "autoload": { @@ -1396,31 +1752,62 @@ "role": "lead" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "time": "2019-07-02T08:10:15+00:00" + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.4.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2025-09-24T13:44:41+00:00" }, { - "name": "sebastian/version", - "version": "2.0.1", + "name": "phpunit/php-file-iterator", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "961bc913d42fe24a257bfff826a5068079ac7782" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782", + "reference": "961bc913d42fe24a257bfff826a5068079ac7782", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1439,107 +1826,115 @@ "role": "lead" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:58:37+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.18.1", + "name": "phpunit/php-invoker", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^12.0" }, "suggest": { - "ext-ctype": "For best performance" + "ext-pcntl": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "dev-main": "6.0-dev" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" + "process" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0" + }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2025-02-07T04:58:58+00:00" }, { - "name": "theseer/tokenizer", - "version": "1.2.0", + "name": "phpunit/php-text-template", + "version": "5.0.0", "source": { "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1551,49 +1946,372 @@ ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0" + }, "funding": [ { - "url": "https://github.com/theseer", + "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-07-12T23:59:07+00:00" + "time": "2025-02-07T04:59:16+00:00" }, { - "name": "webmozart/assert", - "version": "1.9.1", + "name": "phpunit/php-timer", + "version": "8.0.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "php": ">=8.3" }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:59:38+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "12.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "fc5413a2e6d240d2f6d9317bdf7f0a24e73de194" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc5413a2e6d240d2f6d9317bdf7f0a24e73de194", + "reference": "fc5413a2e6d240d2f6d9317bdf7f0a24e73de194", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.4.0", + "phpunit/php-file-iterator": "^6.0.0", + "phpunit/php-invoker": "^6.0.0", + "phpunit/php-text-template": "^5.0.0", + "phpunit/php-timer": "^8.0.0", + "sebastian/cli-parser": "^4.2.0", + "sebastian/comparator": "^7.1.3", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.0.3", + "sebastian/exporter": "^7.0.2", + "sebastian/global-state": "^8.0.2", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/type": "^6.0.3", + "sebastian/version": "^6.0.0", + "staabm/side-effects-detector": "^1.0.5" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "12.4-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.4.1" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-10-09T14:08:29+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" }, "type": "library", "autoload": { "psr-4": { - "Webmozart\\Assert\\": "src/" + "React\\Cache\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1602,25 +2320,3903 @@ ], "authors": [ { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Assertions to validate method input/output with nice error messages.", + "description": "Async, Promise-based cache interface for ReactPHP", "keywords": [ - "assert", - "check", - "validate" + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.6", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-01-01T16:37:48+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.12.28 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-08-19T18:57:03+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "roave/security-advisories", + "version": "dev-latest", + "source": { + "type": "git", + "url": "https://github.com/Roave/SecurityAdvisories.git", + "reference": "d76fe05e57166d21b7b1e3da6f7f3895c3c5db46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/d76fe05e57166d21b7b1e3da6f7f3895c3c5db46", + "reference": "d76fe05e57166d21b7b1e3da6f7f3895c3c5db46", + "shasum": "" + }, + "conflict": { + "3f/pygmentize": "<1.2", + "adaptcms/adaptcms": "<=1.3", + "admidio/admidio": "<4.3.12", + "adodb/adodb-php": "<=5.22.9", + "aheinze/cockpit": "<2.2", + "aimeos/ai-admin-graphql": ">=2022.04.1,<2022.10.10|>=2023.04.1,<2023.10.6|>=2024.04.1,<2024.07.2", + "aimeos/ai-admin-jsonadm": "<2020.10.13|>=2021.04.1,<2021.10.6|>=2022.04.1,<2022.10.3|>=2023.04.1,<2023.10.4|==2024.04.1", + "aimeos/ai-client-html": ">=2020.04.1,<2020.10.27|>=2021.04.1,<2021.10.22|>=2022.04.1,<2022.10.13|>=2023.04.1,<2023.10.15|>=2024.04.1,<2024.04.7", + "aimeos/ai-controller-frontend": "<2020.10.15|>=2021.04.1,<2021.10.8|>=2022.04.1,<2022.10.8|>=2023.04.1,<2023.10.9|==2024.04.1", + "aimeos/aimeos-core": ">=2022.04.1,<2022.10.17|>=2023.04.1,<2023.10.17|>=2024.04.1,<2024.04.7", + "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", + "airesvsg/acf-to-rest-api": "<=3.1", + "akaunting/akaunting": "<2.1.13", + "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53", + "alextselegidis/easyappointments": "<1.5.2.0-beta1", + "alt-design/alt-redirect": "<1.6.4", + "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", + "amazing/media2click": ">=1,<1.3.3", + "ameos/ameos_tarteaucitron": "<1.2.23", + "amphp/artax": "<1.0.6|>=2,<2.0.6", + "amphp/http": "<=1.7.2|>=2,<=2.1", + "amphp/http-client": ">=4,<4.4", + "anchorcms/anchor-cms": "<=0.12.7", + "andreapollastri/cipi": "<=3.1.15", + "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5", + "aoe/restler": "<1.7.1", + "apache-solr-for-typo3/solr": "<2.8.3", + "apereo/phpcas": "<1.6", + "api-platform/core": "<3.4.17|>=4,<4.0.22|>=4.1,<4.1.5", + "api-platform/graphql": "<3.4.17|>=4,<4.0.22|>=4.1,<4.1.5", + "appwrite/server-ce": "<=1.2.1", + "arc/web": "<3", + "area17/twill": "<1.2.5|>=2,<2.5.3", + "artesaos/seotools": "<0.17.2", + "asymmetricrypt/asymmetricrypt": "<9.9.99", + "athlon1600/php-proxy": "<=5.1", + "athlon1600/php-proxy-app": "<=3", + "athlon1600/youtube-downloader": "<=4", + "austintoddj/canvas": "<=3.4.2", + "auth0/auth0-php": ">=3.3,<=8.16", + "auth0/login": "<=7.18", + "auth0/symfony": "<=5.4.1", + "auth0/wordpress": "<=5.3", + "automad/automad": "<2.0.0.0-alpha5", + "automattic/jetpack": "<9.8", + "awesome-support/awesome-support": "<=6.0.7", + "aws/aws-sdk-php": "<3.288.1", + "azuracast/azuracast": "<0.18.3", + "b13/seo_basics": "<0.8.2", + "backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2", + "backpack/crud": "<3.4.9", + "backpack/filemanager": "<2.0.2|>=3,<3.0.9", + "bacula-web/bacula-web": "<9.7.1", + "badaso/core": "<=2.9.11", + "bagisto/bagisto": "<=2.3.7", + "barrelstrength/sprout-base-email": "<1.2.7", + "barrelstrength/sprout-forms": "<3.9", + "barryvdh/laravel-translation-manager": "<0.6.8", + "barzahlen/barzahlen-php": "<2.0.1", + "baserproject/basercms": "<=5.1.1", + "bassjobsen/bootstrap-3-typeahead": ">4.0.2", + "bbpress/bbpress": "<2.6.5", + "bcit-ci/codeigniter": "<3.1.3", + "bcosca/fatfree": "<3.7.2", + "bedita/bedita": "<4", + "bednee/cooluri": "<1.0.30", + "bigfork/silverstripe-form-capture": ">=3,<3.1.1", + "billz/raspap-webgui": "<3.3.6", + "binarytorch/larecipe": "<2.8.1", + "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3", + "blueimp/jquery-file-upload": "==6.4.4", + "bmarshall511/wordpress_zero_spam": "<5.2.13", + "bolt/bolt": "<3.7.2", + "bolt/core": "<=4.2", + "born05/craft-twofactorauthentication": "<3.3.4", + "bottelet/flarepoint": "<2.2.1", + "bref/bref": "<2.1.17", + "brightlocal/phpwhois": "<=4.2.5", + "brotkrueml/codehighlight": "<2.7", + "brotkrueml/schema": "<1.13.1|>=2,<2.5.1", + "brotkrueml/typo3-matomo-integration": "<1.3.2", + "buddypress/buddypress": "<7.2.1", + "bugsnag/bugsnag-laravel": ">=2,<2.0.2", + "bvbmedia/multishop": "<2.0.39", + "bytefury/crater": "<6.0.2", + "cachethq/cachet": "<2.5.1", + "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cardgate/magento2": "<2.0.33", + "cardgate/woocommerce": "<=3.1.15", + "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cart2quote/module-quotation-encoded": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cartalyst/sentry": "<=2.1.6", + "catfan/medoo": "<1.7.5", + "causal/oidc": "<4", + "cecil/cecil": "<7.47.1", + "centreon/centreon": "<22.10.15", + "cesnet/simplesamlphp-module-proxystatistics": "<3.1", + "chriskacerguis/codeigniter-restserver": "<=2.7.1", + "chrome-php/chrome": "<1.14", + "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", + "ckeditor/ckeditor": "<4.25", + "clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3", + "co-stack/fal_sftp": "<0.2.6", + "cockpit-hq/cockpit": "<2.11.4", + "codeception/codeception": "<3.1.3|>=4,<4.1.22", + "codeigniter/framework": "<3.1.10", + "codeigniter4/framework": "<4.6.2", + "codeigniter4/shield": "<1.0.0.0-beta8", + "codiad/codiad": "<=2.8.4", + "codingms/additional-tca": ">=1.7,<1.15.17|>=1.16,<1.16.9", + "commerceteam/commerce": ">=0.9.6,<0.9.9", + "components/jquery": ">=1.0.3,<3.5", + "composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7", + "concrete5/concrete5": "<9.4.3", + "concrete5/core": "<8.5.8|>=9,<9.1", + "contao-components/mediaelement": ">=2.14.2,<2.21.1", + "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4", + "contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.13.56|>=5,<5.3.38|>=5.4.0.0-RC1-dev,<5.6.1", + "contao/core": "<3.5.39", + "contao/core-bundle": "<4.13.56|>=5,<5.3.38|>=5.4,<5.6.1", + "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8", + "contao/managed-edition": "<=1.5", + "corveda/phpsandbox": "<1.3.5", + "cosenary/instagram": "<=2.3", + "couleurcitron/tarteaucitron-wp": "<0.3", + "craftcms/cms": "<=4.16.5|>=5,<=5.8.6", + "croogo/croogo": "<4", + "cuyz/valinor": "<0.12", + "czim/file-handling": "<1.5|>=2,<2.3", + "czproject/git-php": "<4.0.3", + "damienharper/auditor-bundle": "<5.2.6", + "dapphp/securimage": "<3.6.6", + "darylldoyle/safe-svg": "<1.9.10", + "datadog/dd-trace": ">=0.30,<0.30.2", + "datahihi1/tiny-env": "<1.0.3|>=1.0.9,<1.0.11", + "datatables/datatables": "<1.10.10", + "david-garcia/phpwhois": "<=4.3.1", + "dbrisinajumi/d2files": "<1", + "dcat/laravel-admin": "<=2.1.3|==2.2.0.0-beta|==2.2.2.0-beta", + "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", + "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4", + "desperado/xml-bundle": "<=0.1.7", + "dev-lancer/minecraft-motd-parser": "<=1.0.5", + "devgroup/dotplant": "<2020.09.14-dev", + "digimix/wp-svg-upload": "<=1", + "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2", + "dl/yag": "<3.0.1", + "dmk/webkitpdf": "<1.1.4", + "dnadesign/silverstripe-elemental": "<5.3.12", + "doctrine/annotations": "<1.2.7", + "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", + "doctrine/common": "<2.4.3|>=2.5,<2.5.1", + "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4", + "doctrine/doctrine-bundle": "<1.5.2", + "doctrine/doctrine-module": "<0.7.2", + "doctrine/mongodb-odm": "<1.0.2", + "doctrine/mongodb-odm-bundle": "<3.0.1", + "doctrine/orm": ">=1,<1.2.4|>=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", + "dolibarr/dolibarr": "<21.0.3", + "dompdf/dompdf": "<2.0.4", + "doublethreedigital/guest-entries": "<3.1.2", + "drupal-pattern-lab/unified-twig-extensions": "<=0.1", + "drupal/admin_audit_trail": "<1.0.5", + "drupal/ai": "<1.0.5", + "drupal/alogin": "<2.0.6", + "drupal/cache_utility": "<1.2.1", + "drupal/commerce_alphabank_redirect": "<1.0.3", + "drupal/commerce_eurobank_redirect": "<2.1.1", + "drupal/config_split": "<1.10|>=2,<2.0.2", + "drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.3.14|>=10.4,<10.4.5|>=11,<11.0.13|>=11.1,<11.1.5", + "drupal/core-recommended": ">=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", + "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", + "drupal/formatter_suite": "<2.1", + "drupal/gdpr": "<3.0.1|>=3.1,<3.1.2", + "drupal/google_tag": "<1.8|>=2,<2.0.8", + "drupal/ignition": "<1.0.4", + "drupal/lightgallery": "<1.6", + "drupal/link_field_display_mode_formatter": "<1.6", + "drupal/matomo": "<1.24", + "drupal/oauth2_client": "<4.1.3", + "drupal/oauth2_server": "<2.1", + "drupal/obfuscate": "<2.0.1", + "drupal/quick_node_block": "<2", + "drupal/rapidoc_elements_field_formatter": "<1.0.1", + "drupal/spamspan": "<3.2.1", + "drupal/tfa": "<1.10", + "duncanmcclean/guest-entries": "<3.1.2", + "dweeves/magmi": "<=0.7.24", + "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2", + "ecodev/newsletter": "<=4", + "ectouch/ectouch": "<=2.7.2", + "egroupware/egroupware": "<23.1.20240624", + "elefant/cms": "<2.0.7", + "elgg/elgg": "<3.3.24|>=4,<4.0.5", + "elijaa/phpmemcacheadmin": "<=1.3", + "elmsln/haxcms": "<11.0.14", + "encore/laravel-admin": "<=1.8.19", + "endroid/qr-code-bundle": "<3.4.2", + "enhavo/enhavo-app": "<=0.13.1", + "enshrined/svg-sanitize": "<0.22", + "erusev/parsedown": "<1.7.2", + "ether/logs": "<3.0.4", + "evolutioncms/evolution": "<=3.2.3", + "exceedone/exment": "<4.4.3|>=5,<5.0.3", + "exceedone/laravel-admin": "<2.2.3|==3", + "ezsystems/demobundle": ">=5.4,<5.4.6.1-dev", + "ezsystems/ez-support-tools": ">=2.2,<2.2.3", + "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev", + "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev", + "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24", + "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.39|>=3.3,<3.3.39", + "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1|>=5.3.0.0-beta1,<5.3.5", + "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12", + "ezsystems/ezplatform-http-cache": "<2.3.16", + "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35", + "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", + "ezsystems/ezplatform-richtext": ">=2.3,<2.3.26|>=3.3,<3.3.40", + "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15", + "ezsystems/ezplatform-user": ">=1,<1.0.1", + "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31", + "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.03.5.1", + "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", + "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", + "ezyang/htmlpurifier": "<=4.2", + "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", + "facturascripts/facturascripts": "<=2022.08", + "fastly/magento2": "<1.2.26", + "feehi/cms": "<=2.1.1", + "feehi/feehicms": "<=2.1.1", + "fenom/fenom": "<=2.12.1", + "filament/actions": ">=3.2,<3.2.123", + "filament/infolists": ">=3,<3.2.115", + "filament/tables": ">=3,<3.2.115", + "filegator/filegator": "<7.8", + "filp/whoops": "<2.1.13", + "fineuploader/php-traditional-server": "<=1.2.2", + "firebase/php-jwt": "<6", + "fisharebest/webtrees": "<=2.1.18", + "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", + "fixpunkt/fp-newsletter": "<1.1.1|>=1.2,<2.1.2|>=2.2,<3.2.6", + "flarum/core": "<1.8.10", + "flarum/flarum": "<0.1.0.0-beta8", + "flarum/framework": "<1.8.10", + "flarum/mentions": "<1.6.3", + "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15", + "flarum/tags": "<=0.1.0.0-beta13", + "floriangaerber/magnesium": "<0.3.1", + "fluidtypo3/vhs": "<5.1.1", + "fof/byobu": ">=0.3.0.0-beta2,<1.1.7", + "fof/upload": "<1.2.3", + "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1", + "fooman/tcpdf": "<6.2.22", + "forkcms/forkcms": "<5.11.1", + "fossar/tcpdf-parser": "<6.2.22", + "francoisjacquet/rosariosis": "<=11.5.1", + "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2", + "friendsofsymfony/oauth2-php": "<1.3", + "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", + "friendsofsymfony/user-bundle": ">=1,<1.3.5", + "friendsofsymfony1/swiftmailer": ">=4,<5.4.13|>=6,<6.2.5", + "friendsofsymfony1/symfony1": ">=1.1,<1.5.19", + "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", + "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", + "froala/wysiwyg-editor": "<=4.3", + "froxlor/froxlor": "<=2.2.5", + "frozennode/administrator": "<=5.0.12", + "fuel/core": "<1.8.1", + "funadmin/funadmin": "<=5.0.2", + "gaoming13/wechat-php-sdk": "<=1.10.2", + "genix/cms": "<=1.1.11", + "georgringer/news": "<1.3.3", + "geshi/geshi": "<=1.0.9.1", + "getformwork/formwork": "<1.13.1|>=2.0.0.0-beta1,<2.0.0.0-beta4", + "getgrav/grav": "<1.7.46", + "getkirby/cms": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", + "getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", + "getkirby/panel": "<2.5.14", + "getkirby/starterkit": "<=3.7.0.2", + "gilacms/gila": "<=1.15.4", + "gleez/cms": "<=1.3|==2", + "globalpayments/php-sdk": "<2", + "goalgorilla/open_social": "<12.3.11|>=12.4,<12.4.10|>=13.0.0.0-alpha1,<13.0.0.0-alpha11", + "gogentooss/samlbase": "<1.2.7", + "google/protobuf": "<3.4", + "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", + "gp247/core": "<1.1.24", + "gree/jose": "<2.2.1", + "gregwar/rst": "<1.0.3", + "grumpydictator/firefly-iii": "<6.1.17", + "gugoan/economizzer": "<=0.9.0.0-beta1", + "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", + "guzzlehttp/oauth-subscriber": "<0.8.1", + "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", + "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2", + "handcraftedinthealps/goodby-csv": "<1.4.3", + "harvesthq/chosen": "<1.8.7", + "helloxz/imgurl": "<=2.31", + "hhxsv5/laravel-s": "<3.7.36", + "hillelcoren/invoice-ninja": "<5.3.35", + "himiklab/yii2-jqgrid-widget": "<1.0.8", + "hjue/justwriting": "<=1", + "hov/jobfair": "<1.0.13|>=2,<2.0.2", + "httpsoft/http-message": "<1.0.12", + "hyn/multi-tenant": ">=5.6,<5.7.2", + "ibexa/admin-ui": ">=4.2,<4.2.3|>=4.6,<4.6.25|>=5,<5.0.3", + "ibexa/admin-ui-assets": ">=4.6.0.0-alpha1,<4.6.21", + "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2", + "ibexa/fieldtype-richtext": ">=4.6,<4.6.25|>=5,<5.0.3", + "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", + "ibexa/http-cache": ">=4.6,<4.6.14", + "ibexa/post-install": "<1.0.16|>=4.6,<4.6.14", + "ibexa/solr": ">=4.5,<4.5.4", + "ibexa/user": ">=4,<4.4.3|>=5,<5.0.3", + "icecoder/icecoder": "<=8.1", + "idno/known": "<=1.3.1", + "ilicmiljan/secure-props": ">=1.2,<1.2.2", + "illuminate/auth": "<5.5.10", + "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<6.18.31|>=7,<7.22.4", + "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40", + "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", + "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75", + "imdbphp/imdbphp": "<=5.1.1", + "impresscms/impresscms": "<=1.4.5", + "impresspages/impresspages": "<1.0.13", + "in2code/femanager": "<6.4.2|>=7,<7.5.3|>=8,<8.3.1", + "in2code/ipandlanguageredirect": "<5.1.2", + "in2code/lux": "<17.6.1|>=18,<24.0.2", + "in2code/powermail": "<7.5.1|>=8,<8.5.1|>=9,<10.9.1|>=11,<12.5.3|==13", + "innologi/typo3-appointments": "<2.0.6", + "intelliants/subrion": "<4.2.2", + "inter-mediator/inter-mediator": "==5.5", + "ipl/web": "<0.10.1", + "islandora/crayfish": "<4.1", + "islandora/islandora": ">=2,<2.4.1", + "ivankristianto/phpwhois": "<=4.3", + "jackalope/jackalope-doctrine-dbal": "<1.7.4", + "jambagecom/div2007": "<0.10.2", + "james-heinrich/getid3": "<1.9.21", + "james-heinrich/phpthumb": "<=1.7.23", + "jasig/phpcas": "<1.3.3", + "jbartels/wec-map": "<3.0.3", + "jcbrand/converse.js": "<3.3.3", + "joelbutcher/socialstream": "<5.6|>=6,<6.2", + "johnbillion/wp-crontrol": "<1.16.2|>=1.17,<1.19.2", + "joomla/application": "<1.0.13", + "joomla/archive": "<1.1.12|>=2,<2.0.1", + "joomla/database": ">=1,<2.2|>=3,<3.4", + "joomla/filesystem": "<1.6.2|>=2,<2.0.1", + "joomla/filter": "<2.0.6|>=3,<3.0.5|==4", + "joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12", + "joomla/input": ">=2,<2.0.2", + "joomla/joomla-cms": "<3.9.12|>=4,<4.4.13|>=5,<5.2.6", + "joomla/joomla-platform": "<1.5.4", + "joomla/session": "<1.3.1", + "joyqi/hyper-down": "<=2.4.27", + "jsdecena/laracom": "<2.0.9", + "jsmitty12/phpwhois": "<5.1", + "juzaweb/cms": "<=3.4.2", + "jweiland/events2": "<8.3.8|>=9,<9.0.6", + "jweiland/kk-downloader": "<1.2.2", + "kazist/phpwhois": "<=4.2.6", + "kelvinmo/simplexrd": "<3.1.1", + "kevinpapst/kimai2": "<1.16.7", + "khodakhah/nodcms": "<=3", + "kimai/kimai": "<=2.20.1", + "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", + "klaviyo/magento2-extension": ">=1,<3", + "knplabs/knp-snappy": "<=1.4.2", + "kohana/core": "<3.3.3", + "koillection/koillection": "<1.6.12", + "krayin/laravel-crm": "<=1.3", + "kreait/firebase-php": ">=3.2,<3.8.1", + "kumbiaphp/kumbiapp": "<=1.1.1", + "la-haute-societe/tcpdf": "<6.2.22", + "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2", + "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1", + "laminas/laminas-http": "<2.14.2", + "lara-zeus/artemis": ">=1,<=1.0.6", + "lara-zeus/dynamic-dashboard": ">=3,<=3.0.1", + "laravel/fortify": "<1.11.1", + "laravel/framework": "<10.48.29|>=11,<11.44.1|>=12,<12.1.1", + "laravel/laravel": ">=5.4,<5.4.22", + "laravel/pulse": "<1.3.1", + "laravel/reverb": "<1.4", + "laravel/socialite": ">=1,<2.0.10", + "latte/latte": "<2.10.8", + "lavalite/cms": "<=9|==10.1", + "lavitto/typo3-form-to-database": "<2.2.5|>=3,<3.2.2|>=4,<4.2.3|>=5,<5.0.2", + "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", + "league/commonmark": "<2.7", + "league/flysystem": "<1.1.4|>=2,<2.1.1", + "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", + "leantime/leantime": "<3.3", + "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", + "libreform/libreform": ">=2,<=2.0.8", + "librenms/librenms": "<2017.08.18", + "liftkit/database": "<2.13.2", + "lightsaml/lightsaml": "<1.3.5", + "limesurvey/limesurvey": "<6.5.12", + "livehelperchat/livehelperchat": "<=3.91", + "livewire/livewire": "<2.12.7|>=3.0.0.0-beta1,<3.6.4", + "livewire/volt": "<1.7", + "lms/routes": "<2.1.1", + "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", + "lomkit/laravel-rest-api": "<2.13", + "luracast/restler": "<3.1", + "luyadev/yii-helpers": "<1.2.1", + "macropay-solutions/laravel-crud-wizard-free": "<3.4.17", + "maestroerror/php-heic-to-jpg": "<1.0.5", + "magento/community-edition": "<2.4.6.0-patch13|>=2.4.7.0-beta1,<2.4.7.0-patch8|>=2.4.8.0-beta1,<2.4.8.0-patch3|>=2.4.9.0-alpha1,<2.4.9.0-alpha3|==2.4.9", + "magento/core": "<=1.9.4.5", + "magento/magento1ce": "<1.9.4.3-dev", + "magento/magento1ee": ">=1,<1.14.4.3-dev", + "magento/product-community-edition": "<2.4.4.0-patch9|>=2.4.5,<2.4.5.0-patch8|>=2.4.6,<2.4.6.0-patch6|>=2.4.7,<2.4.7.0-patch1", + "magento/project-community-edition": "<=2.0.2", + "magneto/core": "<1.9.4.4-dev", + "mahocommerce/maho": "<25.9", + "maikuolan/phpmussel": ">=1,<1.6", + "mainwp/mainwp": "<=4.4.3.3", + "manogi/nova-tiptap": "<=3.2.6", + "mantisbt/mantisbt": "<=2.26.3", + "marcwillmann/turn": "<0.3.3", + "marshmallow/nova-tiptap": "<5.7", + "matomo/matomo": "<1.11", + "matyhtf/framework": "<3.0.6", + "mautic/core": "<5.2.8|>=6.0.0.0-alpha,<6.0.5", + "mautic/core-lib": ">=1.0.0.0-beta,<4.4.13|>=5.0.0.0-alpha,<5.1.1", + "maximebf/debugbar": "<1.19", + "mdanter/ecc": "<2", + "mediawiki/abuse-filter": "<1.39.9|>=1.40,<1.41.3|>=1.42,<1.42.2", + "mediawiki/cargo": "<3.8.3", + "mediawiki/core": "<1.39.5|==1.40", + "mediawiki/data-transfer": ">=1.39,<1.39.11|>=1.41,<1.41.3|>=1.42,<1.42.2", + "mediawiki/matomo": "<2.4.3", + "mediawiki/semantic-media-wiki": "<4.0.2", + "mehrwert/phpmyadmin": "<3.2", + "melisplatform/melis-asset-manager": "<5.0.1", + "melisplatform/melis-cms": "<5.3.4", + "melisplatform/melis-cms-slider": "<5.3.1", + "melisplatform/melis-core": "<5.3.11", + "melisplatform/melis-front": "<5.0.1", + "mezzio/mezzio-swoole": "<3.7|>=4,<4.3", + "mgallegos/laravel-jqgrid": "<=1.3", + "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1", + "microsoft/microsoft-graph-beta": "<2.0.1", + "microsoft/microsoft-graph-core": "<2.0.2", + "microweber/microweber": "<=2.0.19", + "mikehaertl/php-shellcommand": "<1.6.1", + "miniorange/miniorange-saml": "<1.4.3", + "mittwald/typo3_forum": "<1.2.1", + "mobiledetect/mobiledetectlib": "<2.8.32", + "modx/revolution": "<=3.1", + "mojo42/jirafeau": "<4.4", + "mongodb/mongodb": ">=1,<1.9.2", + "monolog/monolog": ">=1.8,<1.12", + "moodle/moodle": "<4.3.12|>=4.4,<4.4.8|>=4.5.0.0-beta,<4.5.4", + "moonshine/moonshine": "<=3.12.5", + "mos/cimage": "<0.7.19", + "movim/moxl": ">=0.8,<=0.10", + "movingbytes/social-network": "<=1.2.1", + "mpdf/mpdf": "<=7.1.7", + "munkireport/comment": "<4.1", + "munkireport/managedinstalls": "<2.6", + "munkireport/munki_facts": "<1.5", + "munkireport/munkireport": ">=2.5.3,<5.6.3", + "munkireport/reportdata": "<3.5", + "munkireport/softwareupdate": "<1.6", + "mustache/mustache": ">=2,<2.14.1", + "mwdelaney/wp-enable-svg": "<=0.2", + "namshi/jose": "<2.2", + "nasirkhan/laravel-starter": "<11.11", + "nategood/httpful": "<1", + "neoan3-apps/template": "<1.1.1", + "neorazorx/facturascripts": "<2022.04", + "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", + "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3", + "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9", + "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", + "neos/swiftmailer": "<5.4.5", + "nesbot/carbon": "<2.72.6|>=3,<3.8.4", + "netcarver/textile": "<=4.1.2", + "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", + "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", + "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", + "nilsteampassnet/teampass": "<3.1.3.1-dev", + "nitsan/ns-backup": "<13.0.1", + "nonfiction/nterchange": "<4.1.1", + "notrinos/notrinos-erp": "<=0.7", + "noumo/easyii": "<=0.9", + "novaksolutions/infusionsoft-php-sdk": "<1", + "novosga/novosga": "<=2.2.12", + "nukeviet/nukeviet": "<4.5.02", + "nyholm/psr7": "<1.6.1", + "nystudio107/craft-seomatic": "<3.4.12", + "nzedb/nzedb": "<0.8", + "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", + "october/backend": "<1.1.2", + "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", + "october/october": "<3.7.5", + "october/rain": "<1.0.472|>=1.1,<1.1.2", + "october/system": "<3.7.5", + "oliverklee/phpunit": "<3.5.15", + "omeka/omeka-s": "<4.0.3", + "onelogin/php-saml": "<2.10.4", + "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5", + "open-web-analytics/open-web-analytics": "<1.8.1", + "opencart/opencart": ">=0", + "openid/php-openid": "<2.3", + "openmage/magento-lts": "<20.12.3", + "opensolutions/vimbadmin": "<=3.0.15", + "opensource-workshop/connect-cms": "<1.8.7|>=2,<2.4.7", + "orchid/platform": ">=8,<14.43", + "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1", + "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1", + "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7", + "oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1", + "oro/customer-portal": ">=4.1,<=4.1.13|>=4.2,<=4.2.10|>=5,<=5.0.11|>=5.1,<=5.1.3", + "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<=5.0.12|>=5.1,<=5.1.3", + "oveleon/contao-cookiebar": "<1.16.3|>=2,<2.1.3", + "oxid-esales/oxideshop-ce": "<=7.0.5", + "oxid-esales/paymorrow-module": ">=1,<1.0.2|>=2,<2.0.1", + "packbackbooks/lti-1-3-php-library": "<5", + "padraic/humbug_get_contents": "<1.1.2", + "pagarme/pagarme-php": "<3", + "pagekit/pagekit": "<=1.0.18", + "paragonie/ecc": "<2.0.1", + "paragonie/random_compat": "<2", + "passbolt/passbolt_api": "<4.6.2", + "paypal/adaptivepayments-sdk-php": "<=3.9.2", + "paypal/invoice-sdk-php": "<=3.9", + "paypal/merchant-sdk-php": "<3.12", + "paypal/permissions-sdk-php": "<=3.9.1", + "pear/archive_tar": "<1.4.14", + "pear/auth": "<1.2.4", + "pear/crypt_gpg": "<1.6.7", + "pear/http_request2": "<2.7", + "pear/pear": "<=1.10.1", + "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1", + "personnummer/personnummer": "<3.0.2", + "phanan/koel": "<5.1.4", + "phenx/php-svg-lib": "<0.5.2", + "php-censor/php-censor": "<2.0.13|>=2.1,<2.1.5", + "php-mod/curl": "<2.3.2", + "phpbb/phpbb": "<3.3.11", + "phpems/phpems": ">=6,<=6.1.3", + "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7", + "phpmailer/phpmailer": "<6.5", + "phpmussel/phpmussel": ">=1,<1.6", + "phpmyadmin/phpmyadmin": "<5.2.2", + "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5|>=3.2.10,<=4.0.1", + "phpoffice/common": "<0.2.9", + "phpoffice/math": "<=0.2", + "phpoffice/phpexcel": "<=1.8.2", + "phpoffice/phpspreadsheet": "<1.30|>=2,<2.1.12|>=2.2,<2.4|>=3,<3.10|>=4,<5", + "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", + "phpservermon/phpservermon": "<3.6", + "phpsysinfo/phpsysinfo": "<3.4.3", + "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", + "phpwhois/phpwhois": "<=4.2.5", + "phpxmlrpc/extras": "<0.6.1", + "phpxmlrpc/phpxmlrpc": "<4.9.2", + "pi/pi": "<=2.5", + "pimcore/admin-ui-classic-bundle": "<1.7.6", + "pimcore/customer-management-framework-bundle": "<4.2.1", + "pimcore/data-hub": "<1.2.4", + "pimcore/data-importer": "<1.8.9|>=1.9,<1.9.3", + "pimcore/demo": "<10.3", + "pimcore/ecommerce-framework-bundle": "<1.0.10", + "pimcore/perspective-editor": "<1.5.1", + "pimcore/pimcore": "<11.5.4", + "piwik/piwik": "<1.11", + "pixelfed/pixelfed": "<0.12.5", + "plotly/plotly.js": "<2.25.2", + "pocketmine/bedrock-protocol": "<8.0.2", + "pocketmine/pocketmine-mp": "<5.32.1", + "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1", + "pressbooks/pressbooks": "<5.18", + "prestashop/autoupgrade": ">=4,<4.10.1", + "prestashop/blockreassurance": "<=5.1.3", + "prestashop/blockwishlist": ">=2,<2.1.1", + "prestashop/contactform": ">=1.0.1,<4.3", + "prestashop/gamification": "<2.3.2", + "prestashop/prestashop": "<8.2.3", + "prestashop/productcomments": "<5.0.2", + "prestashop/ps_checkout": "<4.4.1|>=5,<5.0.5", + "prestashop/ps_contactinfo": "<=3.3.2", + "prestashop/ps_emailsubscription": "<2.6.1", + "prestashop/ps_facetedsearch": "<3.4.1", + "prestashop/ps_linklist": "<3.1", + "privatebin/privatebin": "<1.4|>=1.5,<1.7.4", + "processwire/processwire": "<=3.0.246", + "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", + "propel/propel1": ">=1,<=1.7.1", + "pterodactyl/panel": "<=1.11.10", + "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", + "ptrofimov/beanstalk_console": "<1.7.14", + "pubnub/pubnub": "<6.1", + "punktde/pt_extbase": "<1.5.1", + "pusher/pusher-php-server": "<2.2.1", + "pwweb/laravel-core": "<=0.3.6.0-beta", + "pxlrbt/filament-excel": "<1.1.14|>=2.0.0.0-alpha,<2.3.3", + "pyrocms/pyrocms": "<=3.9.1", + "qcubed/qcubed": "<=3.1.1", + "quickapps/cms": "<=2.0.0.0-beta2", + "rainlab/blog-plugin": "<1.4.1", + "rainlab/debugbar-plugin": "<3.1", + "rainlab/user-plugin": "<=1.4.5", + "rankmath/seo-by-rank-math": "<=1.0.95", + "rap2hpoutre/laravel-log-viewer": "<0.13", + "react/http": ">=0.7,<1.9", + "really-simple-plugins/complianz-gdpr": "<6.4.2", + "redaxo/source": "<5.18.3", + "remdex/livehelperchat": "<4.29", + "renolit/reint-downloadmanager": "<4.0.2|>=5,<5.0.1", + "reportico-web/reportico": "<=8.1", + "rhukster/dom-sanitizer": "<1.0.7", + "rmccue/requests": ">=1.6,<1.8", + "robrichards/xmlseclibs": ">=1,<3.0.4", + "roots/soil": "<4.1", + "roundcube/roundcubemail": "<1.5.10|>=1.6,<1.6.11", + "rudloff/alltube": "<3.0.3", + "rudloff/rtmpdump-bin": "<=2.3.1", + "s-cart/core": "<=9.0.5", + "s-cart/s-cart": "<6.9", + "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", + "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9", + "samwilson/unlinked-wikibase": "<1.42", + "scheb/two-factor-bundle": "<3.26|>=4,<4.11", + "sensiolabs/connect": "<4.2.3", + "serluck/phpwhois": "<=4.2.6", + "setasign/fpdi": "<2.6.4", + "sfroemken/url_redirect": "<=1.2.1", + "sheng/yiicms": "<1.2.1", + "shopware/core": "<6.6.10.7-dev|>=6.7,<6.7.3.1-dev", + "shopware/platform": "<6.6.10.7-dev|>=6.7,<6.7.3.1-dev", + "shopware/production": "<=6.3.5.2", + "shopware/shopware": "<=5.7.17|>=6.7,<6.7.2.1-dev", + "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", + "shopxo/shopxo": "<=6.4", + "showdoc/showdoc": "<2.10.4", + "shuchkin/simplexlsx": ">=1.0.12,<1.1.13", + "silverstripe-australia/advancedreports": ">=1,<=2", + "silverstripe/admin": "<1.13.19|>=2,<2.1.8", + "silverstripe/assets": ">=1,<1.11.1", + "silverstripe/cms": "<4.11.3", + "silverstripe/comments": ">=1.3,<3.1.1", + "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", + "silverstripe/framework": "<5.3.23", + "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3", + "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", + "silverstripe/recipe-cms": ">=4.5,<4.5.3", + "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", + "silverstripe/reports": "<5.2.3", + "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4|>=2.1,<2.1.2", + "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1", + "silverstripe/subsites": ">=2,<2.6.1", + "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", + "silverstripe/userforms": "<3|>=5,<5.4.2", + "silverstripe/versioned-admin": ">=1,<1.11.1", + "simogeo/filemanager": "<=2.5", + "simple-updates/phpwhois": "<=1", + "simplesamlphp/saml2": "<=4.16.15|>=5.0.0.0-alpha1,<=5.0.0.0-alpha19", + "simplesamlphp/saml2-legacy": "<=4.16.15", + "simplesamlphp/simplesamlphp": "<1.18.6", + "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", + "simplesamlphp/simplesamlphp-module-openid": "<1", + "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", + "simplesamlphp/xml-common": "<1.20", + "simplesamlphp/xml-security": "==1.6.11", + "simplito/elliptic-php": "<1.0.6", + "sitegeist/fluid-components": "<3.5", + "sjbr/sr-feuser-register": "<2.6.2|>=5.1,<12.5", + "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3", + "sjbr/static-info-tables": "<2.3.1", + "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1", + "slim/slim": "<2.6", + "slub/slub-events": "<3.0.3", + "smarty/smarty": "<4.5.3|>=5,<5.1.1", + "snipe/snipe-it": "<8.1.18", + "socalnick/scn-social-auth": "<1.15.2", + "socialiteproviders/steam": "<1.1", + "solspace/craft-freeform": ">=5,<5.10.16", + "soosyze/soosyze": "<=2", + "spatie/browsershot": "<5.0.5", + "spatie/image-optimizer": "<1.7.3", + "spencer14420/sp-php-email-handler": "<1", + "spipu/html2pdf": "<5.2.8", + "spoon/library": "<1.4.1", + "spoonity/tcpdf": "<6.2.22", + "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", + "ssddanbrown/bookstack": "<24.05.1", + "starcitizentools/citizen-skin": ">=1.9.4,<3.9", + "starcitizentools/short-description": ">=4,<4.0.1", + "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1", + "starcitizenwiki/embedvideo": "<=4", + "statamic/cms": "<=5.16", + "stormpath/sdk": "<9.9.99", + "studio-42/elfinder": "<=2.1.64", + "studiomitte/friendlycaptcha": "<0.1.4", + "subhh/libconnect": "<7.0.8|>=8,<8.1", + "sukohi/surpass": "<1", + "sulu/form-bundle": ">=2,<2.5.3", + "sulu/sulu": "<1.6.44|>=2,<2.5.25|>=2.6,<2.6.9|>=3.0.0.0-alpha1,<3.0.0.0-alpha3", + "sumocoders/framework-user-bundle": "<1.4", + "superbig/craft-audit": "<3.0.2", + "svewap/a21glossary": "<=0.4.10", + "swag/paypal": "<5.4.4", + "swiftmailer/swiftmailer": "<6.2.5", + "swiftyedit/swiftyedit": "<1.2", + "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", + "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", + "sylius/grid-bundle": "<1.10.1", + "sylius/paypal-plugin": "<1.6.2|>=1.7,<1.7.2|>=2,<2.0.2", + "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", + "sylius/sylius": "<1.12.19|>=1.13.0.0-alpha1,<1.13.4", + "symbiote/silverstripe-multivaluefield": ">=3,<3.1", + "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4", + "symbiote/silverstripe-seed": "<6.0.3", + "symbiote/silverstripe-versionedfiles": "<=2.0.3", + "symfont/process": ">=0", + "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", + "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", + "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", + "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4", + "symfony/http-client": ">=4.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", + "symfony/http-foundation": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", + "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1", + "symfony/mime": ">=4.3,<4.3.8", + "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/polyfill": ">=1,<1.10", + "symfony/polyfill-php55": ">=1,<1.10", + "symfony/process": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/routing": ">=2,<2.0.19", + "symfony/runtime": ">=5.3,<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8", + "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.4.10|>=7,<7.0.10|>=7.1,<7.1.3", + "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", + "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", + "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", + "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", + "symfony/symfony": "<5.4.47|>=6,<6.4.15|>=7,<7.1.8", + "symfony/translation": ">=2,<2.0.17", + "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", + "symfony/ux-autocomplete": "<2.11.2", + "symfony/ux-live-component": "<2.25.1", + "symfony/ux-twig-component": "<2.25.1", + "symfony/validator": "<5.4.43|>=6,<6.4.11|>=7,<7.1.4", + "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", + "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", + "symfony/webhook": ">=6.3,<6.3.8", + "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7|>=2.2.0.0-beta1,<2.2.0.0-beta2", + "symphonycms/symphony-2": "<2.6.4", + "t3/dce": "<0.11.5|>=2.2,<2.6.2", + "t3g/svg-sanitizer": "<1.0.3", + "t3s/content-consent": "<1.0.3|>=2,<2.0.2", + "tastyigniter/tastyigniter": "<4", + "tcg/voyager": "<=1.8", + "tecnickcom/tc-lib-pdf-font": "<2.6.4", + "tecnickcom/tcpdf": "<6.8", + "terminal42/contao-tablelookupwizard": "<3.3.5", + "thelia/backoffice-default-template": ">=2.1,<2.1.2", + "thelia/thelia": ">=2.1,<2.1.3", + "theonedemon/phpwhois": "<=4.2.5", + "thinkcmf/thinkcmf": "<6.0.8", + "thorsten/phpmyfaq": "<=4.0.1|>=4.0.7,<4.0.13", + "tikiwiki/tiki-manager": "<=17.1", + "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", + "tinymce/tinymce": "<7.2", + "tinymighty/wiki-seo": "<1.2.2", + "titon/framework": "<9.9.99", + "tltneon/lgsl": "<7", + "tobiasbg/tablepress": "<=2.0.0.0-RC1", + "topthink/framework": "<6.0.17|>=6.1,<=8.0.4", + "topthink/think": "<=6.1.1", + "topthink/thinkphp": "<=3.2.3|>=6.1.3,<=8.0.4", + "torrentpier/torrentpier": "<=2.4.3", + "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", + "tribalsystems/zenario": "<=9.7.61188", + "truckersmp/phpwhois": "<=4.3.1", + "ttskch/pagination-service-provider": "<1", + "twbs/bootstrap": "<3.4.1|>=4,<4.3.1", + "twig/twig": "<3.11.2|>=3.12,<3.14.1|>=3.16,<3.19", + "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", + "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-belog": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-beuser": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-core": "<=8.7.56|>=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-dashboard": ">=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1", + "typo3/cms-extensionmanager": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-felogin": ">=4.2,<4.2.3", + "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1", + "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5", + "typo3/cms-indexed-search": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8|==13.4.2", + "typo3/cms-lowlevel": ">=11,<=11.5.41", + "typo3/cms-recordlist": ">=11,<11.5.48", + "typo3/cms-recycler": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30", + "typo3/cms-scheduler": ">=11,<=11.5.41", + "typo3/cms-setup": ">=9,<=9.5.50|>=10,<=10.4.49|>=11,<=11.5.43|>=12,<=12.4.30|>=13,<=13.4.11", + "typo3/cms-webhooks": ">=12,<=12.4.30|>=13,<=13.4.11", + "typo3/cms-workspaces": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", + "typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3", + "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", + "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", + "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", + "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10", + "ua-parser/uap-php": "<3.8", + "uasoft-indonesia/badaso": "<=2.9.7", + "unisharp/laravel-filemanager": "<2.9.1", + "universal-omega/dynamic-page-list3": "<3.6.4", + "unopim/unopim": "<=0.3", + "userfrosting/userfrosting": ">=0.3.1,<4.6.3", + "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", + "uvdesk/community-skeleton": "<=1.1.1", + "uvdesk/core-framework": "<=1.1.1", + "vanilla/safecurl": "<0.9.2", + "verbb/comments": "<1.5.5", + "verbb/formie": "<=2.1.43", + "verbb/image-resizer": "<2.0.9", + "verbb/knock-knock": "<1.2.8", + "verot/class.upload.php": "<=2.1.6", + "vertexvaar/falsftp": "<0.2.6", + "villagedefrance/opencart-overclocked": "<=1.11.1", + "vova07/yii2-fileapi-widget": "<0.1.9", + "vrana/adminer": "<=4.8.1", + "vufind/vufind": ">=2,<9.1.1", + "waldhacker/hcaptcha": "<2.1.2", + "wallabag/tcpdf": "<6.2.22", + "wallabag/wallabag": "<2.6.11", + "wanglelecc/laracms": "<=1.0.3", + "wapplersystems/a21glossary": "<=0.4.10", + "web-auth/webauthn-framework": ">=3.3,<3.3.4|>=4.5,<4.9", + "web-auth/webauthn-lib": ">=4.5,<4.9", + "web-feet/coastercms": "==5.5", + "web-tp3/wec_map": "<3.0.3", + "webbuilders-group/silverstripe-kapost-bridge": "<0.4", + "webcoast/deferred-image-processing": "<1.0.2", + "webklex/laravel-imap": "<5.3", + "webklex/php-imap": "<5.3", + "webpa/webpa": "<3.1.2", + "webreinvent/vaahcms": "<=2.3.1", + "wikibase/wikibase": "<=1.39.3", + "wikimedia/parsoid": "<0.12.2", + "willdurand/js-translation-bundle": "<2.1.1", + "winter/wn-backend-module": "<1.2.4", + "winter/wn-cms-module": "<1.0.476|>=1.1,<1.1.11|>=1.2,<1.2.7", + "winter/wn-dusk-plugin": "<2.1", + "winter/wn-system-module": "<1.2.4", + "wintercms/winter": "<=1.2.3", + "wireui/wireui": "<1.19.3|>=2,<2.1.3", + "woocommerce/woocommerce": "<6.6|>=8.8,<8.8.5|>=8.9,<8.9.3", + "wp-cli/wp-cli": ">=0.12,<2.5", + "wp-graphql/wp-graphql": "<=1.14.5", + "wp-premium/gravityforms": "<2.4.21", + "wpanel/wpanel4-cms": "<=4.3.1", + "wpcloud/wp-stateless": "<3.2", + "wpglobus/wpglobus": "<=1.9.6", + "wwbn/avideo": "<14.3", + "xataface/xataface": "<3", + "xpressengine/xpressengine": "<3.0.15", + "yab/quarx": "<2.4.5", + "yeswiki/yeswiki": "<=4.5.4", + "yetiforce/yetiforce-crm": "<6.5", + "yidashi/yii2cmf": "<=2", + "yii2mod/yii2-cms": "<1.9.2", + "yiisoft/yii": "<1.1.31", + "yiisoft/yii2": "<2.0.52", + "yiisoft/yii2-authclient": "<2.2.15", + "yiisoft/yii2-bootstrap": "<2.0.4", + "yiisoft/yii2-dev": "<=2.0.45", + "yiisoft/yii2-elasticsearch": "<2.0.5", + "yiisoft/yii2-gii": "<=2.2.4", + "yiisoft/yii2-jui": "<2.0.4", + "yiisoft/yii2-redis": "<2.0.20", + "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6", + "yoast-seo-for-typo3/yoast_seo": "<7.2.3", + "yourls/yourls": "<=1.8.2", + "yuan1994/tpadmin": "<=1.3.12", + "z-push/z-push-dev": "<2.7.6", + "zencart/zencart": "<=1.5.7.0-beta", + "zendesk/zendesk_api_client_php": "<2.2.11", + "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", + "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-db": "<2.2.10|>=2.3,<2.3.5", + "zendframework/zend-developer-tools": ">=1.2.2,<1.2.3", + "zendframework/zend-diactoros": "<1.8.4", + "zendframework/zend-feed": "<2.10.3", + "zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-http": "<2.8.1", + "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", + "zendframework/zend-mail": "<2.4.11|>=2.5,<2.7.2", + "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-session": ">=2,<2.2.9|>=2.3,<2.3.4", + "zendframework/zend-validator": ">=2.3,<2.3.6", + "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zendframework": "<=3", + "zendframework/zendframework1": "<1.12.20", + "zendframework/zendopenid": "<2.0.2", + "zendframework/zendrest": "<2.0.2", + "zendframework/zendservice-amazon": "<2.0.3", + "zendframework/zendservice-api": "<1", + "zendframework/zendservice-audioscrobbler": "<2.0.2", + "zendframework/zendservice-nirvanix": "<2.0.2", + "zendframework/zendservice-slideshare": "<2.0.2", + "zendframework/zendservice-technorati": "<2.0.2", + "zendframework/zendservice-windowsazure": "<2.0.2", + "zendframework/zendxml": ">=1,<1.0.1", + "zenstruck/collection": "<0.2.1", + "zetacomponents/mail": "<1.8.2", + "zf-commons/zfc-user": "<1.2.2", + "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", + "zfr/zfr-oauth2-server-module": "<0.1.2", + "zoujingli/thinkadmin": "<=6.1.53" + }, + "default-branch": true, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "role": "maintainer" + }, + { + "name": "Ilya Tribusean", + "email": "slash3b@gmail.com", + "role": "maintainer" + } + ], + "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", + "keywords": [ + "dev" + ], + "support": { + "issues": "https://github.com/Roave/SecurityAdvisories/issues", + "source": "https://github.com/Roave/SecurityAdvisories/tree/latest" + }, + "funding": [ + { + "url": "https://github.com/Ocramius", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/roave/security-advisories", + "type": "tidelift" + } + ], + "time": "2025-10-21T21:05:51+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/90f41072d220e5c40df6e8635f5dafba2d9d4d04", + "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/cli-parser", + "type": "tidelift" + } + ], + "time": "2025-09-14T09:36:45+00:00" + }, + { + "name": "sebastian/comparator", + "version": "7.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "dc904b4bb3ab070865fa4068cd84f3da8b945148" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dc904b4bb3ab070865fa4068cd84f3da8b945148", + "reference": "dc904b4bb3ab070865fa4068cd84f3da8b945148", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.2" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2025-08-20T11:27:00+00:00" + }, + { + "name": "sebastian/complexity", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:46+00:00" + }, + { + "name": "sebastian/environment", + "version": "8.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/24a711b5c916efc6d6e62aa65aa2ec98fef77f68", + "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/8.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2025-08-12T14:11:56+00:00" + }, + { + "name": "sebastian/exporter", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "016951ae10980765e4e7aee491eb288c64e505b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7", + "reference": "016951ae10980765e4e7aee491eb288c64e505b7", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:16:11+00:00" + }, + { + "name": "sebastian/global-state", + "version": "8.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "ef1377171613d09edd25b7816f05be8313f9115d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d", + "reference": "ef1377171613d09edd25b7816f05be8313f9115d", + "shasum": "" + }, + "require": { + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" + } + ], + "time": "2025-08-29T11:29:25+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:57:28+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "shasum": "" + }, + "require": { + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:57:48+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:58:17+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-13T04:44:59+00:00" + }, + { + "name": "sebastian/type", + "version": "6.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/6.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" + } + ], + "time": "2025-08-09T06:57:12+00:00" + }, + { + "name": "sebastian/version", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T05:00:38+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "symfony/console", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", + "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-22T15:31:00+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.3.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-13T11:49:31+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd", + "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-07T08:17:47+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T13:41:35+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.3.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d", + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.3.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-05T10:16:07+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T09:58:17+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php84", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-24T13:30:11+00:00" + }, + { + "name": "symfony/process", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b", + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-11T10:12:26+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-25T09:37:31+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-02-24T10:49:57+00:00" + }, + { + "name": "symfony/string", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "f96476035142921000338bad71e5247fbc138872" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", + "reference": "f96476035142921000338bad71e5247fbc138872", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-11T14:36:48+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } ], - "time": "2020-07-08T17:02:28+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "roave/security-advisories": 20 + }, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "1.1.0" + "platform": { + "php": ">=8.1", + "ext-pdo": "*" + }, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/debian/Jenkinsfile b/debian/Jenkinsfile new file mode 100644 index 0000000..89ef9f8 --- /dev/null +++ b/debian/Jenkinsfile @@ -0,0 +1,133 @@ +#!groovy + +// Aktuální verze Pipeline: https://github.com/VitexSoftware/BuildImages/blob/main/Test/Jenkinsfile-parael + +String[] distributions = [ + 'debian:bookworm', + 'debian:trixie', + 'debian:forky', + 'ubuntu:jammy', + 'ubuntu:noble' +] + +String vendor = 'vitexsoftware' +String imagePrefix = 'multiflexi-' + +properties([ + copyArtifactPermission('*') +]) + +node { + ansiColor('xterm') { + stage('SCM Checkout') { + checkout scm + } + } +} + +def branches = [:] + +distributions.each { distro -> + branches[distro] = { + def (distroFamily, distroCode) = distro.split(':') + def imageName = "${vendor}/${imagePrefix}${distroCode}:latest" + def buildImage + def artifacts = [] + def buildVer + + node { + ansiColor('xterm') { + stage("Checkout ${distro}") { + checkout scm + buildImage = docker.image(imageName) + + sh 'git checkout debian/changelog' + buildVer = sh( + script: "dpkg-parsechangelog --show-field Version", + returnStdout: true + ).trim() + ".${env.BUILD_NUMBER}~${distroCode}" + } + + stage("Build ${distro}") { + buildImage.inside { + sh """ + dch -b -v ${buildVer} "${env.BUILD_TAG}" + sudo apt-get update --allow-releaseinfo-change + sudo chown jenkins:jenkins .. + debuild-pbuilder -i -us -uc -b + mkdir -p \$WORKSPACE/dist/debian/ + rm -rf \$WORKSPACE/dist/debian/* + for deb in \$(awk '{print \$1}' debian/files); do + mv "../\$deb" \$WORKSPACE/dist/debian/ + done + """ + artifacts = sh( + script: "awk '{print \$1}' debian/files", + returnStdout: true + ).trim().split('\n') + } + } + + stage("Test ${distro}") { + buildImage.inside { + def debconf_debug = 0 + sh """ + cd \$WORKSPACE/dist/debian/ + dpkg-scanpackages . /dev/null > Packages + gzip -9c Packages > Packages.gz + cd \$WORKSPACE + echo "deb [trusted=yes] file://///\$WORKSPACE/dist/debian/ ./" | sudo tee /etc/apt/sources.list.d/local.list + sudo apt-get update --allow-releaseinfo-change + """ + artifacts.each { deb_file -> + if (deb_file.endsWith('.deb')) { + def pkgName = deb_file.tokenize('/')[-1].replaceFirst(/_.*/, '') + def distroCodename = sh( + script: "lsb_release -sc", + returnStdout: true + ).trim() + echo "Installing ${pkgName} on ${distroCodename}" + sh """ + sudo DEBIAN_FRONTEND=noninteractive DEBCONF_DEBUG=${debconf_debug} \ + apt-get -y install ${pkgName} \ + || sudo apt-get -y -f install + """ + } + } + } + } + + stage("Archive artifacts ${distro}") { + buildImage.inside { + artifacts.each { deb_file -> + println "Archiving artifact: ${deb_file}" + archiveArtifacts artifacts: "dist/debian/${deb_file}" + } + + sh ''' + set -e + if [ -f debian/files ]; then + while read -r file _; do + [ -n "$file" ] || continue + rm -f "dist/debian/$file" || true + rm -f "../$file" || true + rm -f "$WORKSPACE/$file" || true + done < debian/files + fi + ''' + } + } + + } + } + } +} + + +parallel branches + +node { + stage('Publish to Aptly') { + publishDebToAptly() + } +} diff --git a/debian/Jenkinsfile.release b/debian/Jenkinsfile.release new file mode 100644 index 0000000..450c50f --- /dev/null +++ b/debian/Jenkinsfile.release @@ -0,0 +1,117 @@ +#!groovy + +// Current version of this Pipeline https://raw.githubusercontent.com/VitexSoftware/multiflexi-buildimages/refs/heads/main/Test/multiflexi-halloworld/Jenkinsfile + +String[] distributions = ['debian:bookworm', 'debian:trixie', 'debian:forky', 'ubuntu:jammy', 'ubuntu:noble'] + +String vendor = 'vitexsoftware' +String imagePrefix = 'multiflexi-' +//String distroFamily = '' + +properties([ + copyArtifactPermission('*') +]) +node() { + ansiColor('xterm') { + stage('SCM Checkout') { + checkout scm + } + } +} + +def branches = [:] +distributions.each { distro -> + branches[distro] = { + def distroName = distro + println "Dist:" + distroName + + def dist = distroName.split(':') + def distroCode = dist[1] + def buildImage = '' + def artifacts = [] + def buildVer = '' + + node { + ansiColor('xterm') { + stage('Checkout ' + distroName) { + checkout scm + def imageName = vendor + '/' + imagePrefix + distroCode + ':latest' + buildImage = docker.image(imageName) + sh 'git checkout debian/changelog' + def version = sh ( + script: 'dpkg-parsechangelog --show-field Version', + returnStdout: true + ).trim() + buildVer = version + '.' + env.BUILD_NUMBER + '~' + distroCode + } + stage('Build ' + distroName) { + buildImage.inside { + sh 'dch -b -v ' + buildVer + ' "' + env.BUILD_TAG + '"' + sh 'sudo apt-get update --allow-releaseinfo-change' + sh 'sudo chown jenkins:jenkins ..' + sh 'debuild-pbuilder -i -us -uc -b' + sh 'mkdir -p $WORKSPACE/dist/debian/ ; rm -rf $WORKSPACE/dist/debian/* ; for deb in $(cat debian/files | awk \'{print $1}\'); do mv "../$deb" $WORKSPACE/dist/debian/; done' + artifacts = sh ( + script: "cat debian/files | awk '{print \$1}'", + returnStdout: true + ).trim().split('\n') + } + } + + stage('Test ' + distroName) { + buildImage.inside { + def debconf_debug = 0 //Set to "5" or "developer" to debug debconf + sh 'cd $WORKSPACE/dist/debian/ ; dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz; cd $WORKSPACE' + sh 'echo "deb [trusted=yes] file://///$WORKSPACE/dist/debian/ ./" | sudo tee /etc/apt/sources.list.d/local.list' + sh 'sudo apt-get update --allow-releaseinfo-change' + sh 'echo "INSTALATION"' + artifacts.each { deb_file -> + if (deb_file.endsWith('.deb')) { + sh 'echo -e "${GREEN} installing ' + deb_file + ' on `lsb_release -sc` ${ENDCOLOR} "' + sh 'sudo DEBIAN_FRONTEND=noninteractive DEBCONF_DEBUG=' + debconf_debug + ' apt-get -y install $WORKSPACE/dist/debian/' + deb_file + } + } + } + } + stage('Archive artifacts ' + distroName ) { + // Only run if previous stages (Build and Test) succeeded + buildImage.inside { + // Archive all produced artifacts listed in debian/files + artifacts.each { deb_file -> + println "Archiving artifact: " + deb_file + archiveArtifacts artifacts: 'dist/debian/' + deb_file + } + + // Cleanup: remove any produced files named in debian/files + // Try both the dist location and any potential original locations referenced by debian/files + sh ''' + set -e + if [ -f debian/files ]; then + while read -r file _; do + [ -n "$file" ] || continue + rm -f "dist/debian/$file" || true + rm -f "../$file" || true + rm -f "$WORKSPACE/$file" || true + done < debian/files + fi + ''' + } + } + } + } + } +} +parallel branches + +if (!currentBuild.result || currentBuild.result == 'SUCCESS') { + build job: 'MultiFlexi-publish', + wait: false, + parameters: [ + string(name: 'UPSTREAM_JOB', value: env.JOB_NAME), + string(name: 'UPSTREAM_BUILD', value: env.BUILD_NUMBER), + string(name: 'REMOTE_SSH', value: 'multirepo@repo.multiflexi.eu'), + string(name: 'REMOTE_REPO_DIR', value: '/srv/repo'), + string(name: 'COMPONENT', value: 'main'), + string(name: 'DEB_DIST', value: '') + ] +} diff --git a/debian/README.Debian b/debian/README.Debian new file mode 100644 index 0000000..ec29b5d --- /dev/null +++ b/debian/README.Debian @@ -0,0 +1,8 @@ +php-vitexsoftware-fluentpdo for Debian + +Please edit this to provide information specific to +this php-vitexsoftware-fluentpdo Debian package. + + (Automatically generated by debmake Version 4.5.1) + + -- Vítězslav Dvořák Tue, 21 Oct 2025 23:54:19 +0200 diff --git a/debian/README.source b/debian/README.source new file mode 100644 index 0000000..c6a982c --- /dev/null +++ b/debian/README.source @@ -0,0 +1,14 @@ +php-vitexsoftware-fluentpdo for Debian + +See Debian policy manual section 4.14. + https://www.debian.org/doc/debian-policy/ch-source.html#source-package-handling-debian-readme-source + +If running dpkg-source -x on a source package doesn’t produce the source of the +package, ready for editing, and allow one to make changes and run +dpkg-buildpackage to produce a modified package without taking any additional +steps, creating this file explain how to do all of these is recommended. +Otherwise, remove this file. + + (Automatically generated by debmake Version 4.5.1) + + -- Vítězslav Dvořák Tue, 21 Oct 2025 23:54:19 +0200 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..1de5b29 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,9 @@ +php-vitexsoftware-fluentpdo (3.0.0-1) unstable; urgency=medium + + * Initial Debian packaging of FluentPDO - PHP 8.1+ Edition + * Modernized fork of FluentPDO with strict typing and union types + * Requires PHP 8.1+ with PDO extension + * Smart join builder with automatic table joins + * Modern type declarations and enhanced features + + -- Vítězslav Dvořák Mon, 21 Oct 2024 22:18:00 +0000 diff --git a/debian/clean b/debian/clean new file mode 100644 index 0000000..4a97dfa --- /dev/null +++ b/debian/clean @@ -0,0 +1 @@ +# You must remove unused comment lines for the released package. diff --git a/debian/composer.json b/debian/composer.json new file mode 100644 index 0000000..1300db0 --- /dev/null +++ b/debian/composer.json @@ -0,0 +1,50 @@ +{ + "name": "deb/fluentpdo", + "description": "FluentPDO - PHP 8.1+ Edition. A modernized fork with strict typing, union types, and enhanced features. Quick and light PHP library for rapid query building with smart join builder.", + "type": "library", + "keywords": [ + "db", + "database", + "dbal", + "pdo", + "fluent", + "query", + "builder", + "mysql", + "oracle", + "mssql", + "php8", + "php81", + "strict-types", + "union-types", + "modern-php" + ], + "homepage": "https://github.com/VitexSoftware/php-vitexsoftware-fluentpdo", + "license": [ + "Apache-2.0", + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "envms", + "homepage": "https://env.ms" + }, + { + "name": "vitex", + "homepage": "https://vitexsoftware.com" + } + ], + "autoload": { + "psr-4": { + "Envms\\FluentPDO\\": "./", + "Envms\\FluentPDO\\QueriesPDO\\": "./Queries/" + } + }, + "require": { + "php": ">=8.1", + "ext-pdo": "*" + }, + "replace": { + "envms/fluentpdo": "^2.2" + } +} diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..7bcef08 --- /dev/null +++ b/debian/control @@ -0,0 +1,35 @@ +Source: php-vitexsoftware-fluentpdo +Section: php +Priority: optional +Maintainer: Vítězslav Dvořák +Build-Depends: + debhelper-compat (= 13), + php-cli, + composer, +Standards-Version: 4.7.0 +Homepage: https://github.com/VitexSoftware/php-vitexsoftware-fluentpdo +Rules-Requires-Root: no +Vcs-Git: https://github.com/VitexSoftware/php-vitexsoftware-fluentpdo.git +Vcs-Browser: https://github.com/VitexSoftware/php-vitexsoftware-fluentpdo + +Package: php-vitexsoftware-fluentpdo +Architecture: all +Multi-Arch: foreign +Depends: + ${misc:Depends}, + php-cli (>= 8.1), + php-pdo, +Suggests: + php-mysql | php-sqlite3 | php-pgsql, +Description: FluentPDO - PHP 8.1+ Edition with modern features + FluentPDO is a modernized PHP SQL query builder library using PDO with a smart + join builder that automatically creates table joins. This version (3.x) requires + PHP 8.1+ and includes modern type declarations, strict typing, and enhanced + features. + . + Key features: + - Smart Join Builder: Automatically creates JOINs based on column references + - Fluent Interface: Method chaining for building queries + - PDO Integration: Built on top of PDO for database portability + - Type Safety: Modern PHP 8.1+ with strict typing throughout + - Union Types: Uses modern PHP union types where appropriate diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..64c6d41 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,48 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: php-vitexsoftware-fluentpdo +Upstream-Contact: Vítězslav Dvořák +Source: https://github.com/VitexSoftware/php-vitexsoftware-fluentpdo + +Files: * +Copyright: 2024 Vítězslav Dvořák + Original FluentPDO by envms +License: Apache-2.0 or GPL-2.0+ + +Files: src/* +Copyright: 2024 Vítězslav Dvořák + Original FluentPDO by envms +License: Apache-2.0 or GPL-2.0+ + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + On Debian systems, the complete text of the Apache License 2.0 + can be found in "/usr/share/common-licenses/Apache-2.0". + +License: GPL-2.0+ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + . + On Debian systems, the complete text of the GNU General Public License + can be found in "/usr/share/common-licenses/GPL-2". \ No newline at end of file diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..522e345 --- /dev/null +++ b/debian/dirs @@ -0,0 +1,2 @@ + +# You must remove unused comment lines for the released package. diff --git a/debian/files b/debian/files new file mode 100644 index 0000000..dff631b --- /dev/null +++ b/debian/files @@ -0,0 +1,2 @@ +php-vitexsoftware-fluentpdo_3.0.0-1_all.deb php optional +php-vitexsoftware-fluentpdo_3.0.0-1_amd64.buildinfo php optional diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000..4a97dfa --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1 @@ +# You must remove unused comment lines for the released package. diff --git a/debian/links b/debian/links new file mode 100644 index 0000000..522e345 --- /dev/null +++ b/debian/links @@ -0,0 +1,2 @@ + +# You must remove unused comment lines for the released package. diff --git a/debian/maintscript.ex b/debian/maintscript.ex new file mode 100644 index 0000000..34601ea --- /dev/null +++ b/debian/maintscript.ex @@ -0,0 +1,7 @@ +# see: dh_installdeb(1), dpkg-maintscript-helper(1) +# For renaming a conffile, you are advised to uncomment and edit the following +#dpkg-maintscript-helper mv_conffile old-conffile new-conffile prior-version package +# For switching a symlink to directory, you are advised to uncomment and edit the following +#dpkg-maintscript-helper symlink_to_dir pathname old-target prior-version package +# For switching a directory to symlink, you are advised to uncomment and edit the following +#dpkg-maintscript-helper dir_to_symlink pathname new-target prior-version package diff --git a/debian/php-vitexsoftware-fluentpdo.install b/debian/php-vitexsoftware-fluentpdo.install new file mode 100644 index 0000000..191a060 --- /dev/null +++ b/debian/php-vitexsoftware-fluentpdo.install @@ -0,0 +1,5 @@ +src/*.php usr/share/php/FluentPDO/ +src/Queries/*.php usr/share/php/FluentPDO/Queries/ +debian/tmp/composer.json usr/share/php/FluentPDO/ +readme.md usr/share/doc/php-vitexsoftware-fluentpdo/ +CHANGELOG.md usr/share/doc/php-vitexsoftware-fluentpdo/ diff --git a/debian/postinst.ex b/debian/postinst.ex new file mode 100644 index 0000000..220990b --- /dev/null +++ b/debian/postinst.ex @@ -0,0 +1,7 @@ +#!/bin/sh +# If no user provided script is activated in this file, you should remove this file. +set -e + +#DEBHELPER# + +exit 0 diff --git a/debian/postrm.ex b/debian/postrm.ex new file mode 100644 index 0000000..220990b --- /dev/null +++ b/debian/postrm.ex @@ -0,0 +1,7 @@ +#!/bin/sh +# If no user provided script is activated in this file, you should remove this file. +set -e + +#DEBHELPER# + +exit 0 diff --git a/debian/preinst.ex b/debian/preinst.ex new file mode 100644 index 0000000..220990b --- /dev/null +++ b/debian/preinst.ex @@ -0,0 +1,7 @@ +#!/bin/sh +# If no user provided script is activated in this file, you should remove this file. +set -e + +#DEBHELPER# + +exit 0 diff --git a/debian/prerm.ex b/debian/prerm.ex new file mode 100644 index 0000000..220990b --- /dev/null +++ b/debian/prerm.ex @@ -0,0 +1,7 @@ +#!/bin/sh +# If no user provided script is activated in this file, you should remove this file. +set -e + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..14168b0 --- /dev/null +++ b/debian/rules @@ -0,0 +1,15 @@ +#!/usr/bin/make -f + +%: + dh $@ + +override_dh_auto_build: + # No build step needed for pure PHP library + +override_dh_auto_test: + # Skip tests during package build to avoid dependency issues + +override_dh_auto_install: + mkdir -p debian/tmp + jq '.version = "'`dpkg-parsechangelog | sed -n 's/^Version: //p'| sed 's/~.*//' `'"' debian/composer.json |sponge debian/tmp/composer.json + dh_auto_install diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml new file mode 100644 index 0000000..661e26b --- /dev/null +++ b/debian/salsa-ci.yml @@ -0,0 +1,25 @@ +# For more information on what jobs are run see: +# https://salsa.debian.org/salsa-ci-team/pipeline +# +# To enable the jobs, go to your repository (at salsa.debian.org) +# and click over Settings > CI/CD > Expand (in General pipelines). +# In "CI/CD configuration file" write debian/salsa-ci.yml and click +# in "Save Changes". The CI tests will run after the next commit. +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml + +# # This commented-out sample disables all default tests, only disable those +# # CI tests that is required to get the CI process to succeed. +# +# variables: +# SALSA_CI_DISABLE_APTLY: 1 +# SALSA_CI_DISABLE_AUTOPKGTEST: 1 +# SALSA_CI_DISABLE_BLHC: 1 +# SALSA_CI_DISABLE_LINTIAN: 1 +# SALSA_CI_DISABLE_PIUPARTS: 1 +# SALSA_CI_DISABLE_REPROTEST: 1 +# SALSA_CI_DISABLE_BUILD_PACKAGE_ALL: 1 +# SALSA_CI_DISABLE_BUILD_PACKAGE_ANY: 1 +# SALSA_CI_DISABLE_BUILD_PACKAGE_I386: 1 +# SALSA_CI_DISABLE_CROSSBUILD_ARM64: 1 diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/tests/control b/debian/tests/control new file mode 100644 index 0000000..f61fd44 --- /dev/null +++ b/debian/tests/control @@ -0,0 +1,9 @@ +# +# DEP-8: autopkgtest - automatic as-installed package testing +# Please check * https://dep-team.pages.debian.net/deps/dep8/ +# * /usr/share/doc/autopkgtest +# +# !!! Please make sure to edit this to a valid test, otherwise build will fails +# +#Tests: testcode.sh +#Restrictions: allow-stderr, breaks-testbed, needs-internet, needs-root diff --git a/debian/tmp/composer.json b/debian/tmp/composer.json new file mode 100644 index 0000000..68b1216 --- /dev/null +++ b/debian/tmp/composer.json @@ -0,0 +1,51 @@ +{ + "name": "deb/fluentpdo", + "description": "FluentPDO - PHP 8.1+ Edition. A modernized fork with strict typing, union types, and enhanced features. Quick and light PHP library for rapid query building with smart join builder.", + "type": "library", + "keywords": [ + "db", + "database", + "dbal", + "pdo", + "fluent", + "query", + "builder", + "mysql", + "oracle", + "mssql", + "php8", + "php81", + "strict-types", + "union-types", + "modern-php" + ], + "homepage": "https://github.com/VitexSoftware/php-vitexsoftware-fluentpdo", + "license": [ + "Apache-2.0", + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "envms", + "homepage": "https://env.ms" + }, + { + "name": "vitex", + "homepage": "https://vitexsoftware.com" + } + ], + "autoload": { + "psr-4": { + "Envms\\FluentPDO\\": "./", + "Envms\\FluentPDO\\QueriesPDO\\": "./Queries/" + } + }, + "require": { + "php": ">=8.1", + "ext-pdo": "*" + }, + "replace": { + "envms/fluentpdo": "^2.2" + }, + "version": "3.0.0-1" +} diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 0000000..dc2feb0 --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,16 @@ +# +# DEP-12: Per-package machine-readable metadata about Upstream +# Please check * https://dep-team.pages.debian.net/deps/dep12/ +# * https://wiki.debian.org/UpstreamMetadata +Reference: + Author: + Title: + Journal: + Year: + Volume: + Number: + Pages: + DOI: + PMID: + URL: + eprint: diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..6ebdc86 --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +# You must remove unused comment lines for the released package. +# Compulsory line, this is a version 4 file +version=4 diff --git a/readme.md b/readme.md index 228db07..8b4982a 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,21 @@ -# FluentPDO [![Build Status](https://secure.travis-ci.org/envms/fluentpdo.png?branch=master)](http://travis-ci.org/envms/fluentpdo) [![Maintainability](https://api.codeclimate.com/v1/badges/19210ca91c7055b89705/maintainability)](https://codeclimate.com/github/fpdo/fluentpdo/maintainability) +# FluentPDO - PHP 8.1+ Edition + +**A modernized fork of the original FluentPDO project, updated for PHP 8.1+ with modern type declarations and enhanced features.** FluentPDO is a PHP SQL query builder using PDO. It's a quick and light library featuring a smart join builder, which automatically creates table joins for you. +## About This Fork + +This is a modernized fork of the original [envms/fluentpdo](https://github.com/envms/fluentpdo) project. Since the original project has been inactive for 3+ years (last commit in 2021), this fork provides: + +- **PHP 8.1+ compatibility** with modern type declarations +- **Strict typing** throughout the codebase +- **Union types** and **mixed types** where appropriate +- **Typed properties** for better IDE support +- **Array parameter handling** with automatic JSON serialization +- **Enhanced error handling** and debugging capabilities +- **Updated dependencies** and development tools + ## Features - Easy interface for creating robust queries @@ -9,25 +23,22 @@ FluentPDO is a PHP SQL query builder using PDO. It's a quick and light library f - Ability to build complex SELECT, INSERT, UPDATE & DELETE queries with little code - Type hinting for magic methods with code completion in smart IDEs -## Versions +## PHP Version Requirements -#### Version 2.x +**This fork requires PHP 8.1 or higher.** -The stable release of FluentPDO and actively maintained. Officially supports PHP 7.3 to PHP 8.0, -but it can work with previous versions of PHP 7. +### What's New in This PHP 8.1+ Edition -#### Version 1.x +- **Modern Type System**: Full use of PHP 8.1+ type declarations including union types +- **Strict Types**: All files use `declare(strict_types=1)` for better type safety +- **Array Handling**: Automatic JSON serialization of array parameters to prevent SQL errors +- **Enhanced Performance**: Better memory usage and performance through strict typing +- **Developer Experience**: Improved IDE support with proper type hints and autocomplete +- **Future Ready**: Prepared for upcoming PHP versions -The legacy release of FluentPDO. It is no longer supported and will not be maintained or updated. -This version works with PHP 5.4 to 7.1. +### Migrating from Original FluentPDO -#### Version 3.x - alpha - -This version is a full rewrite of Fluent from the ground up. Its main advantage is -significantly less memory usage and much greater performance in query building. It also places -a few additional restrictions to make queries easier to read and maintain. Documentation has also -been a very common request, and version 3 is being fully documented alongside development. -Details and metrics will be posted once available. +If you're upgrading from the original FluentPDO (v2.x), this version maintains API compatibility while requiring PHP 8.1+. The main changes are internal improvements and type safety enhancements. ## Reference @@ -37,34 +48,42 @@ Details and metrics will be posted once available. ### Composer -The preferred way to install FluentPDO is via [composer](http://getcomposer.org/). - -Add the following line in your `composer.json` file: +The preferred way to install this PHP 8.1+ edition of FluentPDO is via [composer](http://getcomposer.org/). - "require": { - ... - "envms/fluentpdo": "^2.2.0" - } +```bash +composer require vitexsoftware/fluentpdo +``` -update your dependencies with `composer update`, and you're done! +Or add the following line in your `composer.json` file: -### Download Zip +```json +{ + "require": { + "vitexsoftware/fluentpdo": "^3.0" + } +} +``` -If you prefer not to use composer, download the latest release, create the directory `Envms/FluentPDO` in your library directory, and drop this repository into it. Finally, add: +Then run `composer update` and you're done! -```php -require '[lib-dir]/Envms/FluentPDO/src/Query.php'; -``` +### Requirements -to the top of your application. **Note:** You will need an autoloader to use FluentPDO without changing its source code. +- **PHP 8.1+** (required) +- **PDO extension** (required) +- Any PDO-compatible database (MySQL, PostgreSQL, SQLite, etc.) ## Getting Started Create a new PDO instance, and pass the instance to FluentPDO: ```php +insertInto('article', $values)->execute(); // shorter version ##### UPDATE ```php -$set = array('published_at' => new FluentLiteral('NOW()')); +use Envms\FluentPDO\Literal; + +$set = ['published_at' => new Literal('NOW()')]; $query = $fluent->update('article')->set($set)->where('id', 1)->execute(); $query = $fluent->update('article', $set, 1)->execute(); // shorter version if updating one row by primary key @@ -174,6 +195,43 @@ $query = $fluent->deleteFrom('article', 1)->execute(); // shorter version if del ***Note**: INSERT, UPDATE and DELETE queries will only run after you call `->execute()`* +## Modern PHP 8.1+ Features + +### Array Parameter Handling + +This edition automatically handles array parameters by converting them to JSON strings: + +```php +// Arrays are automatically converted to JSON +$data = [ + 'name' => 'John Doe', + 'tags' => ['php', 'mysql', 'programming'], // Automatically converts to JSON + 'metadata' => ['created' => '2025-01-01', 'active' => true] +]; + +$fluent->insertInto('users', $data)->execute(); +``` + +### Strict Type Declarations + +All classes use strict typing for better performance and error detection: + +```php + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO; /** - * Class Exception + * Class Exception. */ class Exception extends \Exception { - } diff --git a/src/Literal.php b/src/Literal.php index 57bc755..a157cb7 100644 --- a/src/Literal.php +++ b/src/Literal.php @@ -1,34 +1,38 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO; /** - * SQL literal value + * SQL literal value. */ class Literal { - - /** @var string */ - protected $value = ''; + protected string $value = ''; /** - * Create literal value - * - * @param string $value + * Create literal value. */ - function __construct($value) + public function __construct(string $value) { $this->value = $value; } /** - * Get literal value - * - * @return string + * Get literal value. */ - function __toString() + public function __toString(): string { return $this->value; } - } diff --git a/src/Queries/Base.php b/src/Queries/Base.php index b05aae1..e394d8a 100644 --- a/src/Queries/Base.php +++ b/src/Queries/Base.php @@ -1,56 +1,64 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO\Queries; -use DateTime, IteratorAggregate, PDO, PDOStatement; -use Envms\FluentPDO\{Exception, Literal, Query, Regex, Structure, Utilities}; +use Envms\FluentPDO\Exception; +use Envms\FluentPDO\Literal; +use Envms\FluentPDO\Query; +use Envms\FluentPDO\Regex; +use Envms\FluentPDO\Structure; +use Envms\FluentPDO\Utilities; +use IteratorAggregate; +use PDO; +use PDOStatement; /** - * Base query builder + * Base query builder. */ -abstract class Base implements IteratorAggregate +abstract class Base implements \IteratorAggregate { + protected Query $fluent; - /** @var float */ - private $totalTime; + protected null|bool|\PDOStatement $result; + + /** + * @var array - definition clauses + */ + protected array $clauses = []; - /** @var float */ - private $executionTime; + protected array $statements = []; - /** @var bool */ - private $object = false; + protected array $parameters = []; - /** @var Query */ - protected $fluent; + protected Regex $regex; - /** @var PDOStatement|null|bool */ - protected $result; + protected string $message = ''; - /** @var array - definition clauses */ - protected $clauses = []; - /** @var array */ - protected $statements = []; - /** @var array */ - protected $parameters = []; + protected int $currentFetchMode; - /** @var Regex */ - protected $regex; + private float $totalTime; - /** @var string */ - protected $message = ''; + private float $executionTime; - /** @var int */ - protected $currentFetchMode; + private bool $object = false; /** * BaseQuery constructor. - * - * @param Query $fluent - * @param $clauses */ protected function __construct(Query $fluent, $clauses) { - $this->currentFetchMode = defined('PDO::FETCH_DEFAULT') ? PDO::FETCH_DEFAULT : PDO::FETCH_BOTH; + $this->currentFetchMode = \defined('PDO::FETCH_DEFAULT') ? \PDO::FETCH_DEFAULT : \PDO::FETCH_BOTH; $this->fluent = $fluent; $this->clauses = $clauses; $this->result = null; @@ -62,11 +70,11 @@ protected function __construct(Query $fluent, $clauses) /** * Return formatted query when request class representation - * ie: echo $query - * - * @return string - formatted query + * ie: echo $query. * * @throws Exception + * + * @return string - formatted query */ public function __toString() { @@ -74,117 +82,24 @@ public function __toString() } /** - * Initialize statement and parameter clauses. - */ - private function initClauses(): void - { - foreach ($this->clauses as $clause => $value) { - if ($value) { - $this->statements[$clause] = []; - $this->parameters[$clause] = []; - } else { - $this->statements[$clause] = null; - $this->parameters[$clause] = null; - } - } - } - - /** - * Add statement for all clauses except WHERE - * - * @param $clause - * @param $statement - * @param array $parameters - * - * @return $this - */ - protected function addStatement($clause, $statement, $parameters = []) - { - if ($statement === null) { - return $this->resetClause($clause); - } - - if ($this->clauses[$clause]) { - if (is_array($statement)) { - $this->statements[$clause] = array_merge($this->statements[$clause], $statement); - } else { - $this->statements[$clause][] = $statement; - } - - $this->parameters[$clause] = array_merge($this->parameters[$clause], $parameters); - } else { - $this->statements[$clause] = $statement; - $this->parameters[$clause] = $parameters; - } - - return $this; - } - - /** - * Add statement for all kind of clauses - * - * @param $statement - * @param string $separator - should be AND or OR - * @param array $parameters - * - * @return $this - */ - protected function addWhereStatement($statement, string $separator = 'AND', $parameters = []) - { - if ($statement === null) { - return $this->resetClause('WHERE'); - } - - if (is_array($statement)) { - foreach ($statement as $s) { - $this->statements['WHERE'][] = [$separator, $s]; - } - } else { - $this->statements['WHERE'][] = [$separator, $statement]; - } - - $this->parameters['WHERE'] = array_merge($this->parameters['WHERE'], $parameters); - - return $this; - } - - /** - * Remove all prev defined statements - * - * @param $clause - * - * @return $this - */ - protected function resetClause($clause) - { - $this->statements[$clause] = null; - $this->parameters[$clause] = []; - if (isset($this->clauses[$clause]) && $this->clauses[$clause]) { - $this->statements[$clause] = []; - } - - return $this; - } - - /** - * Implements method from IteratorAggregate - * - * @return PDOStatement + * Implements method from IteratorAggregate. * * @throws Exception + * + * @return \PDOStatement */ #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): \Traversable { return $this->execute(); } /** - * Execute query with earlier added parameters - * - * @return PDOStatement + * Execute query with earlier added parameters. * * @throws Exception + * + * @return \PDOStatement */ public function execute() { @@ -208,17 +123,9 @@ public function execute() } /** - * @return Structure - */ - protected function getStructure(): Structure - { - return $this->fluent->getStructure(); - } - - /** - * Get PDOStatement result + * Get PDOStatement result. * - * @return PDOStatement|null|bool + * @return null|bool|\PDOStatement */ public function getResult() { @@ -226,43 +133,30 @@ public function getResult() } /** - * Get query parameters - * - * @return array + * Get query parameters. */ public function getParameters(): array { return $this->buildParameters(); } - /** - * @return array - */ public function getRawClauses(): array { return $this->clauses; } - /** - * @return array - */ public function getRawStatements(): array { return $this->statements; } - /** - * @return array - */ public function getRawParameters(): array { return $this->parameters; } /** - * Gets the total time of query building, preparation and execution - * - * @return float + * Gets the total time of query building, preparation and execution. */ public function getTotalTime(): float { @@ -270,29 +164,23 @@ public function getTotalTime(): float } /** - * Gets the query execution time - * - * @return float + * Gets the query execution time. */ public function getExecutionTime(): float { return $this->executionTime; } - /** - * @return string - */ public function getMessage(): string { return $this->message; } /** - * Get query string + * Get query string. * * @param bool $formatted - Return formatted query * - * @return string * @throws Exception */ public function getQuery(bool $formatted = true): string @@ -307,11 +195,11 @@ public function getQuery(bool $formatted = true): string } /** - * Select an item as object + * Select an item as object. * - * @param object|boolean $object If set to true, items are returned as stdClass, otherwise a class - * name can be passed and a new instance of this class is returned. - * Can be set to false to return items as an associative array. + * @param bool|object $object If set to true, items are returned as stdClass, otherwise a class + * name can be passed and a new instance of this class is returned. + * Can be set to false to return items as an associative array. * * @return $this */ @@ -323,16 +211,94 @@ public function asObject($object = true) } /** - * Converts php null values to Literal instances to be inserted into a database + * Add statement for all clauses except WHERE. + * + * @param array $parameters + * + * @return $this + */ + protected function addStatement($clause, $statement, $parameters = []) + { + if ($statement === null) { + return $this->resetClause($clause); + } + + if ($this->clauses[$clause]) { + if (\is_array($statement)) { + $this->statements[$clause] = array_merge($this->statements[$clause], $statement); + } else { + $this->statements[$clause][] = $statement; + } + + $this->parameters[$clause] = array_merge($this->parameters[$clause], $parameters); + } else { + $this->statements[$clause] = $statement; + $this->parameters[$clause] = $parameters; + } + + return $this; + } + + /** + * Add statement for all kind of clauses. + * + * @param string $separator - should be AND or OR + * @param array $parameters + * + * @return $this + */ + protected function addWhereStatement($statement, string $separator = 'AND', $parameters = []) + { + if ($statement === null) { + return $this->resetClause('WHERE'); + } + + if (\is_array($statement)) { + foreach ($statement as $s) { + $this->statements['WHERE'][] = [$separator, $s]; + } + } else { + $this->statements['WHERE'][] = [$separator, $statement]; + } + + $this->parameters['WHERE'] = array_merge($this->parameters['WHERE'], $parameters); + + return $this; + } + + /** + * Remove all prev defined statements. + * + * @return $this + */ + protected function resetClause($clause) + { + $this->statements[$clause] = null; + $this->parameters[$clause] = []; + + if (isset($this->clauses[$clause]) && $this->clauses[$clause]) { + $this->statements[$clause] = []; + } + + return $this; + } + + protected function getStructure(): Structure + { + return $this->fluent->getStructure(); + } + + /** + * Converts php null values to Literal instances to be inserted into a database. */ protected function convertNullValues(): void { $filterList = ['VALUES', 'ON DUPLICATE KEY UPDATE', 'SET']; foreach ($this->statements as $clause => $statement) { - if (in_array($clause, $filterList)) { + if (\in_array($clause, $filterList, true)) { if (isset($statement[0])) { - for ($i = 0, $iMax = count($statement); $i < $iMax; $i++) { + for ($i = 0, $iMax = \count($statement); $i < $iMax; ++$i) { foreach ($statement[$i] as $key => $value) { $this->statements[$clause][$i][$key] = Utilities::nullToLiteral($value); } @@ -347,10 +313,11 @@ protected function convertNullValues(): void } /** - * Generate query + * Generate query. * - * @return string * @throws Exception + * + * @return string */ protected function buildQuery() { @@ -362,14 +329,14 @@ protected function buildQuery() foreach ($this->clauses as $clause => $separator) { if ($this->clauseNotEmpty($clause)) { - if (is_string($separator)) { - $query .= " {$clause} " . implode($separator, $this->statements[$clause]); + if (\is_string($separator)) { + $query .= " {$clause} ".implode($separator, $this->statements[$clause]); } elseif ($separator === null) { $query .= " {$clause} {$this->statements[$clause]}"; - } elseif (is_callable($separator)) { + } elseif (\is_callable($separator)) { $query .= $separator(); } else { - throw new Exception("Clause '$clause' is incorrectly set to '$separator'."); + throw new Exception("Clause '{$clause}' is incorrectly set to '{$separator}'."); } } } @@ -377,26 +344,34 @@ protected function buildQuery() return trim(str_replace(['\.', '\:'], ['.', ':'], $query)); } - /** - * @return array - */ protected function buildParameters(): array { $parameters = []; + foreach ($this->parameters as $clauses) { if ($this->fluent->convertWrite === true) { $clauses = Utilities::convertSqlWriteValues($clauses); } - if (is_array($clauses)) { + if (\is_array($clauses)) { foreach ($clauses as $key => $value) { - if (strpos($key, ':') === 0) { // these are named params e.g. (':name' => 'Mark') + // Convert arrays to JSON strings for PDO compatibility + if (\is_array($value)) { + $value = json_encode($value); + } + + if (str_starts_with($key, ':')) { // these are named params e.g. (':name' => 'Mark') $parameters += [$key => $value]; } else { $parameters[] = $value; } } } elseif ($clauses !== false && $clauses !== null) { + // Convert arrays to JSON strings for PDO compatibility + if (\is_array($clauses)) { + $clauses = json_encode($clauses); + } + $parameters[] = $clauses; } } @@ -405,23 +380,22 @@ protected function buildParameters(): array } /** - * @param $value - * * @return string */ protected function quote($value) { if (!isset($value)) { - return "NULL"; + return 'NULL'; } - if (is_array($value)) { // (a, b) IN ((1, 2), (3, 4)) - return "(" . implode(", ", array_map([$this, 'quote'], $value)) . ")"; + if (\is_array($value)) { // (a, b) IN ((1, 2), (3, 4)) + return '('.implode(', ', array_map([$this, 'quote'], $value)).')'; } - $value = $this->formatValue($value); - if (is_float($value)) { - return sprintf("%F", $value); // otherwise depends on setlocale() + $value = self::formatValue($value); + + if (\is_float($value)) { + return sprintf('%F', $value); // otherwise depends on setlocale() } if ($value === true) { @@ -432,25 +406,39 @@ protected function quote($value) return 0; } - if (is_int($value) || $value instanceof Literal) { // number or SQL code - for example "NOW()" - return (string)$value; + if (\is_int($value) || $value instanceof Literal) { // number or SQL code - for example "NOW()" + return (string) $value; } return $this->fluent->getPdo()->quote($value); } /** - * @param $clause - * + * Initialize statement and parameter clauses. + */ + private function initClauses(): void + { + foreach ($this->clauses as $clause => $value) { + if ($value) { + $this->statements[$clause] = []; + $this->parameters[$clause] = []; + } else { + $this->statements[$clause] = null; + $this->parameters[$clause] = null; + } + } + } + + /** * @return bool */ private function clauseNotEmpty($clause) { - if ((Utilities::isCountable($this->statements[$clause])) && $this->clauses[$clause]) { - return (bool)count($this->statements[$clause]); + if (Utilities::isCountable($this->statements[$clause]) && $this->clauses[$clause]) { + return (bool) \count($this->statements[$clause]); } - return (bool)$this->statements[$clause]; + return (bool) $this->statements[$clause]; } /** @@ -458,9 +446,9 @@ private function clauseNotEmpty($clause) * * @return mixed */ - private function formatValue($val) + private static function formatValue($val) { - if ($val instanceof DateTime) { + if ($val instanceof \DateTime) { return $val->format('Y-m-d H:i:s'); // may be driver specific } @@ -484,7 +472,7 @@ private function prepareQuery($query): void prepare function until we call PDOStatement::execute() below. If PDO::prepare() was consistent, this is where we would check for prepare errors, such as invalid SQL. - */ + */ if ($this->result === false) { $error = $this->fluent->getPdo()->errorInfo(); @@ -520,41 +508,38 @@ private function executeQuery($parameters, $startTime, $execTime): void } } - /** - * @param PDOStatement $result - */ - private function setObjectFetchMode(PDOStatement $result): void + private function setObjectFetchMode(\PDOStatement $result): void { if ($this->object !== false) { if (class_exists($this->object)) { - $this->currentFetchMode = PDO::FETCH_CLASS; + $this->currentFetchMode = \PDO::FETCH_CLASS; $result->setFetchMode($this->currentFetchMode, $this->object); } else { - $this->currentFetchMode = PDO::FETCH_OBJ; + $this->currentFetchMode = \PDO::FETCH_OBJ; $result->setFetchMode($this->currentFetchMode); } - } elseif ($this->fluent->getPdo()->getAttribute(PDO::ATTR_DEFAULT_FETCH_MODE) === PDO::FETCH_BOTH) { - $this->currentFetchMode = PDO::FETCH_ASSOC; + } elseif ($this->fluent->getPdo()->getAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE) === \PDO::FETCH_BOTH) { + $this->currentFetchMode = \PDO::FETCH_ASSOC; $result->setFetchMode($this->currentFetchMode); } } /** - * Echo/pass a debug string + * Echo/pass a debug string. * * @throws Exception */ - private function debug() + private function debug(): void { if (!empty($this->fluent->debug)) { - if (!is_callable($this->fluent->debug)) { + if (!\is_callable($this->fluent->debug)) { $backtrace = ''; $query = $this->getQuery(); $parameters = $this->getParameters(); $debug = ''; if ($parameters) { - $debug = '# parameters: ' . implode(', ', array_map([$this, 'quote'], $parameters)) . "\n"; + $debug = '# parameters: '.implode(', ', array_map([$this, 'quote'], $parameters))."\n"; } $debug .= $query; @@ -566,13 +551,13 @@ private function debug() } } - $time = sprintf('%0.3f', $this->totalTime * 1000) . 'ms'; + $time = sprintf('%0.3f', $this->totalTime * 1000).'ms'; $rows = ($this->result) ? $this->result->rowCount() : 0; $finalString = "# {$backtrace['file']}:{$backtrace['line']} ({$time}; rows = {$rows})\n{$debug}\n\n"; // if STDERR is set, send there, otherwise just output the string - if (defined('STDERR') && is_resource(STDERR)) { - fwrite(STDERR, $finalString); + if (\defined('STDERR') && \is_resource(\STDERR)) { + fwrite(\STDERR, $finalString); } else { echo $finalString; } diff --git a/src/Queries/Common.php b/src/Queries/Common.php index fefd253..d84c0e3 100644 --- a/src/Queries/Common.php +++ b/src/Queries/Common.php @@ -1,33 +1,57 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO\Queries; -use Envms\FluentPDO\{Exception, Literal, Utilities}; +use Envms\FluentPDO\Exception; +use Envms\FluentPDO\Literal; +use Envms\FluentPDO\Utilities; /** - * CommonQuery add JOIN and WHERE clauses for (SELECT, UPDATE, DELETE) + * CommonQuery add JOIN and WHERE clauses for (SELECT, UPDATE, DELETE). * - * @method $this from(string $table) - add FROM to DELETE query - * @method $this leftJoin(string $statement) - add LEFT JOIN to query - * $statement can be the 'table' name only or 'table:' to back reference the join - * @method $this rightJoin(string $statement) - add RIGHT JOIN to query - * @method $this innerJoin(string $statement) - add INNER JOIN to query - * @method $this outerJoin(string $statement) - add OUTER JOIN to query - * @method $this fullJoin(string $statement) - add FULL JOIN to query - * @method $this group(string $column) - add GROUP BY to query - * @method $this groupBy(string $column) - add GROUP BY to query - * @method $this having(string $column) - add HAVING query - * @method $this order(string $column) - add ORDER BY to query - * @method $this orderBy(string $column) - add ORDER BY to query - * @method $this limit(int $limit) - add LIMIT to query - * @method $this offset(int $offset) - add OFFSET to query * @method $this comment(string $comment) - add COMMENT (--) to query + * @method $this from(string $table) - add FROM to DELETE query + * @method $this fullJoin(string $statement) - add FULL JOIN to query + * @method $this group(string $column) - add GROUP BY to query + * @method $this groupBy(string $column) - add GROUP BY to query + * @method $this having(string $column) - add HAVING query + * @method $this innerJoin(string $statement) - add INNER JOIN to query + * @method $this leftJoin(string $statement) - add LEFT JOIN to query + * $statement can be the 'table' name only or 'table:' to back reference the join + * @method $this limit(int $limit) - add LIMIT to query + * @method $this offset(int $offset) - add OFFSET to query + * @method $this order(string $column) - add ORDER BY to query + * @method $this orderBy(string $column) - add ORDER BY to query + * @method $this outerJoin(string $statement) - add OUTER JOIN to query + * @method $this rightJoin(string $statement) - add RIGHT JOIN to query */ abstract class Common extends Base { + /** + * @var array - Query tables (also include table from clause FROM) + */ + protected array $joins = []; - /** @var array - methods which are allowed to be called by the magic method __call() */ - private $validMethods = [ + /** + * @var bool - Disable adding undefined joins to query? + */ + protected bool $isSmartJoinEnabled = true; + + /** + * @var array - methods which are allowed to be called by the magic method __call() + */ + private array $validMethods = [ 'comment', 'from', 'fullJoin', @@ -42,15 +66,9 @@ abstract class Common extends Base 'order', 'orderBy', 'outerJoin', - 'rightJoin' + 'rightJoin', ]; - /** @var array - Query tables (also include table from clause FROM) */ - protected $joins = []; - - /** @var bool - Disable adding undefined joins to query? */ - protected $isSmartJoinEnabled = true; - /** * @param string $name * @param array $parameters - first is $statement followed by $parameters @@ -59,29 +77,38 @@ abstract class Common extends Base */ public function __call($name, $parameters = []) { - if (!in_array($name, $this->validMethods)) { - trigger_error("Call to invalid method " . get_class($this) . "::{$name}()", E_USER_ERROR); + if (!\in_array($name, $this->validMethods, true)) { + trigger_error('Call to invalid method '.\get_class($this)."::{$name}()", \E_USER_ERROR); } $clause = Utilities::toUpperWords($name); - if ($clause == 'GROUP' || $clause == 'ORDER') { + if ($clause === 'GROUP' || $clause === 'ORDER') { $clause = "{$clause} BY"; } - if ($clause == 'COMMENT') { + if ($clause === 'COMMENT') { $clause = "\n--"; } $statement = array_shift($parameters); - if (strpos($clause, 'JOIN') !== false) { + if (str_contains($clause, 'JOIN')) { return $this->addJoinStatements($clause, $statement, $parameters); } return $this->addStatement($clause, $statement, $parameters); } + public function __clone() + { + foreach ($this->clauses as $clause => $value) { + if (\is_array($value) && $value[0] instanceof self) { + $this->clauses[$clause][0] = $this; + } + } + } + /** * @return $this */ @@ -111,11 +138,11 @@ public function isSmartJoinEnabled() } /** - * Add where condition, defaults to appending with AND + * Add where condition, defaults to appending with AND. * - * @param string|array $condition - possibly containing ? or :name (PDO syntax) + * @param array|string $condition - possibly containing ? or :name (PDO syntax) * @param mixed $parameters - * @param string $separator - should be AND or OR + * @param string $separator - should be AND or OR * * @return $this */ @@ -129,7 +156,7 @@ public function where($condition, $parameters = [], $separator = 'AND') return $this; } - if (is_array($condition)) { // where(["column1 > ?" => 1, "column2 < ?" => 2]) + if (\is_array($condition)) { // where(["column1 > ?" => 1, "column2 < ?" => 2]) foreach ($condition as $key => $val) { $this->where($key, $val); } @@ -137,7 +164,7 @@ public function where($condition, $parameters = [], $separator = 'AND') return $this; } - $args = func_get_args(); + $args = \func_get_args(); if ($parameters === []) { return $this->addWhereStatement($condition, $separator); @@ -148,16 +175,20 @@ public function where($condition, $parameters = [], $separator = 'AND') * a parameter (? or :name), add them; it's up to the dev to be valid sql. Otherwise it's probably * just an identifier, so construct a new condition based on the passed parameter value. */ - if (count($args) >= 2 && !$this->regex->sqlParameter($condition)) { + if (\count($args) >= 2 && !$this->regex->sqlParameter($condition)) { // condition is column only - if (is_null($parameters)) { - return $this->addWhereStatement("$condition IS NULL", $separator); - } elseif ($args[1] === []) { + if (null === $parameters) { + return $this->addWhereStatement("{$condition} IS NULL", $separator); + } + + if ($args[1] === []) { return $this->addWhereStatement('FALSE', $separator); - } elseif (is_array($args[1])) { + } + + if (\is_array($args[1])) { $in = $this->quote($args[1]); - return $this->addWhereStatement("$condition IN $in", $separator); + return $this->addWhereStatement("{$condition} IN {$in}", $separator); } // don't parameterize the value if it's an instance of Literal @@ -165,15 +196,15 @@ public function where($condition, $parameters = [], $separator = 'AND') $condition = "{$condition} = {$parameters}"; return $this->addWhereStatement($condition, $separator); - } else { - $condition = "$condition = ?"; } + + $condition = "{$condition} = ?"; } $args = [0 => $args[1]]; // parameters can be passed as [1, 2, 3] and it will fill a condition like: id IN (?, ?, ?) - if (is_array($parameters) && !empty($parameters)) { + if (\is_array($parameters) && !empty($parameters)) { $args = $parameters; } @@ -181,7 +212,7 @@ public function where($condition, $parameters = [], $separator = 'AND') } /** - * Add where appending with OR + * Add where appending with OR. * * @param string $condition - possibly containing ? or :name (PDO syntax) * @param mixed $parameters @@ -190,7 +221,7 @@ public function where($condition, $parameters = [], $separator = 'AND') */ public function whereOr($condition, $parameters = []) { - if (is_array($condition)) { // where(["column1 > ?" => 1, "column2 < ?" => 2]) + if (\is_array($condition)) { // where(["column1 > ?" => 1, "column2 < ?" => 2]) foreach ($condition as $key => $val) { $this->whereOr($key, $val); } @@ -212,7 +243,8 @@ protected function getClauseJoin() /** * @return string */ - protected function getClauseWhere() { + protected function getClauseWhere() + { $firstStatement = array_shift($this->statements['WHERE']); $query = " WHERE {$firstStatement[1]}"; // append first statement to WHERE without condition @@ -229,10 +261,39 @@ protected function getClauseWhere() { } /** - * Statement can contain more tables (e.g. "table1.table2:table3:") + * @throws Exception + * + * @return string + */ + protected function buildQuery() + { + // first create extra join from statements with columns with referenced tables + $statementsWithReferences = ['WHERE', 'SELECT', 'GROUP BY', 'ORDER BY']; + + foreach ($statementsWithReferences as $clause) { + if (\array_key_exists($clause, $this->statements)) { + $this->statements[$clause] = array_map([$this, 'createUndefinedJoins'], $this->statements[$clause]); + } + } + + return parent::buildQuery(); + } + + /** + * @return bool + */ + protected function isEscapedJoin($statement) + { + if (\is_array($statement)) { + $statement = $statement[1]; + } + + return !$this->isSmartJoinEnabled || str_contains($statement, '\.') || str_contains($statement, '\:'); + } + + /** + * Statement can contain more tables (e.g. "table1.table2:table3:"). * - * @param $clause - * @param $statement * @param array $parameters * * @return $this @@ -245,20 +306,20 @@ private function addJoinStatements($clause, $statement, $parameters = []) return $this->resetClause('JOIN'); } - if (array_search(substr($statement, 0, -1), $this->joins) !== false) { + if (array_search(substr($statement, 0, -1), $this->joins, true) !== false) { return $this; } - list($joinAlias, $joinTable) = $this->setJoinNameAlias($statement); + [$joinAlias, $joinTable] = $this->setJoinNameAlias($statement); - if (strpos(strtoupper($statement), ' ON ') !== false || strpos(strtoupper($statement), ' USING') !== false) { + if (str_contains(strtoupper($statement), ' ON ') || str_contains(strtoupper($statement), ' USING')) { return $this->addRawJoins($clause, $statement, $parameters, $joinAlias, $joinTable); } $mainTable = $this->setMainTable(); // if $joinTable does not end with a dot or colon, append one - if (!in_array(substr($joinTable, -1), ['.', ':'])) { + if (!\in_array(substr($joinTable, -1), ['.', ':'], true)) { $joinTable .= '.'; } @@ -266,10 +327,10 @@ private function addJoinStatements($clause, $statement, $parameters = []) // used for applying the table alias $lastItem = array_pop($matches[1]); - array_push($matches[1], $lastItem); + $matches[1][] = $lastItem; foreach ($matches[1] as $joinItem) { - if ($this->matchTableWithJoin($mainTable, $joinItem)) { + if (self::matchTableWithJoin($mainTable, $joinItem)) { // this is still the same table so we don't need to add the same join continue; } @@ -281,18 +342,15 @@ private function addJoinStatements($clause, $statement, $parameters = []) } /** - * Create join string + * Create join string. * - * @param $clause - * @param $mainTable - * @param $joinTable * @param string $joinAlias * * @return string */ private function createJoinStatement($clause, $mainTable, $joinTable, $joinAlias = '') { - if (in_array(substr($mainTable, -1), [':', '.'])) { + if (\in_array(substr($mainTable, -1), [':', '.'], true)) { $mainTable = substr($mainTable, 0, -1); } @@ -301,32 +359,32 @@ private function createJoinStatement($clause, $mainTable, $joinTable, $joinAlias $asJoinAlias = ''; if (!empty($joinAlias)) { - $asJoinAlias = " AS $joinAlias"; + $asJoinAlias = " AS {$joinAlias}"; } else { $joinAlias = $joinTable; } - if (in_array($joinAlias, $this->joins)) { // if the join exists don't create it again + if (\in_array($joinAlias, $this->joins, true)) { // if the join exists don't create it again return ''; - } else { - $this->joins[] = $joinAlias; } - if ($referenceDirection == ':') { // back reference + $this->joins[] = $joinAlias; + + if ($referenceDirection === ':') { // back reference $primaryKey = $this->getStructure()->getPrimaryKey($mainTable); $foreignKey = $this->getStructure()->getForeignKey($mainTable); - return " $clause $joinTable$asJoinAlias ON $joinAlias.$foreignKey = $mainTable.$primaryKey"; - } else { - $primaryKey = $this->getStructure()->getPrimaryKey($joinTable); - $foreignKey = $this->getStructure()->getForeignKey($joinTable); - - return " $clause $joinTable$asJoinAlias ON $joinAlias.$primaryKey = $mainTable.$foreignKey"; + return " {$clause} {$joinTable}{$asJoinAlias} ON {$joinAlias}.{$foreignKey} = {$mainTable}.{$primaryKey}"; } + + $primaryKey = $this->getStructure()->getPrimaryKey($joinTable); + $foreignKey = $this->getStructure()->getForeignKey($joinTable); + + return " {$clause} {$joinTable}{$asJoinAlias} ON {$joinAlias}.{$primaryKey} = {$mainTable}.{$foreignKey}"; } /** - * Create undefined joins from statement with column with referenced tables + * Create undefined joins from statement with column with referenced tables. * * @param string $statement * @@ -339,8 +397,9 @@ private function createUndefinedJoins($statement) } $separator = null; + // if we're in here, this is a where clause - if (is_array($statement)) { + if (\is_array($statement)) { $separator = $statement[0]; $statement = $statement[1]; } @@ -351,19 +410,19 @@ private function createUndefinedJoins($statement) foreach ($matches[1] as $join) { // remove the trailing dot and compare with the joins we already have - if (!in_array(substr($join, 0, -1), $this->joins)) { + if (!\in_array(substr($join, 0, -1), $this->joins, true)) { $this->addJoinStatements('LEFT JOIN', $join); } } // don't rewrite table from other databases foreach ($this->joins as $join) { - if (strpos($join, '.') !== false && strpos($statement, $join) === 0) { + if (str_contains($join, '.') && str_starts_with($statement, $join)) { // rebuild the where statement if ($separator !== null) { $statement = [$separator, $statement]; } - + return $statement; } } @@ -379,41 +438,6 @@ private function createUndefinedJoins($statement) } /** - * @throws Exception - * - * @return string - */ - protected function buildQuery() - { - // first create extra join from statements with columns with referenced tables - $statementsWithReferences = ['WHERE', 'SELECT', 'GROUP BY', 'ORDER BY']; - - foreach ($statementsWithReferences as $clause) { - if (array_key_exists($clause, $this->statements)) { - $this->statements[$clause] = array_map([$this, 'createUndefinedJoins'], $this->statements[$clause]); - } - } - - return parent::buildQuery(); - } - - /** - * @param $statement - * - * @return bool - */ - protected function isEscapedJoin($statement) - { - if (is_array($statement)) { - $statement = $statement[1]; - } - - return !$this->isSmartJoinEnabled || strpos($statement, '\.') !== false || strpos($statement, '\:') !== false; - } - - /** - * @param $statement - * * @return array */ private function setJoinNameAlias($statement) @@ -424,7 +448,8 @@ private function setJoinNameAlias($statement) if ($matches) { $joinTable = $matches[1]; - if (isset($matches[4]) && !in_array(strtoupper($matches[4]), ['ON', 'USING'])) { + + if (isset($matches[4]) && !\in_array(strtoupper($matches[4]), ['ON', 'USING'], true)) { $joinAlias = $matches[4]; } } @@ -433,23 +458,14 @@ private function setJoinNameAlias($statement) } /** - * @param $table - * @param $joinItem - * * @return bool */ - private function matchTableWithJoin($table, $joinItem) + private static function matchTableWithJoin($table, $joinItem) { - return $table == substr($joinItem, 0, -1); + return $table === substr($joinItem, 0, -1); } /** - * @param $clause - * @param $statement - * @param $parameters - * @param $joinAlias - * @param $joinTable - * * @return $this */ private function addRawJoins($clause, $statement, $parameters, $joinAlias, $joinTable) @@ -458,14 +474,14 @@ private function addRawJoins($clause, $statement, $parameters, $joinAlias, $join $joinAlias = $joinTable; } - if (in_array($joinAlias, $this->joins)) { + if (\in_array($joinAlias, $this->joins, true)) { return $this; - } else { - $this->joins[] = $joinAlias; - $statement = " $clause $statement"; - - return $this->addStatement('JOIN', $statement, $parameters); } + + $this->joins[] = $joinAlias; + $statement = " {$clause} {$statement}"; + + return $this->addStatement('JOIN', $statement, $parameters); } /** @@ -475,7 +491,9 @@ private function setMainTable() { if (isset($this->statements['FROM'])) { return $this->statements['FROM']; - } elseif (isset($this->statements['UPDATE'])) { + } + + if (isset($this->statements['UPDATE'])) { return $this->statements['UPDATE']; } @@ -483,20 +501,13 @@ private function setMainTable() } /** - * @param $clause - * @param $parameters - * @param $mainTable - * @param $joinItem - * @param $lastItem - * @param $joinAlias - * * @return mixed */ private function applyTableJoin($clause, $parameters, $mainTable, $joinItem, $lastItem, $joinAlias) { $alias = ''; - if ($joinItem == $lastItem) { + if ($joinItem === $lastItem) { $alias = $joinAlias; // use $joinAlias only for $lastItem } @@ -508,13 +519,4 @@ private function applyTableJoin($clause, $parameters, $mainTable, $joinItem, $la return $joinItem; } - - public function __clone() - { - foreach ($this->clauses as $clause => $value) { - if (is_array($value) && $value[0] instanceof Common) { - $this->clauses[$clause][0] = $this; - } - } - } } diff --git a/src/Queries/Delete.php b/src/Queries/Delete.php index 49c74d9..f270c69 100644 --- a/src/Queries/Delete.php +++ b/src/Queries/Delete.php @@ -1,41 +1,47 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO\Queries; -use Envms\FluentPDO\{Exception, Query}; +use Envms\FluentPDO\Exception; +use Envms\FluentPDO\Query; /** - * DELETE query builder + * DELETE query builder. * - * @method Delete leftJoin(string $statement) add LEFT JOIN to query - * ($statement can be 'table' name only or 'table:' means back reference) - * @method Delete innerJoin(string $statement) add INNER JOIN to query - * ($statement can be 'table' name only or 'table:' means back reference) - * @method Delete from(string $table) add LIMIT to query - * @method Delete orderBy(string $column) add ORDER BY to query - * @method Delete limit(int $limit) add LIMIT to query + * @method Delete innerJoin(string $statement) add INNER JOIN to query + * ($statement can be 'table' name only or 'table:' means back reference) + * @method Delete from(string $table) add LIMIT to query + * @method Delete limit(int $limit) add LIMIT to query + * @method Delete orderBy(string $column) add ORDER BY to query */ class Delete extends Common { - - private $ignore = false; + private bool $ignore = false; /** - * Delete constructor - * - * @param Query $fluent - * @param string $table + * Delete constructor. */ public function __construct(Query $fluent, string $table) { $clauses = [ 'DELETE FROM' => [$this, 'getClauseDeleteFrom'], - 'DELETE' => [$this, 'getClauseDelete'], - 'FROM' => null, - 'JOIN' => [$this, 'getClauseJoin'], - 'WHERE' => [$this, 'getClauseWhere'], - 'ORDER BY' => ', ', - 'LIMIT' => null, + 'DELETE' => [$this, 'getClauseDelete'], + 'FROM' => null, + 'JOIN' => [$this, 'getClauseJoin'], + 'WHERE' => [$this, 'getClauseWhere'], + 'ORDER BY' => ', ', + 'LIMIT' => null, ]; parent::__construct($fluent, $clauses); @@ -45,7 +51,7 @@ public function __construct(Query $fluent, string $table) } /** - * Forces delete operation to fail silently + * Forces delete operation to fail silently. * * @return Delete */ @@ -57,23 +63,7 @@ public function ignore() } /** - * @throws Exception - * - * @return string - */ - protected function buildQuery() - { - if ($this->statements['FROM']) { - unset($this->clauses['DELETE FROM']); - } else { - unset($this->clauses['DELETE']); - } - - return parent::buildQuery(); - } - - /** - * Execute DELETE query + * Execute DELETE query. * * @throws Exception * @@ -86,6 +76,7 @@ public function execute() } $result = parent::execute(); + if ($result) { return $result->rowCount(); } @@ -93,12 +84,28 @@ public function execute() return false; } + /** + * @throws Exception + * + * @return string + */ + protected function buildQuery() + { + if ($this->statements['FROM']) { + unset($this->clauses['DELETE FROM']); + } else { + unset($this->clauses['DELETE']); + } + + return parent::buildQuery(); + } + /** * @return string */ protected function getClauseDelete() { - return 'DELETE' . ($this->ignore ? " IGNORE" : '') . ' ' . $this->statements['DELETE']; + return 'DELETE'.($this->ignore ? ' IGNORE' : '').' '.$this->statements['DELETE']; } /** @@ -106,7 +113,6 @@ protected function getClauseDelete() */ protected function getClauseDeleteFrom() { - return 'DELETE' . ($this->ignore ? " IGNORE" : '') . ' FROM ' . $this->statements['DELETE FROM']; + return 'DELETE'.($this->ignore ? ' IGNORE' : '').' FROM '.$this->statements['DELETE FROM']; } - } diff --git a/src/Queries/Insert.php b/src/Queries/Insert.php index ff0b302..10750d0 100644 --- a/src/Queries/Insert.php +++ b/src/Queries/Insert.php @@ -1,39 +1,47 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO\Queries; -use Envms\FluentPDO\{Exception, Literal, Query}; +use Envms\FluentPDO\Exception; +use Envms\FluentPDO\Literal; +use Envms\FluentPDO\Query; -/** INSERT query builder +/** + * INSERT query builder. */ class Insert extends Base { + private array $columns = []; - /** @var array */ - private $columns = []; + private array $firstValue = []; - /** @var array */ - private $firstValue = []; + private bool $ignore = false; - /** @var bool */ - private $ignore = false; - /** @var bool */ - private $delayed = false; + private bool $delayed = false; /** * InsertQuery constructor. * - * @param Query $fluent - * @param string $table - * @param $values + * @param string $table * * @throws Exception */ public function __construct(Query $fluent, $table, $values) { $clauses = [ - 'INSERT INTO' => [$this, 'getClauseInsertInto'], - 'VALUES' => [$this, 'getClauseValues'], + 'INSERT INTO' => [$this, 'getClauseInsertInto'], + 'VALUES' => [$this, 'getClauseValues'], 'ON DUPLICATE KEY UPDATE' => [$this, 'getClauseOnDuplicateKeyUpdate'], ]; parent::__construct($fluent, $clauses); @@ -43,7 +51,7 @@ public function __construct(Query $fluent, $table, $values) } /** - * Force insert operation to fail silently + * Force insert operation to fail silently. * * @return Insert */ @@ -54,7 +62,8 @@ public function ignore() return $this; } - /** Force insert operation delay support + /** + * Force insert operation delay support. * * @return Insert */ @@ -66,24 +75,24 @@ public function delayed() } /** - * Add VALUES + * Add VALUES. * - * @param $values + * @throws Exception * * @return Insert - * @throws Exception */ public function values($values) { - if (!is_array($values)) { + if (!\is_array($values)) { throw new Exception('Param VALUES for INSERT query must be array'); } $first = current($values); - if (is_string(key($values))) { + + if (\is_string(key($values))) { // is one row array $this->addOneValue($values); - } elseif (is_array($first) && is_string(key($first))) { + } elseif (\is_array($first) && \is_string(key($first))) { // this is multi values foreach ($values as $oneValue) { $this->addOneValue($oneValue); @@ -94,7 +103,7 @@ public function values($values) } /** - * Add ON DUPLICATE KEY UPDATE + * Add ON DUPLICATE KEY UPDATE. * * @param array $values * @@ -103,20 +112,21 @@ public function values($values) public function onDuplicateKeyUpdate($values) { $this->statements['ON DUPLICATE KEY UPDATE'] = array_merge( - $this->statements['ON DUPLICATE KEY UPDATE'], $values + $this->statements['ON DUPLICATE KEY UPDATE'], + $values, ); return $this; } /** - * Execute insert query + * Execute insert query. * * @param mixed $sequence * * @throws Exception * - * @return int|bool - Last inserted primary key + * @return bool|int - Last inserted primary key */ public function execute($sequence = null) { @@ -152,7 +162,7 @@ public function executeWithoutId($sequence = null) */ protected function getClauseInsertInto() { - return 'INSERT' . ($this->ignore ? " IGNORE" : '') . ($this->delayed ? " DELAYED" : '') . ' INTO ' . $this->statements['INSERT INTO']; + return 'INSERT'.($this->ignore ? ' IGNORE' : '').($this->delayed ? ' DELAYED' : '').' INTO '.$this->statements['INSERT INTO']; } /** @@ -161,60 +171,57 @@ protected function getClauseInsertInto() protected function getClauseValues() { $valuesArray = []; + foreach ($this->statements['VALUES'] as $rows) { // literals should not be parametrized. // They are commonly used to call engine functions or literals. // Eg: NOW(), CURRENT_TIMESTAMP etc $placeholders = array_map([$this, 'parameterGetValue'], $rows); - $valuesArray[] = '(' . implode(', ', $placeholders) . ')'; + $valuesArray[] = '('.implode(', ', $placeholders).')'; } $columns = implode(', ', $this->columns); $values = implode(', ', $valuesArray); - return " ($columns) VALUES $values"; + return " ({$columns}) VALUES {$values}"; } - /** * @return string */ protected function getClauseOnDuplicateKeyUpdate() { $result = []; + foreach ($this->statements['ON DUPLICATE KEY UPDATE'] as $key => $value) { - $result[] = "$key = " . $this->parameterGetValue($value); + $result[] = "{$key} = ".$this->parameterGetValue($value); } - return ' ON DUPLICATE KEY UPDATE ' . implode(', ', $result); + return ' ON DUPLICATE KEY UPDATE '.implode(', ', $result); } /** - * @param $param - * * @return string */ protected function parameterGetValue($param) { - return $param instanceof Literal ? (string)$param : '?'; + return $param instanceof Literal ? (string) $param : '?'; } /** * Removes all Literal instances from the argument - * since they are not to be used as PDO parameters but rather injected directly into the query - * - * @param $statements + * since they are not to be used as PDO parameters but rather injected directly into the query. * * @return array */ protected function filterLiterals($statements) { - $f = function ($item) { + $f = static function ($item) { return !$item instanceof Literal; }; - return array_map(function ($item) use ($f) { - if (is_array($item)) { + return array_map(static function ($item) use ($f) { + if (\is_array($item)) { return array_filter($item, $f); } @@ -222,14 +229,11 @@ protected function filterLiterals($statements) }, array_filter($statements, $f)); } - /** - * @return array - */ protected function buildParameters(): array { $this->parameters = array_merge( $this->filterLiterals($this->statements['VALUES']), - $this->filterLiterals($this->statements['ON DUPLICATE KEY UPDATE']) + $this->filterLiterals($this->statements['ON DUPLICATE KEY UPDATE']), ); return parent::buildParameters(); @@ -240,24 +244,27 @@ protected function buildParameters(): array * * @throws Exception */ - private function addOneValue($oneValue) + private function addOneValue($oneValue): void { // check if all $keys are strings foreach ($oneValue as $key => $value) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new Exception('INSERT query: All keys of value array have to be strings.'); } } + if (!$this->firstValue) { $this->firstValue = $oneValue; } + if (!$this->columns) { $this->columns = array_keys($oneValue); } - if ($this->columns != array_keys($oneValue)) { + + if ($this->columns !== array_keys($oneValue)) { throw new Exception('INSERT query: All VALUES have to same keys (columns).'); } + $this->statements['VALUES'][] = $oneValue; } - } diff --git a/src/Queries/Json.php b/src/Queries/Json.php index a37cf72..5e6b1b5 100644 --- a/src/Queries/Json.php +++ b/src/Queries/Json.php @@ -1,41 +1,46 @@ * - * @package Envms\FluentPDO\Queries + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Envms\FluentPDO\Queries; + +use Envms\FluentPDO\Query; + +/** + * Class Json. */ class Json extends Common { + protected mixed $fromTable; - /** @var mixed */ - protected $fromTable; - /** @var mixed */ - protected $fromAlias; - /** @var boolean */ - protected $convertTypes = false; + protected mixed $fromAlias; + + protected bool $convertTypes = false; /** - * Json constructor - * - * @param Query $fluent - * @param string $table + * Json constructor. */ public function __construct(Query $fluent, string $table) { $clauses = [ - 'SELECT' => ', ', - 'JOIN' => [$this, 'getClauseJoin'], - 'WHERE' => [$this, 'getClauseWhere'], + 'SELECT' => ', ', + 'JOIN' => [$this, 'getClauseJoin'], + 'WHERE' => [$this, 'getClauseWhere'], 'GROUP BY' => ',', - 'HAVING' => ' AND ', + 'HAVING' => ' AND ', 'ORDER BY' => ', ', - 'LIMIT' => null, - 'OFFSET' => null, - "\n--" => "\n--", + 'LIMIT' => null, + 'OFFSET' => null, + "\n--" => "\n--", ]; parent::__construct($fluent, $clauses); @@ -52,5 +57,4 @@ public function __construct(Query $fluent, string $table) $this->convertTypes = true; } } - -} \ No newline at end of file +} diff --git a/src/Queries/Select.php b/src/Queries/Select.php index 31ef371..3a4393b 100644 --- a/src/Queries/Select.php +++ b/src/Queries/Select.php @@ -1,39 +1,47 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO\Queries; -use Envms\FluentPDO\{Exception, Query, Utilities}; +use Envms\FluentPDO\Exception; +use Envms\FluentPDO\Query; +use Envms\FluentPDO\Utilities; /** - * SELECT query builder + * SELECT query builder. */ class Select extends Common implements \Countable { + private mixed $fromTable; - /** @var mixed */ - private $fromTable; - /** @var mixed */ - private $fromAlias; + private mixed $fromAlias; /** * SelectQuery constructor. - * - * @param Query $fluent - * @param $from */ - function __construct(Query $fluent, $from) + public function __construct(Query $fluent, $from) { $clauses = [ - 'SELECT' => ', ', - 'FROM' => null, - 'JOIN' => [$this, 'getClauseJoin'], - 'WHERE' => [$this, 'getClauseWhere'], + 'SELECT' => ', ', + 'FROM' => null, + 'JOIN' => [$this, 'getClauseJoin'], + 'WHERE' => [$this, 'getClauseWhere'], 'GROUP BY' => ',', - 'HAVING' => ' AND ', + 'HAVING' => ' AND ', 'ORDER BY' => ', ', - 'LIMIT' => null, - 'OFFSET' => null, - "\n--" => "\n--" + 'LIMIT' => null, + 'OFFSET' => null, + "\n--" => "\n--", ]; parent::__construct($fluent, $clauses); @@ -43,13 +51,12 @@ function __construct(Query $fluent, $from) $this->fromAlias = end($fromParts); $this->statements['FROM'] = $from; - $this->statements['SELECT'][] = $this->fromAlias . '.*'; + $this->statements['SELECT'][] = $this->fromAlias.'.*'; $this->joins[] = $this->fromAlias; } /** * @param mixed $columns - * @param bool $overrideDefault * * @return $this */ @@ -67,7 +74,7 @@ public function select($columns, bool $overrideDefault = false) } /** - * Return table name from FROM clause + * Return table name from FROM clause. */ public function getFromTable() { @@ -75,7 +82,7 @@ public function getFromTable() } /** - * Return table alias from FROM clause + * Return table alias from FROM clause. */ public function getFromAlias() { @@ -83,9 +90,7 @@ public function getFromAlias() } /** - * Returns a single column - * - * @param int $columnNumber + * Returns a single column. * * @throws Exception * @@ -101,10 +106,9 @@ public function fetchColumn(int $columnNumber = 0) } /** - * Fetch first row or column + * Fetch first row or column. * * @param string $column - column name or empty string for the whole row - * @param int $cursorOrientation * * @throws Exception * @@ -127,22 +131,18 @@ public function fetch(?string $column = null, int $cursorOrientation = \PDO::FET } if ($row && $column !== null) { - if (is_object($row)) { + if (\is_object($row)) { return $row->{$column}; - } else { - return $row[$column]; } + + return $row[$column]; } return $row; } /** - * Fetch pairs - * - * @param $key - * @param $value - * @param $object + * Fetch pairs. * * @throws Exception * @@ -150,14 +150,15 @@ public function fetch(?string $column = null, int $cursorOrientation = \PDO::FET */ public function fetchPairs($key, $value, $object = false) { - if (($s = $this->select("$key, $value", true)->asObject($object)->execute()) !== false) { + if (($s = $this->select("{$key}, {$value}", true)->asObject($object)->execute()) !== false) { return $s->fetchAll(\PDO::FETCH_KEY_PAIR); } return $s; } - /** Fetch all row + /** + * Fetch all row. * * @param string $index - specify index column. Allows for data organization by field using 'field[]' * @param string $selectOnly - select columns which could be fetched @@ -175,26 +176,26 @@ public function fetchAll($index = '', $selectOnly = '') } if ($selectOnly) { - $this->select($index . ', ' . $selectOnly, true); + $this->select($index.', '.$selectOnly, true); } if ($index) { return $this->buildSelectData($index, $indexAsArray); - } else { - if (($result = $this->execute()) !== false) { - if ($this->fluent->convertRead === true) { - return Utilities::stringToNumeric($result, $result->fetchAll()); - } else { - return $result->fetchAll(); - } + } + + if (($result = $this->execute()) !== false) { + if ($this->fluent->convertRead === true) { + return Utilities::stringToNumeric($result, $result->fetchAll()); } - return false; + return $result->fetchAll(); } + + return false; } /** - * \Countable interface doesn't break current select query + * \Countable interface doesn't break current select query. * * @throws Exception * @@ -205,7 +206,7 @@ public function count() { $fluent = clone $this; - return (int)$fluent->select('COUNT(*)', true)->fetchColumn(); + return (int) $fluent->select('COUNT(*)', true)->fetchColumn(); } /** @@ -217,15 +218,12 @@ public function getIterator() { if ($this->fluent->convertRead === true) { return new \ArrayIterator($this->fetchAll()); - } else { - return $this->execute(); } + + return $this->execute(); } /** - * @param $index - * @param $indexAsArray - * * @return array */ private function buildSelectData($index, $indexAsArray) @@ -233,7 +231,7 @@ private function buildSelectData($index, $indexAsArray) $data = []; foreach ($this as $row) { - if (is_object($row)) { + if (\is_object($row)) { $key = $row->{$index}; } else { $key = $row[$index]; diff --git a/src/Queries/Update.php b/src/Queries/Update.php index d3ebd8b..08f93ea 100644 --- a/src/Queries/Update.php +++ b/src/Queries/Update.php @@ -1,37 +1,44 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO\Queries; -use Envms\FluentPDO\{Exception, Literal, Query}; +use Envms\FluentPDO\Exception; +use Envms\FluentPDO\Literal; +use Envms\FluentPDO\Query; /** - * UPDATE query builder + * UPDATE query builder. * - * @method Update leftJoin(string $statement) add LEFT JOIN to query - * ($statement can be 'table' name only or 'table:' means back reference) - * @method Update innerJoin(string $statement) add INNER JOIN to query - * ($statement can be 'table' name only or 'table:' means back reference) - * @method Update orderBy(string $column) add ORDER BY to query - * @method Update limit(int $limit) add LIMIT to query + * @method Update innerJoin(string $statement) add INNER JOIN to query + * ($statement can be 'table' name only or 'table:' means back reference) + * @method Update limit(int $limit) add LIMIT to query + * @method Update orderBy(string $column) add ORDER BY to query */ class Update extends Common { - /** - * UpdateQuery constructor - * - * @param Query $fluent - * @param string $table + * UpdateQuery constructor. */ public function __construct(Query $fluent, string $table) { $clauses = [ - 'UPDATE' => [$this, 'getClauseUpdate'], - 'JOIN' => [$this, 'getClauseJoin'], - 'SET' => [$this, 'getClauseSet'], - 'WHERE' => [$this, 'getClauseWhere'], + 'UPDATE' => [$this, 'getClauseUpdate'], + 'JOIN' => [$this, 'getClauseJoin'], + 'SET' => [$this, 'getClauseSet'], + 'WHERE' => [$this, 'getClauseWhere'], 'ORDER BY' => ', ', - 'LIMIT' => null, + 'LIMIT' => null, ]; parent::__construct($fluent, $clauses); @@ -42,9 +49,9 @@ public function __construct(Query $fluent, string $table) } /** - * In Update's case, parameters are not assigned until the query is built, since this method + * In Update's case, parameters are not assigned until the query is built, since this method. * - * @param string|array $fieldOrArray + * @param array|string $fieldOrArray * @param bool|string $value * * @throws Exception @@ -56,15 +63,16 @@ public function set($fieldOrArray, $value = false) if (!$fieldOrArray) { return $this; } - if (is_string($fieldOrArray) && $value !== false) { + + if (\is_string($fieldOrArray) && $value !== false) { $this->statements['SET'][$fieldOrArray] = $value; } else { - if (!is_array($fieldOrArray)) { + if (!\is_array($fieldOrArray)) { throw new Exception('You must pass a value, or provide the SET list as an associative array. column => value'); - } else { - foreach ($fieldOrArray as $field => $value) { - $this->statements['SET'][$field] = $value; - } + } + + foreach ($fieldOrArray as $field => $value) { + $this->statements['SET'][$field] = $value; } } @@ -72,13 +80,13 @@ public function set($fieldOrArray, $value = false) } /** - * Execute update query + * Execute update query. * - * @param boolean $getResultAsPdoStatement true to return the pdo statement instead of row count + * @param bool $getResultAsPdoStatement true to return the pdo statement instead of row count * * @throws Exception * - * @return int|boolean|\PDOStatement + * @return bool|int|\PDOStatement */ public function execute($getResultAsPdoStatement = false) { @@ -104,7 +112,7 @@ public function execute($getResultAsPdoStatement = false) */ protected function getClauseUpdate() { - return 'UPDATE ' . $this->statements['UPDATE']; + return 'UPDATE '.$this->statements['UPDATE']; } /** @@ -113,22 +121,21 @@ protected function getClauseUpdate() protected function getClauseSet() { $setArray = []; + foreach ($this->statements['SET'] as $field => $value) { // named params are being used here - if (is_array($value) && strpos(key($value), ':') === 0) { + if (\is_array($value) && str_starts_with(key($value), ':')) { $key = key($value); - $setArray[] = $field . ' = ' . $key; + $setArray[] = $field.' = '.$key; $this->parameters['SET'][$key] = $value[$key]; - } - elseif ($value instanceof Literal) { - $setArray[] = $field . ' = ' . $value; + } elseif ($value instanceof Literal) { + $setArray[] = $field.' = '.$value; } else { - $setArray[] = $field . ' = ?'; + $setArray[] = $field.' = ?'; $this->parameters['SET'][$field] = $value; } } - return ' SET ' . implode(', ', $setArray); + return ' SET '.implode(', ', $setArray); } - } diff --git a/src/Query.php b/src/Query.php index 4c5d49d..13bf804 100644 --- a/src/Query.php +++ b/src/Query.php @@ -1,62 +1,80 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO; +use Envms\FluentPDO\Queries\Delete; +use Envms\FluentPDO\Queries\Insert; +use Envms\FluentPDO\Queries\Select; +use Envms\FluentPDO\Queries\Update; use PDO; -use Envms\FluentPDO\Queries\{Insert, Select, Update, Delete}; /** * FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins. * * For more information see readme.md * - * @link https://github.com/envms/fluentpdo + * @see https://github.com/envms/fluentpdo + * * @author Chris Bornhoft, start@env.ms * @copyright 2012-2020 envms - Chris Bornhoft, Marek Lichtner * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License, version 3.0 */ /** - * Class Query + * Class Query. + * * @method debug(Queries\Base $param) */ class Query { - /** @var PDO */ - protected $pdo; - /** @var Structure */ - protected $structure; - /** @var bool|callable */ - public $debug = false; + public mixed $debug = false; + + /** + * @var bool - Determines whether to convert types when fetching rows from Select + */ + public bool $convertRead = false; + + /** + * @var bool - Determines whether to convert types within Base::buildParameters() + */ + public bool $convertWrite = false; + + /** + * @var bool - If a query errors, this determines how to handle it + */ + public bool $exceptionOnError = false; + + protected \PDO $pdo; + + protected Structure $structure; - /** @var bool - Determines whether to convert types when fetching rows from Select */ - public $convertRead = false; - /** @var bool - Determines whether to convert types within Base::buildParameters() */ - public $convertWrite = false; + protected string $table; - /** @var bool - If a query errors, this determines how to handle it */ - public $exceptionOnError = false; + protected string $prefix; - /** @var string */ - protected $table; - /** @var string */ - protected $prefix; - /** @var string */ - protected $separator; + protected string $separator; /** - * Query constructor - * - * @param PDO $pdo - * @param ?Structure $structure + * Query constructor. */ - public function __construct(PDO $pdo, ?Structure $structure = null) + public function __construct(\PDO $pdo, ?Structure $structure = null) { $this->pdo = $pdo; // if exceptions are already activated in PDO, activate them in Fluent as well - if ($this->pdo->getAttribute(PDO::ATTR_ERRMODE) === PDO::ERRMODE_EXCEPTION) { + if ($this->pdo->getAttribute(\PDO::ATTR_ERRMODE) === \PDO::ERRMODE_EXCEPTION) { $this->throwExceptionOnError(true); } @@ -64,13 +82,11 @@ public function __construct(PDO $pdo, ?Structure $structure = null) } /** - * Create SELECT query from $table + * Create SELECT query from $table. * * @param ?string $table - db table name * @param ?int $primaryKey - return one row by primary key * - * @return Select - * * @throws Exception */ public function from(?string $table = null, ?int $primaryKey = null): Select @@ -84,19 +100,16 @@ public function from(?string $table = null, ?int $primaryKey = null): Select $tableTable = $query->getFromTable(); $tableAlias = $query->getFromAlias(); $primaryKeyName = $this->structure->getPrimaryKey($tableTable); - $query = $query->where("$tableAlias.$primaryKeyName", $primaryKey); + $query = $query->where("{$tableAlias}.{$primaryKeyName}", $primaryKey); } return $query; } /** - * Create INSERT INTO query - * - * @param ?string $table - * @param array $values - accepts one or multiple rows, @see docs + * Create INSERT INTO query. * - * @return Insert + * @param array $values - accepts one or multiple rows, @see docs * * @throws Exception */ @@ -109,13 +122,9 @@ public function insertInto(?string $table = null, array $values = []): Insert } /** - * Create UPDATE query + * Create UPDATE query. * - * @param ?string $table * @param array|string $set - * @param ?int $primaryKey - * - * @return Update * * @throws Exception */ @@ -127,6 +136,7 @@ public function update(?string $table = null, $set = [], ?int $primaryKey = null $query = new Update($this, $table); $query->set($set); + if ($primaryKey) { $primaryKeyName = $this->getStructure()->getPrimaryKey($this->table); $query = $query->where($primaryKeyName, $primaryKey); @@ -136,12 +146,9 @@ public function update(?string $table = null, $set = [], ?int $primaryKey = null } /** - * Create DELETE query - * - * @param ?string $table - * @param ?int $primaryKey delete only row by primary key + * Create DELETE query. * - * @return Delete + * @param ?int $primaryKey delete only row by primary key * * @throws Exception */ @@ -161,38 +168,27 @@ public function delete(?string $table = null, ?int $primaryKey = null): Delete } /** - * Create DELETE FROM query - * - * @param ?string $table - * @param ?int $primaryKey - * - * @return Delete + * Create DELETE FROM query. */ public function deleteFrom(?string $table = null, ?int $primaryKey = null): Delete { - $args = func_get_args(); + $args = \func_get_args(); - return call_user_func_array([$this, 'delete'], $args); + return \call_user_func_array([$this, 'delete'], $args); } - /** - * @return PDO - */ - public function getPdo(): PDO + public function getPdo(): \PDO { return $this->pdo; } - /** - * @return Structure - */ public function getStructure(): Structure { return $this->structure; } /** - * Closes the \PDO connection to the database + * Closes the \PDO connection to the database. */ public function close(): void { @@ -200,17 +196,13 @@ public function close(): void } /** - * Set table name comprised of prefix.separator.table + * Set table name comprised of prefix.separator.table. * - * @param ?string $table - * @param string $prefix - * @param string $separator + * @throws Exception * * @return $this - * - * @throws Exception */ - public function setTableName(?string $table = '', string $prefix = '', string $separator = ''): Query + public function setTableName(?string $table = '', string $prefix = '', string $separator = ''): self { if ($table !== null) { $this->prefix = $prefix; @@ -225,67 +217,42 @@ public function setTableName(?string $table = '', string $prefix = '', string $s return $this; } - /** - * @return string - */ public function getFullTableName(): string { - return $this->prefix . $this->separator . $this->table; + return $this->prefix.$this->separator.$this->table; } - /** - * @return string - */ public function getPrefix(): string { return $this->prefix; } - /** - * @return string - */ public function getSeparator(): string { return $this->separator; } - /** - * @return string - */ public function getTable(): string { return $this->table; } - /** - * @param bool $flag - */ public function throwExceptionOnError(bool $flag): void { $this->exceptionOnError = $flag; } - /** - * @param bool $read - * @param bool $write - */ public function convertTypes(bool $read, bool $write): void { $this->convertRead = $read; $this->convertWrite = $write; } - /** - * @param bool $flag - */ public function convertReadTypes(bool $flag): void { $this->convertRead = $flag; } - /** - * @param bool $flag - */ public function convertWriteTypes(bool $flag): void { $this->convertWrite = $flag; diff --git a/src/Regex.php b/src/Regex.php index e24b0ca..aeef4bf 100644 --- a/src/Regex.php +++ b/src/Regex.php @@ -1,27 +1,42 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO; /** - * Regex class + * Regex class. */ class Regex { - /** @var string - All UTF-8 letter characters */ + /** + * @var string - All UTF-8 letter characters + */ public const ALPHA = '\p{L}'; - /** @var string - All UTF-8 letter and number characters */ + + /** + * @var string - All UTF-8 letter and number characters + */ public const ALNUM = '\p{L}\p{N}'; - /** @var string - All valid SQL characters except the UTF-8 groupings with quotes and wildcards */ + + /** + * @var string - All valid SQL characters except the UTF-8 groupings with quotes and wildcards + */ public const SQLCHARS = '\p{L}\p{N}\p{Pc}\p{Pd}\p{Pf}\p{Pi}'; /** - * Replace "camelCaseMethod" with "camel Case Method" - * - * @param string $subject - * - * @return null|string|string[] + * Replace "camelCaseMethod" with "camel Case Method". */ - public function camelCaseSpaced(string $subject) + public function camelCaseSpaced(string $subject): array|string|null { return preg_replace('/(.)([A-Z]+)/', '$1 $2', $subject); } @@ -30,133 +45,90 @@ public function camelCaseSpaced(string $subject) * Replace "SELECT * FROM table WHERE column = ?" with * "SELECT * * FROM table - * WHERE column = ?" - * - * @param string $subject - * - * @return null|string|string[] + * WHERE column = ?". */ - public function splitClauses(string $subject) + public function splitClauses(string $subject): array|string|null { return preg_replace( '/\b(WHERE|FROM|GROUP BY|HAVING|ORDER BY|LIMIT|OFFSET|UNION|ON DUPLICATE KEY UPDATE|VALUES|SET)\b/', "\n$0", - $subject + $subject, ); } /** * Replace SELECT t2.id FROM t1 LEFT JOIN t2 ON t2.id = t1.t2_id" with * "SELECT t2.id FROM t1 - * LEFT JOIN t2 ON t2.id = t1.t2_id" - * - * @param string $subject - * - * @return null|string|string[] + * LEFT JOIN t2 ON t2.id = t1.t2_id". */ - public function splitSubClauses(string $subject) + public function splitSubClauses(string $subject): array|string|null { return preg_replace( '/\b(INNER|OUTER|LEFT|RIGHT|FULL|CASE|WHEN|END|ELSE|AND|OR)\b/', "\n $0", - $subject + $subject, ); } /** - * Replace "WHERE column = ? " with "WHERE column = ?" - * - * @param string $subject - * - * @return null|string|string[] + * Replace "WHERE column = ? " with "WHERE column = ?". */ - public function removeLineEndWhitespace(string $subject) + public function removeLineEndWhitespace(string $subject): array|string|null { - return preg_replace("/\s+\n/", "\n", $subject); + return preg_replace("/\\s+\n/", "\n", $subject); } /** - * Replace the string "table1.table2:column" with "table2.column" - * - * @param string $subject - * - * @return null|string|string[] + * Replace the string "table1.table2:column" with "table2.column". */ - public function removeAdditionalJoins(string $subject) + public function removeAdditionalJoins(string $subject): array|string|null { return preg_replace('/(?:[^\s]*[.:])?([^\s]+)[.:]([^\s]*)/u', '$1.$2', $subject); } /** - * Match the first file outside of the Fluent source - * - * @param string $subject - * @param ?array $matches - * @param ?string $directory - * - * @return false|int + * Match the first file outside of the Fluent source. */ - public function compareLocation(string $subject, &$matches = null, $directory = null) + public function compareLocation(string $subject, mixed &$matches = null, ?string $directory = null): false|int { $directory = ($directory === null) ? preg_quote(__DIR__, '/') : preg_quote($directory, '/'); - return preg_match('/(^' . $directory . '(\\.php$|[\/\\\\]))/', $subject, $matches); + return preg_match('/(^'.$directory.'(\\.php$|[\/\\\\]))/', $subject, $matches); } /** - * Match the string "?" or ":param" - * - * @param string $subject - * @param array|null $matches - * - * @return false|int + * Match the string "?" or ":param". */ - public function sqlParameter(string $subject, &$matches = null) + public function sqlParameter(string $subject, mixed &$matches = null): false|int { return preg_match('/(\?|:\w+)/', $subject, $matches); } /** - * Match the UTF-8 string "table AS alias" - * - * @param string $subject - * @param array|null $matches - * - * @return false|int + * Match the UTF-8 string "table AS alias". */ - public function tableAlias(string $subject, &$matches = null) + public function tableAlias(string $subject, mixed &$matches = null): false|int { return preg_match( - '/`?([' . self::SQLCHARS . ']+[.:]?[' . self::SQLCHARS . '*]*)`?(\s+AS)?(\s+`?([' . self::SQLCHARS . ']*)`?)?/ui', + '/`?(['.self::SQLCHARS.']+[.:]?['.self::SQLCHARS.'*]*)`?(\s+AS)?(\s+`?(['.self::SQLCHARS.']*)`?)?/ui', $subject, - $matches + $matches, ); } /** - * Match the UTF-8 string "table" or "table." - * - * @param string $subject - * @param array|null $matches - * - * @return false|int + * Match the UTF-8 string "table" or "table.". */ - public function tableJoin(string $subject, &$matches = null) + public function tableJoin(string $subject, mixed &$matches = null): false|int { - return preg_match_all('/([' . self::SQLCHARS . ']+[.:]?)/u', $subject, $matches); + return preg_match_all('/(['.self::SQLCHARS.']+[.:]?)/u', $subject, $matches); } /** - * Match the UTF-8 string "table." or "table.column" - * - * @param string $subject - * @param array|null $matches - * - * @return false|int + * Match the UTF-8 string "table." or "table.column". */ - public function tableJoinFull(string $subject, &$matches = null) + public function tableJoinFull(string $subject, mixed &$matches = null): false|int { - return preg_match_all('/([^[:space:]()]+[.:])[' . self::SQLCHARS . ']*/u', $subject, $matches); + return preg_match_all('/([^[:space:]()]+[.:])['.self::SQLCHARS.']*/u', $subject, $matches); } - } diff --git a/src/Structure.php b/src/Structure.php index ab45bd7..5696693 100644 --- a/src/Structure.php +++ b/src/Structure.php @@ -1,66 +1,56 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO; /** - * Class Structure + * Class Structure. */ class Structure { + private string $primaryKey; - /** @var string */ - private $primaryKey; - /** @var string */ - private $foreignKey; + private string $foreignKey; /** - * Structure constructor - * - * @param string $primaryKey - * @param string $foreignKey + * Structure constructor. */ - function __construct($primaryKey = 'id', $foreignKey = '%s_id') + public function __construct(string $primaryKey = 'id', string $foreignKey = '%s_id') { if ($foreignKey === null) { $foreignKey = $primaryKey; } + $this->primaryKey = $primaryKey; $this->foreignKey = $foreignKey; } - /** - * @param string $table - * - * @return string - */ - public function getPrimaryKey($table) + public function getPrimaryKey(string $table): string { - return $this->key($this->primaryKey, $table); + return self::key($this->primaryKey, $table); } - /** - * @param string $table - * - * @return string - */ - public function getForeignKey($table) + public function getForeignKey(string $table): string { - return $this->key($this->foreignKey, $table); + return self::key($this->foreignKey, $table); } - /** - * @param string|callback $key - * @param string $table - * - * @return string - */ - private function key($key, $table) + private static function key(callable|string $key, string $table): string { - if (is_callable($key)) { + if (\is_callable($key)) { return $key($table); } return sprintf($key, $table); } - } diff --git a/src/Utilities.php b/src/Utilities.php index 3c939f7..2c33e18 100644 --- a/src/Utilities.php +++ b/src/Utilities.php @@ -1,52 +1,51 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Envms\FluentPDO; /** - * Class Utilities + * Class Utilities. */ class Utilities { /** - * Convert "camelCaseWord" to "CAMEL CASE WORD" - * - * @param string $string - * - * @return string + * Convert "camelCaseWord" to "CAMEL CASE WORD". */ - public static function toUpperWords($string) + public static function toUpperWords(string $string): string { $regex = new Regex(); + return trim(strtoupper($regex->camelCaseSpaced($string))); } - /** - * @param string $query - * - * @return string - */ - public static function formatQuery($query) + public static function formatQuery(string $query): string { $regex = new Regex(); $query = $regex->splitClauses($query); $query = $regex->splitSubClauses($query); - $query = $regex->removeLineEndWhitespace($query); - return $query; + return $regex->removeLineEndWhitespace($query); } /** - * Converts columns from strings to types according to PDOStatement::columnMeta() + * Converts columns from strings to types according to PDOStatement::columnMeta(). * - * @param \PDOStatement $statement * @param array|\Traversable $rows - provided by PDOStatement::fetch with PDO::FETCH_ASSOC - * - * @return array|\Traversable */ - public static function stringToNumeric(\PDOStatement $statement, $rows) + public static function stringToNumeric(\PDOStatement $statement, mixed $rows): mixed { - for ($i = 0; ($columnMeta = $statement->getColumnMeta($i)) !== false; $i++) { + for ($i = 0; ($columnMeta = $statement->getColumnMeta($i)) !== false; ++$i) { $type = $columnMeta['native_type']; switch ($type) { @@ -60,18 +59,21 @@ public static function stringToNumeric(\PDOStatement $statement, $rows) case 'SHORT': case 'TINY': if (isset($rows[$columnMeta['name']])) { - $rows[$columnMeta['name']] = $rows[$columnMeta['name']] + 0; + $rows[$columnMeta['name']] += 0; } else { - if (is_array($rows) || $rows instanceof \Traversable) { + if (\is_array($rows) || $rows instanceof \Traversable) { foreach ($rows as &$row) { if (isset($row[$columnMeta['name']])) { - $row[$columnMeta['name']] = $row[$columnMeta['name']] + 0; + $row[$columnMeta['name']] += 0; } } + unset($row); } } + break; + default: // return as string break; @@ -81,14 +83,9 @@ public static function stringToNumeric(\PDOStatement $statement, $rows) return $rows; } - /** - * @param $value - * - * @return bool - */ - public static function convertSqlWriteValues($value) + public static function convertSqlWriteValues(mixed $value): mixed { - if (is_array($value)) { + if (\is_array($value)) { foreach ($value as $k => $v) { $value[$k] = self::convertValue($v); } @@ -99,41 +96,33 @@ public static function convertSqlWriteValues($value) return $value; } - /** - * @param $value - * - * @return int|string - */ - public static function convertValue($value) + public static function convertValue(mixed $value): mixed { - switch (gettype($value)) { + switch (\gettype($value)) { case 'boolean': $conversion = ($value) ? 1 : 0; + + break; + case 'array': + $conversion = json_encode($value); + break; + default: $conversion = $value; + break; } return $conversion; } - /** - * @param $subject - * - * @return bool - */ - public static function isCountable($subject) + public static function isCountable(mixed $subject): bool { - return (is_array($subject) || ($subject instanceof \Countable)); + return \is_array($subject) || ($subject instanceof \Countable); } - /** - * @param $value - * - * @return Literal|mixed - */ - public static function nullToLiteral($value) + public static function nullToLiteral(mixed $value): mixed { if ($value === null) { return new Literal('NULL'); diff --git a/tests/Queries/CommonTest.php b/tests/Queries/CommonTest.php index c0ddb3e..16b0010 100644 --- a/tests/Queries/CommonTest.php +++ b/tests/Queries/CommonTest.php @@ -1,23 +1,32 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/../_resources/init.php'; -use PHPUnit\Framework\TestCase; -use Envms\FluentTest\Model\User; use Envms\FluentPDO\Query; +use Envms\FluentTest\Model\User; +use PHPUnit\Framework\TestCase; /** - * Class CommonTest + * Class CommonTest. * * @covers \Envms\FluentPDO\Queries\Common */ class CommonTest extends TestCase { + protected Query $fluent; - /** @var Query */ - protected $fluent; - - public function setUp(): void + protected function setUp(): void { global $pdo; @@ -26,7 +35,7 @@ public function setUp(): void $this->fluent = new Query($pdo); } - public function testFullJoin() + public function testFullJoin(): void { $query = $this->fluent->from('article') ->select('user.name') @@ -34,18 +43,20 @@ public function testFullJoin() ->orderBy('article.title'); $returnValue = ''; + foreach ($query as $row) { - $returnValue .= "$row[name] - $row[title] "; + $returnValue .= "{$row['name']} - {$row['title']} "; } - self::assertEquals('SELECT article.*, user.name FROM article LEFT JOIN user ON user.id = article.user_id ORDER BY article.title', - $query->getQuery(false)); + self::assertEquals( + 'SELECT article.*, user.name FROM article LEFT JOIN user ON user.id = article.user_id ORDER BY article.title', + $query->getQuery(false), + ); self::assertEquals('Marek - article 1 Robert - article 2 Marek - article 3 Kevin - artïcle 4 Chris - article 5 Chris - სარედაქციო 6 ', $returnValue); } - public function testShortJoin() + public function testShortJoin(): void { - $query = $this->fluent->from('article')->leftJoin('user'); $query2 = $this->fluent->from('article')->leftJoin('user author'); $query3 = $this->fluent->from('article')->leftJoin('user AS author'); @@ -55,40 +66,50 @@ public function testShortJoin() self::assertEquals('SELECT article.* FROM article LEFT JOIN user AS author ON author.id = article.user_id', $query3->getQuery(false)); } - public function testJoinShortBackRef() + public function testJoinShortBackRef(): void { $query = $this->fluent->from('user')->innerJoin('article:'); $query2 = $this->fluent->from('user')->innerJoin('article: with_articles'); $query3 = $this->fluent->from('user')->innerJoin('article: AS with_articles'); self::assertEquals('SELECT user.* FROM user INNER JOIN article ON article.user_id = user.id', $query->getQuery(false)); - self::assertEquals('SELECT user.* FROM user INNER JOIN article AS with_articles ON with_articles.user_id = user.id', - $query2->getQuery(false)); - self::assertEquals('SELECT user.* FROM user INNER JOIN article AS with_articles ON with_articles.user_id = user.id', - $query3->getQuery(false)); + self::assertEquals( + 'SELECT user.* FROM user INNER JOIN article AS with_articles ON with_articles.user_id = user.id', + $query2->getQuery(false), + ); + self::assertEquals( + 'SELECT user.* FROM user INNER JOIN article AS with_articles ON with_articles.user_id = user.id', + $query3->getQuery(false), + ); } - public function testJoinShortMulti() + public function testJoinShortMulti(): void { $query = $this->fluent->from('comment') ->leftJoin('article.user'); - self::assertEquals('SELECT comment.* FROM comment LEFT JOIN article ON article.id = comment.article_id LEFT JOIN user ON user.id = article.user_id', - $query->getQuery(false)); + self::assertEquals( + 'SELECT comment.* FROM comment LEFT JOIN article ON article.id = comment.article_id LEFT JOIN user ON user.id = article.user_id', + $query->getQuery(false), + ); } - public function testJoinMultiBackRef() + public function testJoinMultiBackRef(): void { $query = $this->fluent->from('article') ->innerJoin('comment:user AS comment_user'); - self::assertEquals('SELECT article.* FROM article INNER JOIN comment ON comment.article_id = article.id INNER JOIN user AS comment_user ON comment_user.id = comment.user_id', - $query->getQuery(false)); - self::assertEquals(['id' => '1', 'user_id' => '1', 'published_at' => '2011-12-10 12:10:00', 'title' => 'article 1', 'content' => 'content 1'], - $query->fetch()); + self::assertEquals( + 'SELECT article.* FROM article INNER JOIN comment ON comment.article_id = article.id INNER JOIN user AS comment_user ON comment_user.id = comment.user_id', + $query->getQuery(false), + ); + self::assertEquals( + ['id' => '1', 'user_id' => '1', 'published_at' => '2011-12-10 12:10:00', 'title' => 'article 1', 'content' => 'content 1'], + $query->fetch(), + ); } - public function testJoinShortTwoSameTable() + public function testJoinShortTwoSameTable(): void { $query = $this->fluent->from('article') ->leftJoin('user') @@ -97,60 +118,70 @@ public function testJoinShortTwoSameTable() self::assertEquals('SELECT article.* FROM article LEFT JOIN user ON user.id = article.user_id', $query->getQuery(false)); } - public function testJoinShortTwoTables() + public function testJoinShortTwoTables(): void { $query = $this->fluent->from('comment') ->where('comment.id', 2) ->leftJoin('user comment_author')->select('comment_author.name AS comment_name') ->leftJoin('article.user AS article_author')->select('article_author.name AS author_name'); - self::assertEquals('SELECT comment.*, comment_author.name AS comment_name, article_author.name AS author_name FROM comment LEFT JOIN user AS comment_author ON comment_author.id = comment.user_id LEFT JOIN article ON article.id = comment.article_id LEFT JOIN user AS article_author ON article_author.id = article.user_id WHERE comment.id = ?', - $query->getQuery(false)); + self::assertEquals( + 'SELECT comment.*, comment_author.name AS comment_name, article_author.name AS author_name FROM comment LEFT JOIN user AS comment_author ON comment_author.id = comment.user_id LEFT JOIN article ON article.id = comment.article_id LEFT JOIN user AS article_author ON article_author.id = article.user_id WHERE comment.id = ?', + $query->getQuery(false), + ); self::assertEquals([ - 'id' => '2', - 'article_id' => '1', - 'user_id' => '2', - 'content' => 'comment 1.2', + 'id' => '2', + 'article_id' => '1', + 'user_id' => '2', + 'content' => 'comment 1.2', 'comment_name' => 'Robert', - 'author_name' => 'Marek' + 'author_name' => 'Marek', ], $query->fetch()); } - public function testJoinInWhere() + public function testJoinInWhere(): void { $query = $this->fluent->from('article')->where('comment:content <> "" AND user.country.id = ?', 1); - self::assertEquals('SELECT article.* FROM article LEFT JOIN comment ON comment.article_id = article.id LEFT JOIN user ON user.id = article.user_id LEFT JOIN country ON country.id = user.country_id WHERE comment.content <> "" AND country.id = ?', - $query->getQuery(false)); + self::assertEquals( + 'SELECT article.* FROM article LEFT JOIN comment ON comment.article_id = article.id LEFT JOIN user ON user.id = article.user_id LEFT JOIN country ON country.id = user.country_id WHERE comment.content <> "" AND country.id = ?', + $query->getQuery(false), + ); } - public function testJoinInSelect() + public function testJoinInSelect(): void { $query = $this->fluent->from('article')->select('user.name AS author'); self::assertEquals('SELECT article.*, user.name AS author FROM article LEFT JOIN user ON user.id = article.user_id', $query->getQuery(false)); } - public function testJoinInOrderBy() + public function testJoinInOrderBy(): void { $query = $this->fluent->from('article')->orderBy('user.name, article.title'); - self::assertEquals('SELECT article.* FROM article LEFT JOIN user ON user.id = article.user_id ORDER BY user.name, article.title', - $query->getQuery(false)); + self::assertEquals( + 'SELECT article.* FROM article LEFT JOIN user ON user.id = article.user_id ORDER BY user.name, article.title', + $query->getQuery(false), + ); } - public function testJoinInGroupBy() + public function testJoinInGroupBy(): void { $query = $this->fluent->from('article')->groupBy('user.type') ->select(null)->select('user.type, count(article.id) AS article_count'); - self::assertEquals('SELECT user.type, count(article.id) AS article_count FROM article LEFT JOIN user ON user.id = article.user_id GROUP BY user.type', - $query->getQuery(false)); - self::assertEquals(['0' => ['type' => 'admin', 'article_count' => '4'], '1' => ['type' => 'author', 'article_count' => '2']], - $query->fetchAll()); + self::assertEquals( + 'SELECT user.type, count(article.id) AS article_count FROM article LEFT JOIN user ON user.id = article.user_id GROUP BY user.type', + $query->getQuery(false), + ); + self::assertEquals( + ['0' => ['type' => 'admin', 'article_count' => '4'], '1' => ['type' => 'author', 'article_count' => '2']], + $query->fetchAll(), + ); } - public function testEscapeJoin() + public function testEscapeJoin(): void { $query = $this->fluent->from('article') ->where('user\.name = ?', 'Chris'); @@ -161,11 +192,13 @@ public function testEscapeJoin() ->where('comment.id = :id', 1) ->where('user\.name = :name', 'Chris'); - self::assertEquals('SELECT article.* FROM article LEFT JOIN comment ON comment.id = article.comment_id WHERE comment.id = :id AND user.name = :name', - $query->getQuery(false)); + self::assertEquals( + 'SELECT article.* FROM article LEFT JOIN comment ON comment.id = article.comment_id WHERE comment.id = :id AND user.name = :name', + $query->getQuery(false), + ); } - public function testDontCreateDuplicateJoins() + public function testDontCreateDuplicateJoins(): void { $query = $this->fluent->from('article') ->innerJoin('user AS author ON article.user_id = author.id') @@ -183,35 +216,43 @@ public function testDontCreateDuplicateJoins() ->innerJoin('user ON article.user_id = user.id') ->select('user.country.name'); - self::assertEquals('SELECT article.*, author.name FROM article INNER JOIN user AS author ON article.user_id = author.id', - $query->getQuery(false)); + self::assertEquals( + 'SELECT article.*, author.name FROM article INNER JOIN user AS author ON article.user_id = author.id', + $query->getQuery(false), + ); self::assertEquals('SELECT article.*, user.name FROM article INNER JOIN user ON article.user_id = user.id', $query2->getQuery(false)); - self::assertEquals('SELECT article.*, country.name FROM article INNER JOIN user AS author ON article.user_id = author.id LEFT JOIN country ON country.id = author.country_id', - $query3->getQuery(false)); - self::assertEquals('SELECT article.*, country.name FROM article INNER JOIN user ON article.user_id = user.id LEFT JOIN country ON country.id = user.country_id', - $query4->getQuery(false)); + self::assertEquals( + 'SELECT article.*, country.name FROM article INNER JOIN user AS author ON article.user_id = author.id LEFT JOIN country ON country.id = author.country_id', + $query3->getQuery(false), + ); + self::assertEquals( + 'SELECT article.*, country.name FROM article INNER JOIN user ON article.user_id = user.id LEFT JOIN country ON country.id = user.country_id', + $query4->getQuery(false), + ); } - public function testClauseWithRefBeforeJoin() + public function testClauseWithRefBeforeJoin(): void { $query = $this->fluent->from('article')->select('user.name')->innerJoin('user'); $query2 = $this->fluent->from('article')->select('author.name')->innerJoin('user AS author'); $query3 = $this->fluent->from('user')->select('article:title')->innerJoin('article:'); self::assertEquals('SELECT article.*, user.name FROM article INNER JOIN user ON user.id = article.user_id', $query->getQuery(false)); - self::assertEquals('SELECT article.*, author.name FROM article INNER JOIN user AS author ON author.id = article.user_id', - $query2->getQuery(false)); + self::assertEquals( + 'SELECT article.*, author.name FROM article INNER JOIN user AS author ON author.id = article.user_id', + $query2->getQuery(false), + ); self::assertEquals('SELECT user.*, article.title FROM user INNER JOIN article ON article.user_id = user.id', $query3->getQuery(false)); } - public function testFromOtherDB() + public function testFromOtherDB(): void { $queryPrint = $this->fluent->from('db2.user')->where('db2.user.name', 'name')->order('db2.user.name')->getQuery(false); self::assertEquals('SELECT db2.user.* FROM db2.user WHERE db2.user.name = ? ORDER BY db2.user.name', $queryPrint); } - public function testJoinTableWithUsing() + public function testJoinTableWithUsing(): void { $query = $this->fluent->from('article') ->innerJoin('user USING (user_id)') @@ -233,13 +274,13 @@ public function testJoinTableWithUsing() self::assertEquals('SELECT article.*, u.* FROM article INNER JOIN user AS u USING (user_id)', $query3); } - public function testDisableSmartJoin() + public function testDisableSmartJoin(): void { $query = $this->fluent->from('comment') ->select('user.name') ->orderBy('article.published_at') ->getQuery(false); - $printQuery = "-- Plain: $query"; + $printQuery = "-- Plain: {$query}"; $query2 = $this->fluent->from('comment') ->select('user.name') @@ -247,7 +288,7 @@ public function testDisableSmartJoin() ->orderBy('article.published_at') ->getQuery(false); - $printQuery2 = "-- Disable: $query2"; + $printQuery2 = "-- Disable: {$query2}"; $query3 = $this->fluent->from('comment') ->disableSmartJoin() @@ -255,16 +296,20 @@ public function testDisableSmartJoin() ->enableSmartJoin() ->orderBy('article.published_at') ->getQuery(false); - $printQuery3 = "-- Disable and enable: $query3"; + $printQuery3 = "-- Disable and enable: {$query3}"; - self::assertEquals('-- Plain: SELECT comment.*, user.name FROM comment LEFT JOIN user ON user.id = comment.user_id LEFT JOIN article ON article.id = comment.article_id ORDER BY article.published_at', - $printQuery); + self::assertEquals( + '-- Plain: SELECT comment.*, user.name FROM comment LEFT JOIN user ON user.id = comment.user_id LEFT JOIN article ON article.id = comment.article_id ORDER BY article.published_at', + $printQuery, + ); self::assertEquals('-- Disable: SELECT comment.*, user.name FROM comment ORDER BY article.published_at', $printQuery2); - self::assertEquals('-- Disable and enable: SELECT comment.*, user.name FROM comment LEFT JOIN user ON user.id = comment.user_id LEFT JOIN article ON article.id = comment.article_id ORDER BY article.published_at', - $printQuery3); + self::assertEquals( + '-- Disable and enable: SELECT comment.*, user.name FROM comment LEFT JOIN user ON user.id = comment.user_id LEFT JOIN article ON article.id = comment.article_id ORDER BY article.published_at', + $printQuery3, + ); } - public function testPDOFetchObj() + public function testPDOFetchObj(): void { $query = $this->fluent->from('user')->where('id > ?', 0)->orderBy('name'); $query = $query->where('name = ?', 'Marek'); @@ -280,7 +325,7 @@ public function testPDOFetchObj() self::assertEquals($expectObj, $query->fetch()); } - public function testFromIdAsObject() + public function testFromIdAsObject(): void { $query = $this->fluent->from('user', 2)->asObject(); @@ -294,7 +339,7 @@ public function testFromIdAsObject() self::assertEquals($expectObj, $query->fetch()); } - public function testFromIdAsObjectUser() + public function testFromIdAsObjectUser(): void { $expectedUser = new User(); $expectedUser->id = 2; @@ -308,5 +353,4 @@ public function testFromIdAsObjectUser() self::assertEquals('SELECT user.* FROM user WHERE user.id = ?', $query->getQuery(false)); self::assertEquals($expectedUser, $user); } - } diff --git a/tests/Queries/DeleteTest.php b/tests/Queries/DeleteTest.php index 5abd677..a5960c5 100644 --- a/tests/Queries/DeleteTest.php +++ b/tests/Queries/DeleteTest.php @@ -1,22 +1,31 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/../_resources/init.php'; -use PHPUnit\Framework\TestCase; use Envms\FluentPDO\Query; +use PHPUnit\Framework\TestCase; /** - * Class DeleteTest + * Class DeleteTest. * * @covers \Envms\FluentPDO\Queries\Delete */ class DeleteTest extends TestCase { + protected Query $fluent; - /** @var Query */ - protected $fluent; - - public function setUp(): void + protected function setUp(): void { global $pdo; @@ -25,7 +34,7 @@ public function setUp(): void $this->fluent = new Query($pdo); } - public function testDelete() + public function testDelete(): void { $query = $this->fluent->deleteFrom('user') ->where('id', 1); @@ -34,7 +43,7 @@ public function testDelete() self::assertEquals(['0' => '1'], $query->getParameters()); } - public function testDeleteIgnore() + public function testDeleteIgnore(): void { $query = $this->fluent->deleteFrom('user') ->ignore() @@ -44,7 +53,7 @@ public function testDeleteIgnore() self::assertEquals(['0' => '1'], $query->getParameters()); } - public function testDeleteOrderLimit() + public function testDeleteOrderLimit(): void { $query = $this->fluent->deleteFrom('user') ->where('id', 2) @@ -55,7 +64,7 @@ public function testDeleteOrderLimit() self::assertEquals(['0' => '2'], $query->getParameters()); } - public function testDeleteExpanded() + public function testDeleteExpanded(): void { $query = $this->fluent->delete('t1, t2') ->from('t1') @@ -63,12 +72,14 @@ public function testDeleteExpanded() ->innerJoin('t3 ON t2.id = t3.id') ->where('t1.id', 1); - self::assertEquals('DELETE t1, t2 FROM t1 INNER JOIN t2 ON t1.id = t2.id INNER JOIN t3 ON t2.id = t3.id WHERE t1.id = ?', - $query->getQuery(false)); + self::assertEquals( + 'DELETE t1, t2 FROM t1 INNER JOIN t2 ON t1.id = t2.id INNER JOIN t3 ON t2.id = t3.id WHERE t1.id = ?', + $query->getQuery(false), + ); self::assertEquals(['0' => '1'], $query->getParameters()); } - public function testDeleteShortcut() + public function testDeleteShortcut(): void { $query = $this->fluent->deleteFrom('user', 1); @@ -76,11 +87,11 @@ public function testDeleteShortcut() self::assertEquals(['0' => '1'], $query->getParameters()); } - public function testAddFromAfterDelete() + public function testAddFromAfterDelete(): void { $query = $this->fluent->delete('user', 1)->from('user'); self::assertEquals('DELETE user FROM user WHERE id = ?', $query->getQuery(false)); self::assertEquals(['0' => '1'], $query->getParameters()); } -} \ No newline at end of file +} diff --git a/tests/Queries/InsertTest.php b/tests/Queries/InsertTest.php index 73d2de0..f074c16 100644 --- a/tests/Queries/InsertTest.php +++ b/tests/Queries/InsertTest.php @@ -1,22 +1,31 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/../_resources/init.php'; -use PHPUnit\Framework\TestCase; use Envms\FluentPDO\Query; +use PHPUnit\Framework\TestCase; /** - * Class InsertTest + * Class InsertTest. * * @covers \Envms\FluentPDO\Queries\Insert */ class InsertTest extends TestCase { + protected Envms\FluentPDO\Query $fluent; - /** @var Envms\FluentPDO\Query */ - protected $fluent; - - public function setUp(): void + protected function setUp(): void { global $pdo; @@ -25,25 +34,25 @@ public function setUp(): void $this->fluent = new Query($pdo); } - public function testInsertStatement() + public function testInsertStatement(): void { $query = $this->fluent->insertInto('article', [ 'user_id' => 1, - 'title' => 'new title', - 'content' => 'new content' + 'title' => 'new title', + 'content' => 'new content', ]); self::assertEquals('INSERT INTO article (user_id, title, content) VALUES (?, ?, ?)', $query->getQuery(false)); self::assertEquals(['0' => '1', '1' => 'new title', '2' => 'new content'], $query->getParameters()); } - public function testInsertUpdate() + public function testInsertUpdate(): void { $query = $this->fluent->insertInto('article', ['id' => 1]) ->onDuplicateKeyUpdate([ 'published_at' => '2011-12-10 12:10:00', - 'title' => 'article 1b', - 'content' => new Envms\FluentPDO\Literal('abs(-1)') // let's update with a literal and a parameter value + 'title' => 'article 1b', + 'content' => new Envms\FluentPDO\Literal('abs(-1)'), // let's update with a literal and a parameter value ]); $q = $this->fluent->from('article', 1); @@ -51,7 +60,7 @@ public function testInsertUpdate() $query2 = $this->fluent->insertInto('article', ['id' => 1]) ->onDuplicateKeyUpdate([ 'published_at' => '2011-12-10 12:10:00', - 'title' => 'article 1', + 'title' => 'article 1', 'content' => 'content 1', ]); @@ -59,38 +68,46 @@ public function testInsertUpdate() self::assertEquals('INSERT INTO article (id) VALUES (?) ON DUPLICATE KEY UPDATE published_at = ?, title = ?, content = abs(-1)', $query->getQuery(false)); self::assertEquals([0 => '1', 1 => '2011-12-10 12:10:00', 2 => 'article 1b'], $query->getParameters()); - self::assertEquals('last_inserted_id = 1', 'last_inserted_id = ' . $query->execute()); - self::assertEquals(['id' => '1', 'user_id' => '1', 'published_at' => '2011-12-10 12:10:00', 'title' => 'article 1b', 'content' => '1'], - $q->fetch()); - self::assertEquals('last_inserted_id = 1', 'last_inserted_id = ' . $query2->execute()); - self::assertEquals(['id' => '1', 'user_id' => '1', 'published_at' => '2011-12-10 12:10:00', 'title' => 'article 1', 'content' => 'content 1'], - $q2->fetch()); + self::assertEquals('last_inserted_id = 1', 'last_inserted_id = '.$query->execute()); + self::assertEquals( + ['id' => '1', 'user_id' => '1', 'published_at' => '2011-12-10 12:10:00', 'title' => 'article 1b', 'content' => '1'], + $q->fetch(), + ); + self::assertEquals('last_inserted_id = 1', 'last_inserted_id = '.$query2->execute()); + self::assertEquals( + ['id' => '1', 'user_id' => '1', 'published_at' => '2011-12-10 12:10:00', 'title' => 'article 1', 'content' => 'content 1'], + $q2->fetch(), + ); } - public function testInsertWithLiteral() + public function testInsertWithLiteral(): void { - $query = $this->fluent->insertInto('article', + $query = $this->fluent->insertInto( + 'article', [ - 'user_id' => 1, + 'user_id' => 1, 'updated_at' => new Envms\FluentPDO\Literal('NOW()'), - 'title' => 'new title', - 'content' => 'new content', - ]); + 'title' => 'new title', + 'content' => 'new content', + ], + ); self::assertEquals('INSERT INTO article (user_id, updated_at, title, content) VALUES (?, NOW(), ?, ?)', $query->getQuery(false)); self::assertEquals(['0' => '1', '1' => 'new title', '2' => 'new content'], $query->getParameters()); } - public function testInsertIgnore() + public function testInsertIgnore(): void { - $query = $this->fluent->insertInto('article', + $query = $this->fluent->insertInto( + 'article', [ 'user_id' => 1, - 'title' => 'new title', + 'title' => 'new title', 'content' => 'new content', - ])->ignore(); + ], + )->ignore(); self::assertEquals('INSERT IGNORE INTO article (user_id, title, content) VALUES (?, ?, ?)', $query->getQuery(false)); self::assertEquals(['0' => '1', '1' => 'new title', '2' => 'new content'], $query->getParameters()); } -} \ No newline at end of file +} diff --git a/tests/Queries/SelectTest.php b/tests/Queries/SelectTest.php index ea22d69..ddefd2c 100644 --- a/tests/Queries/SelectTest.php +++ b/tests/Queries/SelectTest.php @@ -1,22 +1,31 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/../_resources/init.php'; -use PHPUnit\Framework\TestCase; use Envms\FluentPDO\Query; +use PHPUnit\Framework\TestCase; /** - * Class SelectTest + * Class SelectTest. * * @covers \Envms\FluentPDO\Queries\Select */ class SelectTest extends TestCase { + protected Query $fluent; - /** @var Query */ - protected $fluent; - - public function setUp(): void + protected function setUp(): void { global $pdo; @@ -25,7 +34,7 @@ public function setUp(): void $this->fluent = new Query($pdo); } - public function testBasicQuery() + public function testBasicQuery(): void { $query = $this->fluent ->from('user') @@ -39,9 +48,8 @@ public function testBasicQuery() self::assertEquals([0 => 0, 1 => 'Marek'], $query->getParameters()); } - public function testReturnQueryWithHaving() + public function testReturnQueryWithHaving(): void { - $query = $this->fluent ->from('user') ->select(null) @@ -51,11 +59,13 @@ public function testReturnQueryWithHaving() ->having('type_count > ?', 1) ->orderBy('name'); - self::assertEquals("SELECT type, count(id) AS type_count FROM user WHERE id > ? GROUP BY type HAVING type_count > ? ORDER BY name", - $query->getQuery(false)); + self::assertEquals( + 'SELECT type, count(id) AS type_count FROM user WHERE id > ? GROUP BY type HAVING type_count > ? ORDER BY name', + $query->getQuery(false), + ); } - public function testReturnParameterWithId() + public function testReturnParameterWithId(): void { $query = $this->fluent ->from('user', 2); @@ -64,7 +74,7 @@ public function testReturnParameterWithId() self::assertEquals('SELECT user.* FROM user WHERE user.id = ?', $query->getQuery(false)); } - public function testFromWithAlias() + public function testFromWithAlias(): void { $query = $this->fluent->from('user author')->getQuery(false); $query2 = $this->fluent->from('user AS author')->getQuery(false); @@ -77,20 +87,20 @@ public function testFromWithAlias() self::assertEquals('SELECT author.*, country.name FROM user AS author LEFT JOIN country ON country.id = user AS author.country_id', $query4); } - public function testWhereArrayParameter() + public function testWhereArrayParameter(): void { $query = $this->fluent ->from('user') ->where([ 'id' => 2, - 'type' => 'author' + 'type' => 'author', ]); self::assertEquals('SELECT user.* FROM user WHERE id = ? AND type = ?', $query->getQuery(false)); self::assertEquals([0 => 2, 1 => 'author'], $query->getParameters()); } - public function testWhereColumnValue() + public function testWhereColumnValue(): void { $query = $this->fluent->from('user') ->where('type', 'author'); @@ -99,7 +109,7 @@ public function testWhereColumnValue() self::assertEquals([0 => 'author'], $query->getParameters()); } - public function testWhereColumnNull() + public function testWhereColumnNull(): void { $query = $this->fluent ->from('user') @@ -108,7 +118,7 @@ public function testWhereColumnNull() self::assertEquals('SELECT user.* FROM user WHERE type IS NULL', $query->getQuery(false)); } - public function testWhereColumnArray() + public function testWhereColumnArray(): void { $query = $this->fluent ->from('user') @@ -118,7 +128,7 @@ public function testWhereColumnArray() self::assertEquals([], $query->getParameters()); } - public function testWherePreparedArray() + public function testWherePreparedArray(): void { $query = $this->fluent ->from('user') @@ -128,13 +138,14 @@ public function testWherePreparedArray() self::assertEquals([0 => 1, 1 => 2, 2 => 3], $query->getParameters()); } - public function testWhereColumnName() + public function testWhereColumnName(): void { $query = $this->fluent->from('user') ->where('type = :type', [':type' => 'author']) ->where('id > :id AND name <> :name', [':id' => 3, ':name' => 'Marek']); $returnValue = ''; + foreach ($query as $row) { $returnValue = $row['name']; } @@ -144,18 +155,20 @@ public function testWhereColumnName() self::assertEquals('Kevin', $returnValue); } - public function testWhereOr() + public function testWhereOr(): void { $query = $this->fluent->from('comment') ->where('comment.id = :id', [':id' => 1]) ->whereOr('user.id = :userId', [':userId' => 2]); - self::assertEquals('SELECT comment.* FROM comment LEFT JOIN user ON user.id = comment.user_id WHERE comment.id = :id OR user.id = :userId', - $query->getQuery(false)); + self::assertEquals( + 'SELECT comment.* FROM comment LEFT JOIN user ON user.id = comment.user_id WHERE comment.id = :id OR user.id = :userId', + $query->getQuery(false), + ); self::assertEquals([':id' => '1', ':userId' => '2'], $query->getParameters()); } - public function testWhereReset() + public function testWhereReset(): void { $query = $this->fluent->from('user')->where('id > ?', 0)->orderBy('name'); $query = $query->where(null)->where('name = ?', 'Marek'); @@ -165,9 +178,7 @@ public function testWhereReset() self::assertEquals(['id' => '1', 'country_id' => '1', 'type' => 'admin', 'name' => 'Marek'], $query->fetch()); } - - - public function testSelectArrayParam() + public function testSelectArrayParam(): void { $query = $this->fluent ->from('user') @@ -180,7 +191,7 @@ public function testSelectArrayParam() self::assertEquals(['id' => '1', 'name' => 'Marek'], $query->fetch()); } - public function testGroupByArrayParam() + public function testGroupByArrayParam(): void { $query = $this->fluent ->from('user') @@ -192,7 +203,7 @@ public function testGroupByArrayParam() self::assertEquals(['total_count' => '1'], $query->fetch()); } - public function testCountable() + public function testCountable(): void { $articles = $this->fluent ->from('article') @@ -201,26 +212,27 @@ public function testCountable() ->where('id > 1') ->where('id < 4'); - $count = count($articles); + $count = \count($articles); self::assertEquals(2, $count); self::assertEquals([0 => ['title' => 'article 2'], 1 => ['title' => 'article 3']], $articles->fetchAll()); } - public function testWhereNotArray() + public function testWhereNotArray(): void { $query = $this->fluent->from('article')->where('NOT id', [1, 2]); self::assertEquals('SELECT article.* FROM article WHERE NOT id IN (1, 2)', $query->getQuery(false)); } - public function testWhereColNameEscaped() + public function testWhereColNameEscaped(): void { $query = $this->fluent->from('user') ->where('`type` = :type', [':type' => 'author']) ->where('`id` > :id AND `name` <> :name', [':id' => 3, ':name' => 'Marek']); $rowDisplay = ''; + foreach ($query as $row) { $rowDisplay = $row['name']; } @@ -230,14 +242,14 @@ public function testWhereColNameEscaped() self::assertEquals('Kevin', $rowDisplay); } - public function testAliasesForClausesGroupbyOrderBy() + public function testAliasesForClausesGroupbyOrderBy(): void { $query = $this->fluent->from('article')->group('user_id')->order('id'); self::assertEquals('SELECT article.* FROM article GROUP BY user_id ORDER BY id', $query->getQuery(false)); } - public function testFetch() + public function testFetch(): void { $queryPrint = $this->fluent->from('user', 1)->fetch('name'); $queryPrint2 = $this->fluent->from('user', 1)->fetch(); @@ -246,11 +258,11 @@ public function testFetch() self::assertEquals('Marek', $queryPrint); self::assertEquals(['id' => '1', 'country_id' => '1', 'type' => 'admin', 'name' => 'Marek'], $queryPrint2); - self::assertEquals(false, $statement); - self::assertEquals(false, $statement2); + self::assertFalse($statement); + self::assertFalse($statement2); } - public function testFetchPairsFetchAll() + public function testFetchPairsFetchAll(): void { $result = $this->fluent->from('user')->fetchPairs('id', 'name'); $result2 = $this->fluent->from('user')->fetchAll(); @@ -260,20 +272,22 @@ public function testFetchPairsFetchAll() 0 => ['id' => '1', 'country_id' => '1', 'type' => 'admin', 'name' => 'Marek'], 1 => ['id' => '2', 'country_id' => '1', 'type' => 'author', 'name' => 'Robert'], 2 => ['id' => '3', 'country_id' => '2', 'type' => 'admin', 'name' => 'Chris'], - 3 => ['id' => '4', 'country_id' => '2', 'type' => 'author', 'name' => 'Kevin'] + 3 => ['id' => '4', 'country_id' => '2', 'type' => 'author', 'name' => 'Kevin'], ], $result2); } - public function testFetchAllWithParams() + public function testFetchAllWithParams(): void { $result = $this->fluent->from('user')->fetchAll('id', 'type, name'); - self::assertEquals([1 => ['id' => '1', 'type' => 'admin', 'name' => 'Marek'], 2 => ['id' => '2', 'type' => 'author', 'name' => 'Robert'], - 3 => ['id' => '3', 'type' => 'admin', 'name' => 'Chris'], 4 => ['id' => '4', 'type' => 'author', 'name' => 'Kevin']], - $result); + self::assertEquals( + [1 => ['id' => '1', 'type' => 'admin', 'name' => 'Marek'], 2 => ['id' => '2', 'type' => 'author', 'name' => 'Robert'], + 3 => ['id' => '3', 'type' => 'admin', 'name' => 'Chris'], 4 => ['id' => '4', 'type' => 'author', 'name' => 'Kevin']], + $result, + ); } - public function testFetchColumn() + public function testFetchColumn(): void { $printColumn = $this->fluent->from('user', 3)->fetchColumn(); $printColumn2 = $this->fluent->from('user', 3)->fetchColumn(3); @@ -282,7 +296,7 @@ public function testFetchColumn() self::assertEquals(3, $printColumn); self::assertEquals('Chris', $printColumn2); - self::assertEquals(false, $statement); - self::assertEquals(false, $statement2); + self::assertFalse($statement); + self::assertFalse($statement2); } -} \ No newline at end of file +} diff --git a/tests/Queries/UpdateTest.php b/tests/Queries/UpdateTest.php index 4e231d5..c4d6d29 100644 --- a/tests/Queries/UpdateTest.php +++ b/tests/Queries/UpdateTest.php @@ -1,22 +1,31 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/../_resources/init.php'; -use PHPUnit\Framework\TestCase; use Envms\FluentPDO\Query; +use PHPUnit\Framework\TestCase; /** - * Class UpdateTest + * Class UpdateTest. * * @covers \Envms\FluentPDO\Queries\Update */ class UpdateTest extends TestCase { + protected Query $fluent; - /** @var Query */ - protected $fluent; - - public function setUp(): void + protected function setUp(): void { global $pdo; @@ -25,7 +34,7 @@ public function setUp(): void $this->fluent = new Query($pdo); } - public function testUpdate() + public function testUpdate(): void { $query = $this->fluent->update('country')->set('name', 'aikavolS')->where('id', 1); $query->execute(); @@ -42,7 +51,7 @@ public function testUpdate() self::assertEquals(['id' => '1', 'name' => 'Slovakia', 'details' => '{"gdp": 90.75, "pop": 5456300, "name": "Slovensko"}'], $query3->fetch()); } - public function testUpdateLiteral() + public function testUpdateLiteral(): void { $query = $this->fluent->update('article')->set('published_at', new Envms\FluentPDO\Literal('NOW()'))->where('user_id', 1); @@ -50,7 +59,7 @@ public function testUpdateLiteral() self::assertEquals(['0' => '1'], $query->getParameters()); } - public function testUpdateFromArray() + public function testUpdateFromArray(): void { $query = $this->fluent->update('user')->set(['name' => 'keraM', '`type`' => 'author'])->where('id', 1); @@ -58,30 +67,34 @@ public function testUpdateFromArray() self::assertEquals([0 => 'keraM', 1 => 'author', 2 => '1'], $query->getParameters()); } - public function testUpdateLeftJoin() + public function testUpdateLeftJoin(): void { $query = $this->fluent->update('user') ->outerJoin('country ON country.id = user.country_id') ->set(['name' => 'keraM', '`type`' => 'author']) ->where('id', 1); - self::assertEquals('UPDATE user OUTER JOIN country ON country.id = user.country_id SET name = ?, `type` = ? WHERE id = ?', - $query->getQuery(false)); + self::assertEquals( + 'UPDATE user OUTER JOIN country ON country.id = user.country_id SET name = ?, `type` = ? WHERE id = ?', + $query->getQuery(false), + ); self::assertEquals([0 => 'keraM', 1 => 'author', 2 => '1'], $query->getParameters()); } - public function testUpdateSmartJoin() + public function testUpdateSmartJoin(): void { $query = $this->fluent->update('user') ->set(['type' => 'author']) ->where('country.id', 1); - self::assertEquals('UPDATE user LEFT JOIN country ON country.id = user.country_id SET type = ? WHERE country.id = ?', - $query->getQuery(false)); + self::assertEquals( + 'UPDATE user LEFT JOIN country ON country.id = user.country_id SET type = ? WHERE country.id = ?', + $query->getQuery(false), + ); self::assertEquals([0 => 'author', 1 => '1'], $query->getParameters()); } - public function testUpdateOrderLimit() + public function testUpdateOrderLimit(): void { $query = $this->fluent->update('user') ->set(['type' => 'author']) @@ -93,7 +106,7 @@ public function testUpdateOrderLimit() self::assertEquals([0 => 'author', 1 => '2'], $query->getParameters()); } - public function testUpdateShortCut() + public function testUpdateShortCut(): void { $query = $this->fluent->update('user', ['type' => 'admin'], 1); @@ -101,7 +114,7 @@ public function testUpdateShortCut() self::assertEquals([0 => 'admin', 1 => '1'], $query->getParameters()); } - public function testUpdateZero() + public function testUpdateZero(): void { $this->fluent->update('article')->set('content', '')->where('id', 1)->execute(); $user = $this->fluent->from('article')->where('id', 1)->fetch(); @@ -118,35 +131,40 @@ public function testUpdateZero() self::assertEquals('ID: 1 - content: content 1', $printQuery2); } - public function testUpdateWhere() + public function testUpdateWhere(): void { $query = $this->fluent->update('users') - ->set("`users`.`active`", 1) - ->where("`country`.`name`", 'Slovakia') - ->where("`users`.`name`", 'Marek'); + ->set('`users`.`active`', 1) + ->where('`country`.`name`', 'Slovakia') + ->where('`users`.`name`', 'Marek'); $query2 = $this->fluent->update('users') - ->set("[users].[active]", 1) - ->where("[country].[name]", 'Slovakia') - ->where("[users].[name]", 'Marek'); - - self::assertEquals('UPDATE users LEFT JOIN country ON country.id = users.country_id SET `users`.`active` = ? WHERE `country`.`name` = ? AND `users`.`name` = ?', - $query->getQuery(false)); + ->set('[users].[active]', 1) + ->where('[country].[name]', 'Slovakia') + ->where('[users].[name]', 'Marek'); + + self::assertEquals( + 'UPDATE users LEFT JOIN country ON country.id = users.country_id SET `users`.`active` = ? WHERE `country`.`name` = ? AND `users`.`name` = ?', + $query->getQuery(false), + ); self::assertEquals([0 => '1', 1 => 'Slovakia', 2 => 'Marek'], $query->getParameters()); - self::assertEquals('UPDATE users LEFT JOIN country ON country.id = users.country_id SET [users].[active] = ? WHERE [country].[name] = ? AND [users].[name] = ?', - $query2->getQuery(false)); + self::assertEquals( + 'UPDATE users LEFT JOIN country ON country.id = users.country_id SET [users].[active] = ? WHERE [country].[name] = ? AND [users].[name] = ?', + $query2->getQuery(false), + ); self::assertEquals([0 => '1', 1 => 'Slovakia', 2 => 'Marek'], $query2->getParameters()); } - public function testUpdateNamedParameters() + public function testUpdateNamedParameters(): void { $query = $this->fluent->update('users') - ->set("`users`.`active`", [':active' => 1]) - ->where("`country`.`name` = :country", [':country' => 'Slovakia']); + ->set('`users`.`active`', [':active' => 1]) + ->where('`country`.`name` = :country', [':country' => 'Slovakia']); - self::assertEquals('UPDATE users LEFT JOIN country ON country.id = users.country_id SET `users`.`active` = :active WHERE `country`.`name` = :country', - $query->getQuery(false)); + self::assertEquals( + 'UPDATE users LEFT JOIN country ON country.id = users.country_id SET `users`.`active` = :active WHERE `country`.`name` = :country', + $query->getQuery(false), + ); self::assertEquals([':active' => '1', ':country' => 'Slovakia'], $query->getParameters()); } - } diff --git a/tests/RegexTest.php b/tests/RegexTest.php index 3cbd82c..12eb223 100644 --- a/tests/RegexTest.php +++ b/tests/RegexTest.php @@ -1,115 +1,124 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/_resources/init.php'; -use PHPUnit\Framework\TestCase; use Envms\FluentPDO\Regex; +use PHPUnit\Framework\TestCase; /** - * Class StructureTest + * Class StructureTest. * * @covers \Envms\FluentPDO\Structure */ class RegexTest extends TestCase { - /** @var Regex */ - protected $regex; + protected Regex $regex; - public function setUp(): void + protected function setUp(): void { $this->regex = new Regex(); } - public function testCamelCasedSpaced() + public function testCamelCasedSpaced(): void { - $name = $this->regex->camelCaseSpaced("magicCallMethod"); + $name = $this->regex->camelCaseSpaced('magicCallMethod'); - self::assertEquals("magic Call Method", $name); + self::assertEquals('magic Call Method', $name); } - public function testSplitClauses() + public function testSplitClauses(): void { - $query = $this->regex->splitClauses("SELECT * FROM user WHERE id = 1 OR id = 2 ORDER BY id ASC"); + $query = $this->regex->splitClauses('SELECT * FROM user WHERE id = 1 OR id = 2 ORDER BY id ASC'); self::assertEquals("SELECT * \nFROM user \nWHERE id = 1 OR id = 2 \nORDER BY id ASC", $query); } - public function testSplitSubClauses() + public function testSplitSubClauses(): void { - $query = $this->regex->splitSubClauses("SELECT * FROM user LEFT JOIN article WHERE 1 OR 2"); + $query = $this->regex->splitSubClauses('SELECT * FROM user LEFT JOIN article WHERE 1 OR 2'); self::assertEquals("SELECT * FROM user \n LEFT JOIN article WHERE 1 \n OR 2", $query); } - public function testRemoveLineEndWhitespace() + public function testRemoveLineEndWhitespace(): void { $query = $this->regex->removeLineEndWhitespace("SELECT * \n FROM user \n"); self::assertEquals("SELECT *\n FROM user\n", $query); } - public function testRemoveAdditionalJoins() + public function testRemoveAdditionalJoins(): void { - $join = $this->regex->removeAdditionalJoins("user.article:id"); + $join = $this->regex->removeAdditionalJoins('user.article:id'); - self::assertEquals("article.id", $join); + self::assertEquals('article.id', $join); } - public function testSqlParameter() + public function testSqlParameter(): void { - $isParam = $this->regex->sqlParameter("id = :id"); + $isParam = $this->regex->sqlParameter('id = :id'); self::assertEquals(1, $isParam); - $isParam = $this->regex->sqlParameter("name = ?"); + $isParam = $this->regex->sqlParameter('name = ?'); self::assertEquals(1, $isParam); - $isParam = $this->regex->sqlParameter("count IN (22, 77)"); + $isParam = $this->regex->sqlParameter('count IN (22, 77)'); self::assertEquals(0, $isParam); } - public function testTableAlias() + public function testTableAlias(): void { - $isAlias = $this->regex->tableAlias("user AS u"); + $isAlias = $this->regex->tableAlias('user AS u'); self::assertEquals(1, $isAlias); - $isAlias = $this->regex->tableAlias("user.*"); + $isAlias = $this->regex->tableAlias('user.*'); self::assertEquals(1, $isAlias); - $isAlias = $this->regex->tableAlias(" "); + $isAlias = $this->regex->tableAlias(' '); self::assertEquals(0, $isAlias); - $isAlias = $this->regex->tableAlias("0.00 AS ཎ"); + $isAlias = $this->regex->tableAlias('0.00 AS ཎ'); self::assertEquals(1, $isAlias); } - public function testTableJoin() + public function testTableJoin(): void { - $join = $this->regex->tableJoin("user"); + $join = $this->regex->tableJoin('user'); self::assertEquals(1, $join); - $join = $this->regex->tableJoin("`user`."); + $join = $this->regex->tableJoin('`user`.'); self::assertEquals(1, $join); $join = $this->regex->tableJoin("'''"); self::assertEquals(0, $join); - $join = $this->regex->tableJoin("ឃឡឱ."); + $join = $this->regex->tableJoin('ឃឡឱ.'); self::assertEquals(1, $join); } - public function testTableJoinFull() + public function testTableJoinFull(): void { - $join = $this->regex->tableJoinFull("user."); + $join = $this->regex->tableJoinFull('user.'); self::assertEquals(1, $join); - $join = $this->regex->tableJoinFull("`user`.`column`"); + $join = $this->regex->tableJoinFull('`user`.`column`'); self::assertEquals(1, $join); - $join = $this->regex->tableJoinFull("user .column"); + $join = $this->regex->tableJoinFull('user .column'); self::assertEquals(0, $join); - $join = $this->regex->tableJoinFull("ㇽㇺㇴ.ㇱ"); + $join = $this->regex->tableJoinFull('ㇽㇺㇴ.ㇱ'); self::assertEquals(1, $join); } - } diff --git a/tests/StructureTest.php b/tests/StructureTest.php index c02dbf2..04956bd 100644 --- a/tests/StructureTest.php +++ b/tests/StructureTest.php @@ -1,19 +1,29 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/_resources/init.php'; -use PHPUnit\Framework\TestCase; use Envms\FluentPDO\Structure; +use PHPUnit\Framework\TestCase; /** - * Class StructureTest + * Class StructureTest. * * @covers \Envms\FluentPDO\Structure */ class StructureTest extends TestCase { - - public function testBasicKey() + public function testBasicKey(): void { $structure = new Structure(); @@ -21,7 +31,7 @@ public function testBasicKey() self::assertEquals('user_id', $structure->getForeignKey('user')); } - public function testCustomKey() + public function testCustomKey(): void { $structure = new Structure('whatAnId', '%s_\xid'); @@ -29,7 +39,7 @@ public function testCustomKey() self::assertEquals('user_\xid', $structure->getForeignKey('user')); } - public function testMethodKey() + public function testMethodKey(): void { $structure = new Structure('id', ['StructureTest', 'suffix']); @@ -38,13 +48,10 @@ public function testMethodKey() } /** - * @param $table - * * @return string */ public static function suffix($table) { - return $table . '_id'; + return $table.'_id'; } - } diff --git a/tests/UtilitiesTest.php b/tests/UtilitiesTest.php index 87ce580..afdc95a 100644 --- a/tests/UtilitiesTest.php +++ b/tests/UtilitiesTest.php @@ -1,20 +1,30 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require __DIR__.'/_resources/init.php'; + +use Envms\FluentPDO\Query; +use Envms\FluentPDO\Utilities; use PHPUnit\Framework\TestCase; -use Envms\FluentPDO\{Query,Utilities}; /** - * Class UtilitiesTest + * Class UtilitiesTest. */ class UtilitiesTest extends TestCase { + protected Envms\FluentPDO\Query $fluent; - /** @var Envms\FluentPDO\Query */ - protected $fluent; - - public function setUp(): void + protected function setUp(): void { global $pdo; @@ -23,9 +33,8 @@ public function setUp(): void $this->fluent = new Query($pdo); } - public function testFluentUtil() + public function testFluentUtil(): void { - $value = Utilities::toUpperWords('one'); $value2 = Utilities::toUpperWords(' one '); $value3 = Utilities::toUpperWords('oneTwo'); @@ -41,7 +50,7 @@ public function testFluentUtil() self::assertEquals('ONE TWO THREE', $value6); } - public function testFormatQuery() + public function testFormatQuery(): void { $query = $this->fluent ->from('user') @@ -53,7 +62,7 @@ public function testFormatQuery() self::assertEquals("SELECT user.*\nFROM user\nWHERE id > ?\nORDER BY name", $formattedQuery); } - public function testConvertToNativeType() + public function testConvertToNativeType(): void { $query = $this->fluent ->from('user') @@ -69,7 +78,7 @@ public function testConvertToNativeType() self::assertEquals(['id' => 1], $forceInt); } - public function testConvertSqlWriteValues() + public function testConvertSqlWriteValues(): void { $valueArray = Utilities::convertSqlWriteValues(['string', 1, 2, false, true, null, 'false']); $value1 = Utilities::convertSqlWriteValues(false); @@ -80,7 +89,7 @@ public function testConvertSqlWriteValues() self::assertEquals(1, $value2); } - public function testisCountable() + public function testisCountable(): void { $selectQuery = $this->fluent ->from('user') @@ -92,8 +101,7 @@ public function testisCountable() ->deleteFrom('user') ->where('id', 1); - self::assertEquals(true, Utilities::isCountable($selectQuery)); - self::assertEquals(false, Utilities::isCountable($deleteQuery)); + self::assertTrue(Utilities::isCountable($selectQuery)); + self::assertFalse(Utilities::isCountable($deleteQuery)); } - -} \ No newline at end of file +} diff --git a/tests/_resources/init.php b/tests/_resources/init.php index b639ca2..f303a47 100644 --- a/tests/_resources/init.php +++ b/tests/_resources/init.php @@ -1,11 +1,20 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + if (getenv('TRAVIS')) { - $pdo = new PDO("mysql:dbname=fluentdb;host=localhost;charset=utf8", "root"); -} -else { - $pdo = new PDO("mysql:dbname=fluentdb;host=localhost;charset=utf8", "vagrant", "vagrant"); + $pdo = new PDO('mysql:dbname=fluentdb;host=localhost;charset=utf8', 'root'); +} else { + $pdo = new PDO('mysql:dbname=fluentdb;host=localhost;charset=utf8', 'vagrant', 'vagrant'); } $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);