From 4948cdbd46abcd0581b62cd5a03728dfdc45442a Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 3 Mar 2022 17:26:09 -0500 Subject: [PATCH] Set up a proper formatter for more consistent code style --- .gitignore | 4 +- .php-cs-fixer.dist.php | 551 ++++++++++++++++++ justfile | 31 + src/AnimeClient/API/APIRequestBuilder.php | 41 +- src/AnimeClient/API/AbstractListItem.php | 8 +- src/AnimeClient/API/Anilist/ListItem.php | 15 +- .../API/Anilist/MissingIdException.php | 4 +- src/AnimeClient/API/Anilist/Model.php | 20 +- .../API/Anilist/RequestBuilder.php | 52 +- .../API/Anilist/RequestBuilderTrait.php | 6 +- .../Transformer/AnimeListTransformer.php | 20 +- .../Transformer/MangaListTransformer.php | 22 +- .../API/Anilist/Types/MediaListEntry.php | 12 +- src/AnimeClient/API/CacheTrait.php | 7 +- .../API/Enum/AnimeWatchingStatus/Anilist.php | 5 +- .../API/Enum/AnimeWatchingStatus/Kitsu.php | 5 +- .../API/Enum/AnimeWatchingStatus/Route.php | 3 +- .../API/Enum/AnimeWatchingStatus/Title.php | 3 +- .../API/Enum/MangaReadingStatus/Anilist.php | 5 +- .../API/Enum/MangaReadingStatus/Kitsu.php | 5 +- .../API/Enum/MangaReadingStatus/Route.php | 3 +- .../API/Enum/MangaReadingStatus/Title.php | 3 +- .../API/FailedResponseException.php | 6 +- src/AnimeClient/API/Kitsu/Auth.php | 16 +- .../API/Kitsu/Enum/AnimeAiringStatus.php | 3 +- .../API/Kitsu/Enum/MangaPublishingStatus.php | 3 +- src/AnimeClient/API/Kitsu/ListItem.php | 38 +- src/AnimeClient/API/Kitsu/Model.php | 108 ++-- src/AnimeClient/API/Kitsu/MutationTrait.php | 5 +- src/AnimeClient/API/Kitsu/RequestBuilder.php | 59 +- .../API/Kitsu/RequestBuilderTrait.php | 8 +- .../Transformer/AnimeHistoryTransformer.php | 10 +- .../Transformer/AnimeListTransformer.php | 25 +- .../Kitsu/Transformer/AnimeTransformer.php | 20 +- .../Transformer/CharacterTransformer.php | 20 +- .../Kitsu/Transformer/HistoryTransformer.php | 35 +- .../Transformer/LibraryEntryTransformer.php | 18 +- .../Transformer/MangaHistoryTransformer.php | 10 +- .../Transformer/MangaListTransformer.php | 27 +- .../Kitsu/Transformer/MangaTransformer.php | 18 +- .../Kitsu/Transformer/PersonTransformer.php | 17 +- .../API/Kitsu/Transformer/UserTransformer.php | 8 +- .../API/Mapping/AnimeWatchingStatus.php | 20 +- .../API/Mapping/MangaReadingStatus.php | 18 +- src/AnimeClient/API/ParallelAPIRequest.php | 22 +- src/AnimeClient/Anilist.php | 17 +- src/AnimeClient/AnimeClient.php | 37 +- src/AnimeClient/Command/BaseCommand.php | 70 +-- src/AnimeClient/Command/CacheClear.php | 6 +- src/AnimeClient/Command/CachePrime.php | 7 +- src/AnimeClient/Command/ClearThumbnails.php | 8 +- src/AnimeClient/Command/SyncLists.php | 117 ++-- src/AnimeClient/Command/UpdateThumbnails.php | 7 +- src/AnimeClient/Component/AnimeCover.php | 5 +- src/AnimeClient/Component/Character.php | 5 +- src/AnimeClient/Component/ComponentTrait.php | 6 +- src/AnimeClient/Component/MangaCover.php | 5 +- src/AnimeClient/Component/Media.php | 5 +- src/AnimeClient/Component/Tabs.php | 12 +- src/AnimeClient/Component/VerticalTabs.php | 12 +- src/AnimeClient/Controller.php | 54 +- src/AnimeClient/Controller/Anime.php | 34 +- .../Controller/AnimeCollection.php | 33 +- src/AnimeClient/Controller/Character.php | 11 +- src/AnimeClient/Controller/History.php | 17 +- src/AnimeClient/Controller/Images.php | 35 +- src/AnimeClient/Controller/Manga.php | 29 +- src/AnimeClient/Controller/Misc.php | 12 +- src/AnimeClient/Controller/People.php | 11 +- src/AnimeClient/Controller/Settings.php | 13 +- src/AnimeClient/Controller/User.php | 9 +- src/AnimeClient/Dispatcher.php | 53 +- src/AnimeClient/Enum/API.php | 5 +- src/AnimeClient/Enum/EventType.php | 5 +- src/AnimeClient/Enum/MediaType.php | 5 +- src/AnimeClient/Enum/SyncAction.php | 5 +- src/AnimeClient/FormGenerator.php | 16 +- src/AnimeClient/Helper/Form.php | 4 +- src/AnimeClient/Helper/Menu.php | 7 +- src/AnimeClient/Helper/Picture.php | 22 +- src/AnimeClient/Kitsu.php | 62 +- src/AnimeClient/MenuGenerator.php | 20 +- src/AnimeClient/Model/API.php | 9 +- src/AnimeClient/Model/Anime.php | 11 +- src/AnimeClient/Model/AnimeCollection.php | 40 +- src/AnimeClient/Model/Collection.php | 6 +- src/AnimeClient/Model/DB.php | 7 +- src/AnimeClient/Model/Manga.php | 18 +- src/AnimeClient/Model/MediaTrait.php | 29 +- src/AnimeClient/Model/Settings.php | 37 +- src/AnimeClient/RoutingBase.php | 18 +- src/AnimeClient/Types/AbstractType.php | 36 +- src/AnimeClient/Types/Anime.php | 20 +- src/AnimeClient/Types/AnimeListItem.php | 13 +- src/AnimeClient/Types/AnimePage.php | 8 +- src/AnimeClient/Types/Character.php | 14 +- src/AnimeClient/Types/Characters.php | 6 +- src/AnimeClient/Types/Config.php | 25 +- src/AnimeClient/Types/Config/Anilist.php | 13 +- src/AnimeClient/Types/Config/Cache.php | 12 +- src/AnimeClient/Types/Config/Database.php | 14 +- src/AnimeClient/Types/FormItem.php | 8 +- src/AnimeClient/Types/FormItemData.php | 10 +- src/AnimeClient/Types/HistoryItem.php | 5 +- src/AnimeClient/Types/MangaListItem.php | 19 +- src/AnimeClient/Types/MangaListItemDetail.php | 10 +- src/AnimeClient/Types/MangaPage.php | 17 +- src/AnimeClient/Types/Media.php | 6 +- src/AnimeClient/Types/Person.php | 12 +- .../Types/UndefinedPropertyException.php | 4 +- src/AnimeClient/Types/User.php | 13 +- src/AnimeClient/UrlGenerator.php | 11 +- src/AnimeClient/Util.php | 11 +- src/AnimeClient/constants.php | 16 +- src/Ion/Config.php | 16 +- src/Ion/ConfigInterface.php | 11 +- src/Ion/Di/Container.php | 32 +- src/Ion/Di/ContainerAware.php | 7 +- src/Ion/Di/ContainerAwareInterface.php | 7 +- src/Ion/Di/ContainerInterface.php | 18 +- src/Ion/Di/Exception/ContainerException.php | 6 +- src/Ion/Di/Exception/NotFoundException.php | 6 +- src/Ion/Enum.php | 10 +- src/Ion/Event.php | 5 +- src/Ion/Exception/ConfigException.php | 6 +- src/Ion/Exception/DoubleRenderException.php | 10 +- src/Ion/Exception/ImageCreationException.php | 6 +- src/Ion/Friend.php | 18 +- src/Ion/HttpViewInterface.php | 10 +- src/Ion/ImageBuilder.php | 20 +- src/Ion/Json.php | 17 +- src/Ion/JsonException.php | 6 +- src/Ion/Model.php | 3 +- src/Ion/Transformer/AbstractTransformer.php | 13 +- src/Ion/Transformer/TransformerInterface.php | 6 +- src/Ion/Type/ArrayType.php | 22 +- src/Ion/Type/StringType.php | 13 +- src/Ion/View/HtmlView.php | 12 +- src/Ion/View/HttpView.php | 27 +- src/Ion/View/JsonView.php | 9 +- src/Ion/ViewInterface.php | 5 +- src/Ion/functions.php | 2 +- tools/rector.php | 4 +- 143 files changed, 1714 insertions(+), 1211 deletions(-) create mode 100644 .php-cs-fixer.dist.php create mode 100644 justfile diff --git a/.gitignore b/.gitignore index 02d5513e..ed3bfd88 100644 --- a/.gitignore +++ b/.gitignore @@ -152,4 +152,6 @@ public/mal_mappings.json tmp tools/vendor/ -tools/phinx/vendor/ \ No newline at end of file +tools/phinx/vendor/ +/.php-cs-fixer.php +/.php-cs-fixer.cache \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 00000000..b5620e82 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,551 @@ +in([ + __DIR__, + __DIR__ . '/tools', + // __DIR__ . '/app' + ]) + ->exclude([ + 'apidocs', + 'build', + 'coverage', + 'frontEndSrc', + 'phinx', + 'public', + 'tools', + 'tmp', + 'vendor' + ]); + +$srcFinder = Finder::create()->in(__DIR__ . '/src'); + +return (new Config()) + ->setRiskyAllowed(TRUE) + ->setFinder($srcFinder) + ->setIndent(' ') + ->setRules([ + 'align_multiline_comment' => false, + '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' => [ + '=' => NULL, + '&' => NULL, + ] + ], + 'blank_line_after_namespace' => true, + 'blank_line_after_opening_tag' => false, + 'blank_line_before_statement' => [ + 'statements' => [ + 'case', + 'continue', + 'declare', + 'default', + 'do', + 'exit', + 'for', + 'foreach', + 'goto', + 'return', + 'switch', + 'throw', + 'try', + 'while', + 'yield', + 'yield_from', + ], + ], + 'braces' => [ + 'allow_single_line_anonymous_class_with_empty_body' => true, + 'allow_single_line_closure' => true, + 'position_after_anonymous_constructs' => 'same', + 'position_after_control_structures' => 'next', + 'position_after_functions_and_oop_constructs' => 'next', + ], + 'cast_spaces' => ['space' => 'single'], + 'class_attributes_separation' => [ + 'elements' => [ + 'const' => 'none', + 'property' => 'none', + 'method' => 'one', + 'trait_import' => 'none', + ], + ], + 'class_definition' => [ + 'multi_line_extends_each_single_line' => true, + 'single_item_single_line' => true, + 'single_line' => true, + 'space_before_parenthesis' => true, + ], + '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' => [ + 'todo', + 'codeCoverageIgnore', + 'codeCoverageIgnoreStart', + 'codeCoverageIgnoreEnd', + 'phpstan-ignore-line', + 'phpstan-ignore-next-line', + ], + ], + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'constant_case' => ['case' => 'upper'], + 'control_structure_continuation_position' => ['position' => 'next_line'], + 'date_time_immutable' => false, + 'declare_equal_normalize' => ['space' => 'none'], + 'declare_parentheses' => true, + 'declare_strict_types' => true, + 'dir_constant' => true, + 'doctrine_annotation_array_assignment' => false, + 'doctrine_annotation_braces' => false, + 'doctrine_annotation_indentation' => false, + 'doctrine_annotation_spaces' => false, + 'echo_tag_syntax' => [ + 'format' => 'short', + 'long_function' => 'echo', + 'shorten_simple_statements_only' => false, + ], + 'elseif' => true, + 'empty_loop_body' => ['style' => 'braces'], + 'empty_loop_condition' => ['style' => 'while'], + 'encoding' => true, + 'ereg_to_preg' => true, + 'error_suppression' => [ + 'mute_deprecation_error' => true, + 'noise_remaining_usages' => false, + 'noise_remaining_usages_exclude' => [], + ], + 'escape_implicit_backslashes' => [ + 'double_quoted' => true, + 'heredoc_syntax' => true, + 'single_quoted' => false, + ], + 'explicit_indirect_variable' => true, + 'explicit_string_variable' => true, + 'final_class' => false, + 'final_internal_class' => [ + 'annotation_exclude' => ['@no-final'], + 'annotation_include' => ['@internal'], + 'consider_absent_docblock_as_internal_class' => false, + ], + 'final_public_method_for_abstract_class' => false, + 'fopen_flag_order' => true, + 'fopen_flags' => ['b_mode' => true], + 'full_opening_tag' => true, + 'fully_qualified_strict_types' => true, + 'function_declaration' => ['closure_function_spacing' => 'one'], + 'function_to_constant' => [ + 'functions' => [ + 'get_called_class', + 'get_class', + 'get_class_this', + 'php_sapi_name', + 'phpversion', + 'pi', + ], + ], + 'function_typehint_space' => true, + 'general_phpdoc_annotation_remove' => false, + 'general_phpdoc_tag_rename' => false, + 'get_class_to_class_keyword' => false, + 'global_namespace_import' => [ + 'import_constants' => true, + 'import_functions' => true, + 'import_classes' => true, + ], + 'group_import' => true, + 'header_comment' => false, // false by default + 'heredoc_indentation' => ['indentation' => 'start_plus_one'], + 'heredoc_to_nowdoc' => true, + 'implode_call' => true, + 'include' => true, + 'increment_style' => ['style' => 'post'], + 'indentation_type' => true, + 'integer_literal_case' => true, + 'is_null' => true, + 'lambda_not_used_import' => true, + 'line_ending' => true, + 'linebreak_after_opening_tag' => false, + 'list_syntax' => ['syntax' => 'short'], + 'logical_operators' => true, + 'lowercase_cast' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'mb_str_functions' => false, + 'method_argument_space' => [ + 'after_heredoc' => false, + 'keep_multiple_spaces_after_comma' => false, + 'on_multiline' => 'ensure_fully_multiline', + ], + 'method_chaining_indentation' => true, + 'modernize_strpos' => false, // requires 8.0+ + 'modernize_types_casting' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => ['strategy' => 'no_multi_line'], + 'native_constant_invocation' => false, + 'native_function_casing' => true, + 'native_function_invocation' => false, + 'native_function_type_declaration_casing' => true, + 'new_with_braces' => true, + 'no_alias_functions' => ['sets' => ['@all']], + 'no_alias_language_construct_call' => true, + 'no_alternative_syntax' => ['fix_non_monolithic_code' => false], + 'no_binary_string' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_blank_lines_before_namespace' => false, // conflicts with `single_blank_line_before_namespace` + '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' => ['extra']], + '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_null_property_initialization' => true, + // 'no_php4_constructor' => 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_spaces_inside_parenthesis' => true, + 'no_superfluous_elseif' => true, + 'no_superfluous_phpdoc_tags' => [ + 'allow_mixed' => true, + 'allow_unused_params' => true, + 'remove_inheritdoc' => false, + ], + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_trailing_whitespace_in_string' => true, + 'no_unneeded_control_parentheses' => [ + 'statements' => [ + 'break', + 'clone', + 'continue', + 'echo_print', + 'return', + 'switch_case', + 'yield', + ], + ], + 'no_unneeded_curly_braces' => ['namespaces' => true], + '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' => false, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_useless_sprintf' => true, + 'no_whitespace_before_comma_in_array' => ['after_heredoc' => true], + 'no_whitespace_in_blank_line' => true, + 'non_printable_character' => ['use_escape_sequences_in_strings' => true], + 'normalize_index_brace' => true, + 'not_operator_with_space' => true, + 'not_operator_with_successor_space' => true, + 'nullable_type_declaration_for_default_null_value' => ['use_nullable_type_declaration' => true], + 'object_operator_without_whitespace' => true, + // 'octal_notation' => false, // requires 8.1+ + 'operator_linebreak' => ['only_booleans' => true, 'position' => 'beginning'], + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', + 'constant', + 'property', + 'method', + ], + 'sort_algorithm' => 'none', + ], + 'ordered_imports' => [ + 'sort_algorithm' => 'alpha', + 'imports_order' => ['class', 'function', 'const'], + ], + 'ordered_interfaces' => false, + 'ordered_traits' => false, + 'php_unit_construct' => [ + 'assertions' => [ + 'assertSame', + 'assertEquals', + 'assertNotEquals', + 'assertNotSame', + ], + ], + '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_internal_class' => ['types' => ['normal', 'final']], + '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_size_class' => false, + 'php_unit_strict' => [ + 'assertions' => [ + 'assertAttributeEquals', + 'assertAttributeNotEquals', + 'assertEquals', + 'assertNotEquals', + ], + ], + 'php_unit_test_annotation' => ['style' => 'prefix'], + 'php_unit_test_case_static_method_calls' => [ + 'call_type' => 'this', + 'methods' => [], + ], + 'php_unit_test_class_requires_covers' => false, + 'phpdoc_add_missing_param_annotation' => ['only_untyped' => true], + 'phpdoc_align' => [ + 'align' => 'left' + ], +// 'phpdoc_align' => [ +// 'align' => 'vertical', +// 'tags' => [ +// 'method', +// 'param', +// 'property', +// 'return', +// 'throws', +// 'type', +// 'var', +// ], +// ], + 'phpdoc_annotation_without_dot' => false, + 'phpdoc_indent' => true, + 'phpdoc_inline_tag_normalizer' => [ + 'tags' => [ + 'example', + 'id', + 'internal', + 'inheritdoc', + 'inheritdocs', + 'link', + 'source', + 'toc', + 'tutorial', + ], + ], + 'phpdoc_line_span' => [ + 'const' => 'multi', + 'method' => 'multi', + 'property' => 'multi', + ], + 'phpdoc_no_access' => true, +// 'phpdoc_no_alias_tag' => [ +// 'replacements' => [ +// 'property-read' => 'property', +// 'property-write' => 'property', +// 'type' => 'var', +// 'link' => 'see', +// ], +// ], + 'phpdoc_no_empty_return' => false, + 'phpdoc_no_package' => false, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => true, + 'phpdoc_order_by_value' => [ + 'annotations' => [ + 'author', + 'covers', + 'coversNothing', + 'dataProvider', + 'depends', + 'group', + 'internal', + 'method', + 'property', + 'property-read', + 'property-write', + 'requires', + 'throws', + 'uses', + ], + ], + 'phpdoc_return_self_reference' => [ + 'replacements' => [ + 'this' => '$this', + '@this' => '$this', + '$self' => 'self', + '@self' => 'self', + '$static' => 'static', + '@static' => 'static', + ], + ], + 'phpdoc_scalar' => [ + 'types' => [ + 'boolean', + 'callback', + 'double', + 'integer', + 'real', + 'str', + ], + ], + 'phpdoc_separation' => false, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_summary' => false, + 'phpdoc_tag_casing' => ['tags' => ['inheritDoc']], + 'phpdoc_tag_type' => ['tags' => ['inheritDoc' => 'inline']], + 'phpdoc_to_comment' => false, + 'phpdoc_to_param_type' => false, + 'phpdoc_to_property_type' => false, + 'phpdoc_to_return_type' => false, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types' => ['groups' => ['simple', 'alias', 'meta']], + 'phpdoc_types_order' => [ + 'null_adjustment' => 'always_last', + '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' => false, + 'self_static_accessor' => true, + 'semicolon_after_instruction' => false, + 'set_type_to_cast' => true, + 'short_scalar_cast' => true, + 'simple_to_complex_string_variable' => true, + 'simplified_if_return' => true, + 'simplified_null_return' => false, + 'single_blank_line_at_eof' => true, + 'single_blank_line_before_namespace' => true, + 'single_class_element_per_statement' => ['elements' => ['const', 'property']], + 'single_import_per_statement' => false, + 'single_line_after_imports' => true, + 'single_line_comment_style' => ['comment_types' => ['asterisk', 'hash']], + 'single_line_throw' => false, + 'single_quote' => ['strings_containing_single_quote_chars' => false], + 'single_space_after_construct' => [ + 'constructs' => [ + 'abstract', + 'as', + 'attribute', + 'break', + 'case', + 'catch', + 'class', + 'clone', + 'comment', + 'const', + 'const_import', + 'continue', + 'do', + 'echo', + 'else', + 'elseif', + 'extends', + 'final', + 'finally', + 'for', + 'foreach', + 'function', + 'function_import', + 'global', + 'goto', + 'if', + 'implements', + 'include', + 'include_once', + 'instanceof', + 'insteadof', + 'interface', + 'match', + 'named_argument', + 'new', + 'open_tag_with_echo', + 'php_doc', + 'php_open', + 'print', + 'private', + 'protected', + 'public', + 'require', + 'require_once', + 'return', + 'static', + 'throw', + 'trait', + 'try', + 'use', + 'use_lambda', + 'use_trait', + 'var', + 'while', + 'yield', + 'yield_from', + ], + ], + 'single_trait_insert_per_statement' => true, + 'space_after_semicolon' => ['remove_in_empty_for_expressions' => true], + 'standardize_increment' => true, + 'standardize_not_equals' => true, + 'static_lambda' => true, + 'strict_comparison' => true, + 'strict_param' => true, + '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' => true, + 'elements' => ['arrays'], + ], + 'trim_array_spaces' => true, + 'types_spaces' => ['space' => 'none'], + 'unary_operator_spaces' => false, + 'use_arrow_functions' => true, + 'visibility_required' => ['elements' => ['const', 'method', 'property']], + 'void_return' => false, // changes method signature + 'whitespace_after_comma_in_array' => true, + 'yoda_style' => [ + 'equal' => false, + 'identical' => null, + 'less_and_greater' => false, + 'always_move_variable' => false, + ], + ]); diff --git a/justfile b/justfile new file mode 100644 index 00000000..820343f2 --- /dev/null +++ b/justfile @@ -0,0 +1,31 @@ +# Lists the available actions +default: + @just --list + +# Runs rector, showing what changes will be make +rector-dry-run: + tools/vendor/bin/rector process --config=tools/rector.php --dry-run src + +# Runs rector, and updates the files +rector: + tools/vendor/bin/rector process --config=tools/rector.php src + +# Check code formatting +check-fmt: + tools/vendor/bin/php-cs-fixer fix --dry-run --verbose + +# Fix code formatting +fmt: + tools/vendor/bin/php-cs-fixer fix --verbose + +# Run tests +test: + composer run-script test + +# Run tests, update snapshots +test-update: + composer run-script test-update + +# Run unit tests and generate test-coverage report +coverage: + composer run-script coverage \ No newline at end of file diff --git a/src/AnimeClient/API/APIRequestBuilder.php b/src/AnimeClient/API/APIRequestBuilder.php index 95110258..a82eb698 100644 --- a/src/AnimeClient/API/APIRequestBuilder.php +++ b/src/AnimeClient/API/APIRequestBuilder.php @@ -16,21 +16,25 @@ namespace Aviat\AnimeClient\API; -use const Aviat\AnimeClient\USER_AGENT; - -use function Amp\Promise\wait; -use function Aviat\AnimeClient\getResponse; +use Amp\Http\Client\Body\FormBody; use Amp\Http\Client\Request; -use Amp\Http\Client\Body\FormBody; use Aviat\Ion\Json; + +use Error; use InvalidArgumentException; use Psr\Log\LoggerAwareTrait; +use Throwable; +use TypeError; +use function Amp\Promise\wait; +use function Aviat\AnimeClient\getResponse; +use const Aviat\AnimeClient\USER_AGENT; /** * Wrapper around Http\Client to make it easier to build API requests */ -abstract class APIRequestBuilder { +abstract class APIRequestBuilder +{ use LoggerAwareTrait; /** @@ -101,6 +105,7 @@ abstract class APIRequestBuilder { public function setBasicAuth(string $username, string $password): self { $this->setAuth('basic', base64_encode($username . ':' . $password)); + return $this; } @@ -110,6 +115,7 @@ abstract class APIRequestBuilder { public function setBody(FormBody|string $body): self { $this->request->setBody($body); + return $this; } @@ -132,15 +138,14 @@ abstract class APIRequestBuilder { public function unsetHeader(string $name): self { $this->request->removeHeader($name); + return $this; } /** * Set a request header - * - * @param string|null $value */ - public function setHeader(string $name, string $value = NULL): self + public function setHeader(string $name, ?string $value = NULL): self { if (NULL === $value) { @@ -158,8 +163,6 @@ abstract class APIRequestBuilder { * Set multiple request headers * * name => value - * - * @param array $headers */ public function setHeaders(array $headers): self { @@ -176,7 +179,7 @@ abstract class APIRequestBuilder { */ public function setJsonBody(mixed $body): self { - $requestBody = ( is_string($body)) + $requestBody = (is_string($body)) ? $body : Json::encode($body); @@ -189,13 +192,14 @@ abstract class APIRequestBuilder { public function setQuery(array $params): self { $this->query = http_build_query($params); + return $this; } /** * Return the promise for the current request * - * @throws \Throwable + * @throws Throwable */ public function getFullRequest(): Request { @@ -210,7 +214,7 @@ abstract class APIRequestBuilder { $this->request->getBody() ->createBodyStream() ->read() - ) + ), ]); } @@ -220,14 +224,15 @@ abstract class APIRequestBuilder { /** * Get the data from the response of the passed request * + * @throws Error + * @throws Throwable + * @throws TypeError * @return mixed - * @throws \Error - * @throws \Throwable - * @throws \TypeError */ public function getResponseData(Request $request) { $response = getResponse($request); + return wait($response->getBody()->buffer()); } @@ -295,4 +300,4 @@ abstract class APIRequestBuilder { $this->request->setTcpConnectTimeout(300000); $this->request->setTransferTimeout(300000); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/AbstractListItem.php b/src/AnimeClient/API/AbstractListItem.php index ba4279a3..2e8944f3 100644 --- a/src/AnimeClient/API/AbstractListItem.php +++ b/src/AnimeClient/API/AbstractListItem.php @@ -22,8 +22,8 @@ use Aviat\AnimeClient\Types\FormItemData; /** * Common interface for anime and manga list item CRUD */ -abstract class AbstractListItem { - +abstract class AbstractListItem +{ /** * Create a list item * @@ -62,5 +62,5 @@ abstract class AbstractListItem { * * @param string $id - The id of the list item to delete */ - abstract public function delete(string $id):?Request; -} \ No newline at end of file + abstract public function delete(string $id): ?Request; +} diff --git a/src/AnimeClient/API/Anilist/ListItem.php b/src/AnimeClient/API/Anilist/ListItem.php index 68166dc9..e8ea58d3 100644 --- a/src/AnimeClient/API/Anilist/ListItem.php +++ b/src/AnimeClient/API/Anilist/ListItem.php @@ -26,7 +26,8 @@ use Aviat\AnimeClient\Types\FormItemData; /** * CRUD operations for MAL list items */ -final class ListItem extends AbstractListItem { +final class ListItem extends AbstractListItem +{ use RequestBuilderTrait; /** @@ -35,6 +36,7 @@ final class ListItem extends AbstractListItem { public function create(array $data): Request { $checkedData = Types\MediaListEntry::check($data); + return $this->requestBuilder->mutateRequest('CreateMediaListEntry', $checkedData ?? []); } @@ -44,6 +46,7 @@ final class ListItem extends AbstractListItem { public function createFull(array $data): Request { $checkedData = Types\MediaListEntry::check($data); + return $this->requestBuilder->mutateRequest('CreateFullMediaListEntry', $checkedData ?? []); } @@ -82,23 +85,23 @@ final class ListItem extends AbstractListItem { public function update(string $id, FormItemData $data): Request { $notes = $data->notes ?? ''; - $progress = (int)$data->progress; - $private = (bool)$data->private; + $progress = (int) $data->progress; + $private = (bool) $data->private; $rating = $data->ratingTwenty; $status = ($data->reconsuming === TRUE) ? AnilistStatus::REPEATING : AnimeWatchingStatus::KITSU_TO_ANILIST[$data->status]; $updateData = Types\MediaListEntry::check([ - 'id' => (int)$id, + 'id' => (int) $id, 'status' => $status, 'score' => $rating * 5, 'progress' => $progress, - 'repeat' => (int)$data['reconsumeCount'], + 'repeat' => (int) $data['reconsumeCount'], 'private' => $private, 'notes' => $notes, ]); return $this->requestBuilder->mutateRequest('UpdateMediaListEntry', $updateData ?? []); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Anilist/MissingIdException.php b/src/AnimeClient/API/Anilist/MissingIdException.php index 1ba5f776..cb6e8bfb 100644 --- a/src/AnimeClient/API/Anilist/MissingIdException.php +++ b/src/AnimeClient/API/Anilist/MissingIdException.php @@ -18,4 +18,6 @@ namespace Aviat\AnimeClient\API\Anilist; use InvalidArgumentException; -class MissingIdException extends InvalidArgumentException {} \ No newline at end of file +class MissingIdException extends InvalidArgumentException +{ +} diff --git a/src/AnimeClient/API/Anilist/Model.php b/src/AnimeClient/API/Anilist/Model.php index ab5576a5..be56bff9 100644 --- a/src/AnimeClient/API/Anilist/Model.php +++ b/src/AnimeClient/API/Anilist/Model.php @@ -16,19 +16,17 @@ namespace Aviat\AnimeClient\API\Anilist; -use function Amp\Promise\wait; - -use InvalidArgumentException; - use Amp\Http\Client\Request; + use Aviat\AnimeClient\Anilist; + use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus}; use Aviat\AnimeClient\Types\FormItem; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Json; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; - +use InvalidArgumentException; use Throwable; +use function Amp\Promise\wait; /** * Anilist API Model @@ -179,7 +177,7 @@ final class Model $data = $this->listItem->get($id)['data']; - return ($data !== null) + return ($data !== NULL) ? $data['MediaList'] : []; } @@ -270,7 +268,7 @@ final class Model return NULL; } - return (string)$info['data']['MediaList']['id']; + return (string) $info['data']['MediaList']['id']; } /** @@ -293,6 +291,6 @@ final class Model return NULL; } - return (string)$info['data']['Media']['id']; + return (string) $info['data']['Media']['id']; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Anilist/RequestBuilder.php b/src/AnimeClient/API/Anilist/RequestBuilder.php index 1e5a5e3a..5c728b7d 100644 --- a/src/AnimeClient/API/Anilist/RequestBuilder.php +++ b/src/AnimeClient/API/Anilist/RequestBuilder.php @@ -16,24 +16,22 @@ namespace Aviat\AnimeClient\API\Anilist; -use Amp\Http\Client\Request; -use Amp\Http\Client\Response; +use Amp\Http\Client\{Request, Response}; use Aviat\AnimeClient\Anilist; -use Aviat\Ion\Di\ContainerAware; -use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Json; - -use Aviat\Ion\JsonException; -use function Amp\Promise\wait; -use function Aviat\AnimeClient\getResponse; -use const Aviat\AnimeClient\USER_AGENT; - use Aviat\AnimeClient\API\APIRequestBuilder; - +use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; +use Aviat\Ion\{Json, JsonException}; use LogicException; use Throwable; -final class RequestBuilder extends APIRequestBuilder { +use function Amp\Promise\wait; + +use function Aviat\AnimeClient\getResponse; +use function in_array; +use const Aviat\AnimeClient\USER_AGENT; + +final class RequestBuilder extends APIRequestBuilder +{ use ContainerAware; /** @@ -115,27 +113,28 @@ final class RequestBuilder extends APIRequestBuilder { $query = file_get_contents($file); $body = [ - 'query' => $query + 'query' => $query, ]; if ( ! empty($variables)) { $body['variables'] = []; - foreach($variables as $key => $val) + + foreach ($variables as $key => $val) { $body['variables'][$key] = $val; } } return $this->postRequest([ - 'body' => $body + 'body' => $body, ]); } /** * @throws Throwable */ - public function mutateRequest (string $name, array $variables = []): Request + public function mutateRequest(string $name, array $variables = []): Request { $file = __DIR__ . "/Mutations/{$name}.graphql"; if ( ! file_exists($file)) @@ -146,11 +145,13 @@ final class RequestBuilder extends APIRequestBuilder { $query = file_get_contents($file); $body = [ - 'query' => $query + 'query' => $query, ]; - if (!empty($variables)) { + if ( ! empty($variables)) + { $body['variables'] = []; + foreach ($variables as $key => $val) { $body['variables'][$key] = $val; @@ -166,7 +167,7 @@ final class RequestBuilder extends APIRequestBuilder { * @throws Throwable * @return mixed[] */ - public function mutate (string $name, array $variables = []): array + public function mutate(string $name, array $variables = []): array { $request = $this->mutateRequest($name, $variables); $response = $this->getResponseFromRequest($request); @@ -242,13 +243,13 @@ final class RequestBuilder extends APIRequestBuilder { //'requestHeaders' => $request->getHeaders(), ]); - - if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE)) + if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE)) { - $logger?->warning('Non 200 response for POST api call', (array)$response->getBody()); + $logger?->warning('Non 200 response for POST api call', (array) $response->getBody()); } $rawBody = wait($response->getBody()->buffer()); + try { return Json::decode($rawBody); @@ -257,7 +258,8 @@ final class RequestBuilder extends APIRequestBuilder { { dump($e); dump($rawBody); - die(); + + exit(); } } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Anilist/RequestBuilderTrait.php b/src/AnimeClient/API/Anilist/RequestBuilderTrait.php index f5df579f..d8e5028c 100644 --- a/src/AnimeClient/API/Anilist/RequestBuilderTrait.php +++ b/src/AnimeClient/API/Anilist/RequestBuilderTrait.php @@ -18,7 +18,8 @@ namespace Aviat\AnimeClient\API\Anilist; use Aviat\Ion\Di\ContainerAware; -trait RequestBuilderTrait { +trait RequestBuilderTrait +{ use ContainerAware; /** @@ -32,6 +33,7 @@ trait RequestBuilderTrait { public function setRequestBuilder(RequestBuilder $requestBuilder): self { $this->requestBuilder = $requestBuilder; + return $this; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php b/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php index bb22d117..b5189f7a 100644 --- a/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php +++ b/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php @@ -16,9 +16,7 @@ namespace Aviat\AnimeClient\API\Anilist\Transformer; -use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Anilist as AnilistStatus; -use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuStatus; -use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; +use Aviat\AnimeClient\API\{Enum, Mapping}; use Aviat\AnimeClient\Types\{AnimeListItem, FormItem}; use Aviat\Ion\Transformer\AbstractTransformer; @@ -26,8 +24,8 @@ use Aviat\Ion\Transformer\AbstractTransformer; use DateTime; use DateTimeInterface; -class AnimeListTransformer extends AbstractTransformer { - +class AnimeListTransformer extends AbstractTransformer +{ public function transform(array|object $item): AnimeListItem { return AnimeListItem::from([]); @@ -35,12 +33,10 @@ class AnimeListTransformer extends AbstractTransformer { /** * Transform Anilist list item to Kitsu form update format - * - * @return FormItem */ public function untransform(array $item): FormItem { - $reconsuming = $item['status'] === AnilistStatus::REPEATING; + $reconsuming = $item['status'] === Enum\AnimeWatchingStatus\Anilist::REPEATING; return FormItem::from([ 'id' => $item['id'], @@ -53,12 +49,12 @@ class AnimeListTransformer extends AbstractTransformer { 'reconsumeCount' => $item['repeat'], 'reconsuming' => $reconsuming, 'status' => $reconsuming - ? KitsuStatus::WATCHING - : AnimeWatchingStatus::ANILIST_TO_KITSU[$item['status']], + ? Enum\AnimeWatchingStatus\Kitsu::WATCHING + : Mapping\AnimeWatchingStatus::ANILIST_TO_KITSU[$item['status']], 'updatedAt' => (new DateTime()) ->setTimestamp($item['updatedAt']) - ->format(DateTimeInterface::W3C) + ->format(DateTimeInterface::W3C), ], ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php b/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php index 2dcd5d0b..d494c48e 100644 --- a/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php +++ b/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php @@ -16,19 +16,15 @@ namespace Aviat\AnimeClient\API\Anilist\Transformer; -use Aviat\AnimeClient\API\Enum\MangaReadingStatus\Anilist as AnilistStatus; -use Aviat\AnimeClient\API\Enum\MangaReadingStatus\Kitsu as KitsuStatus; -use Aviat\AnimeClient\API\Mapping\MangaReadingStatus; -use Aviat\AnimeClient\Types\MangaListItem; -use Aviat\AnimeClient\Types\FormItem; - +use Aviat\AnimeClient\API\{Enum, Mapping}; +use Aviat\AnimeClient\Types\{FormItem, MangaListItem}; use Aviat\Ion\Transformer\AbstractTransformer; use DateTime; use DateTimeInterface; -class MangaListTransformer extends AbstractTransformer { - +class MangaListTransformer extends AbstractTransformer +{ public function transform(array|object $item): MangaListItem { return MangaListItem::from([]); @@ -39,7 +35,7 @@ class MangaListTransformer extends AbstractTransformer { */ public function untransform(array $item): FormItem { - $reconsuming = $item['status'] === AnilistStatus::REPEATING; + $reconsuming = $item['status'] === Enum\MangaReadingStatus\Anilist::REPEATING; return FormItem::from([ 'id' => $item['id'], @@ -52,12 +48,12 @@ class MangaListTransformer extends AbstractTransformer { 'reconsumeCount' => $item['repeat'], 'reconsuming' => $reconsuming, 'status' => $reconsuming - ? KitsuStatus::READING - : MangaReadingStatus::ANILIST_TO_KITSU[$item['status']], + ? Enum\MangaReadingStatus\Kitsu::READING + : Mapping\MangaReadingStatus::ANILIST_TO_KITSU[$item['status']], 'updatedAt' => (new DateTime()) ->setTimestamp($item['updatedAt']) ->format(DateTimeInterface::W3C), - ] + ], ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Anilist/Types/MediaListEntry.php b/src/AnimeClient/API/Anilist/Types/MediaListEntry.php index b846b017..05919791 100644 --- a/src/AnimeClient/API/Anilist/Types/MediaListEntry.php +++ b/src/AnimeClient/API/Anilist/Types/MediaListEntry.php @@ -18,19 +18,13 @@ namespace Aviat\AnimeClient\API\Anilist\Types; use Aviat\AnimeClient\Types\AbstractType; -class MediaListEntry extends AbstractType { - +class MediaListEntry extends AbstractType +{ public int|string $id; - public ?string $notes; - public ?bool $private; - public int $progress; - public ?int $repeat; - public string $status; - public ?int $score; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/CacheTrait.php b/src/AnimeClient/API/CacheTrait.php index cb18ef27..b3490c74 100644 --- a/src/AnimeClient/API/CacheTrait.php +++ b/src/AnimeClient/API/CacheTrait.php @@ -21,8 +21,8 @@ use Psr\SimpleCache\CacheInterface; /** * Helper methods for dealing with the Cache */ -trait CacheTrait { - +trait CacheTrait +{ protected CacheInterface $cache; /** @@ -31,6 +31,7 @@ trait CacheTrait { public function setCache(CacheInterface $cache): self { $this->cache = $cache; + return $this; } @@ -64,4 +65,4 @@ trait CacheTrait { return $value; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Anilist.php b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Anilist.php index 80ed0ccd..3df76050 100644 --- a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Anilist.php +++ b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Anilist.php @@ -21,11 +21,12 @@ use Aviat\Ion\Enum; /** * Possible values for watching status for the current anime */ -final class Anilist extends Enum { +final class Anilist extends Enum +{ public const WATCHING = 'CURRENT'; public const COMPLETED = 'COMPLETED'; public const ON_HOLD = 'PAUSED'; public const DROPPED = 'DROPPED'; public const PLAN_TO_WATCH = 'PLANNING'; public const REPEATING = 'REPEATING'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Kitsu.php b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Kitsu.php index a91059a5..aa3d2e12 100644 --- a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Kitsu.php +++ b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Kitsu.php @@ -21,10 +21,11 @@ use Aviat\Ion\Enum; /** * Possible values for watching status for the current anime */ -final class Kitsu extends Enum { +final class Kitsu extends Enum +{ public const WATCHING = 'current'; public const PLAN_TO_WATCH = 'planned'; public const ON_HOLD = 'on_hold'; public const DROPPED = 'dropped'; public const COMPLETED = 'completed'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Route.php b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Route.php index 3a6725f1..56501da4 100644 --- a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Route.php +++ b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Route.php @@ -21,7 +21,8 @@ use Aviat\Ion\Enum; /** * Possible values for current watching status of anime */ -final class Route extends Enum { +final class Route extends Enum +{ public const ALL = 'all'; public const WATCHING = 'watching'; public const PLAN_TO_WATCH = 'plan_to_watch'; diff --git a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Title.php b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Title.php index 3393a2ea..ddaca39e 100644 --- a/src/AnimeClient/API/Enum/AnimeWatchingStatus/Title.php +++ b/src/AnimeClient/API/Enum/AnimeWatchingStatus/Title.php @@ -21,7 +21,8 @@ use Aviat\Ion\Enum; /** * Possible values for current watching status of anime */ -final class Title extends Enum { +final class Title extends Enum +{ public const ALL = 'All'; public const WATCHING = 'Currently Watching'; public const PLAN_TO_WATCH = 'Plan to Watch'; diff --git a/src/AnimeClient/API/Enum/MangaReadingStatus/Anilist.php b/src/AnimeClient/API/Enum/MangaReadingStatus/Anilist.php index 6b2f8624..cb93faf9 100644 --- a/src/AnimeClient/API/Enum/MangaReadingStatus/Anilist.php +++ b/src/AnimeClient/API/Enum/MangaReadingStatus/Anilist.php @@ -21,11 +21,12 @@ use Aviat\Ion\Enum; /** * Possible values for watching status for the current anime */ -final class Anilist extends Enum { +final class Anilist extends Enum +{ public const READING = 'CURRENT'; public const COMPLETED = 'COMPLETED'; public const ON_HOLD = 'PAUSED'; public const DROPPED = 'DROPPED'; public const PLAN_TO_READ = 'PLANNING'; public const REPEATING = 'REPEATING'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Enum/MangaReadingStatus/Kitsu.php b/src/AnimeClient/API/Enum/MangaReadingStatus/Kitsu.php index 94c62bd6..5d547015 100644 --- a/src/AnimeClient/API/Enum/MangaReadingStatus/Kitsu.php +++ b/src/AnimeClient/API/Enum/MangaReadingStatus/Kitsu.php @@ -21,10 +21,11 @@ use Aviat\Ion\Enum; /** * Possible values for current reading status of manga */ -final class Kitsu extends Enum { +final class Kitsu extends Enum +{ public const READING = 'current'; public const PLAN_TO_READ = 'planned'; public const DROPPED = 'dropped'; public const ON_HOLD = 'on_hold'; public const COMPLETED = 'completed'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Enum/MangaReadingStatus/Route.php b/src/AnimeClient/API/Enum/MangaReadingStatus/Route.php index c65ecd38..99e4ad25 100644 --- a/src/AnimeClient/API/Enum/MangaReadingStatus/Route.php +++ b/src/AnimeClient/API/Enum/MangaReadingStatus/Route.php @@ -21,7 +21,8 @@ use Aviat\Ion\Enum; /** * Possible values for current reading status of manga */ -final class Route extends Enum { +final class Route extends Enum +{ public const ALL = 'all'; public const READING = 'reading'; public const PLAN_TO_READ = 'plan_to_read'; diff --git a/src/AnimeClient/API/Enum/MangaReadingStatus/Title.php b/src/AnimeClient/API/Enum/MangaReadingStatus/Title.php index 9fc01fd4..cba4dbc7 100644 --- a/src/AnimeClient/API/Enum/MangaReadingStatus/Title.php +++ b/src/AnimeClient/API/Enum/MangaReadingStatus/Title.php @@ -21,7 +21,8 @@ use Aviat\Ion\Enum; /** * Possible values for current reading status of manga */ -final class Title extends Enum { +final class Title extends Enum +{ public const ALL = 'All'; public const READING = 'Currently Reading'; public const PLAN_TO_READ = 'Plan to Read'; diff --git a/src/AnimeClient/API/FailedResponseException.php b/src/AnimeClient/API/FailedResponseException.php index 26bd939b..4ff3c391 100644 --- a/src/AnimeClient/API/FailedResponseException.php +++ b/src/AnimeClient/API/FailedResponseException.php @@ -21,6 +21,6 @@ use UnexpectedValueException; /** * Exception for an API Request that fails validation */ -class FailedResponseException extends UnexpectedValueException { - -} \ No newline at end of file +class FailedResponseException extends UnexpectedValueException +{ +} diff --git a/src/AnimeClient/API/Kitsu/Auth.php b/src/AnimeClient/API/Kitsu/Auth.php index 6ed48960..879ada2f 100644 --- a/src/AnimeClient/API/Kitsu/Auth.php +++ b/src/AnimeClient/API/Kitsu/Auth.php @@ -18,17 +18,18 @@ namespace Aviat\AnimeClient\API\Kitsu; use Aura\Session\Segment; -use const Aviat\AnimeClient\SESSION_SEGMENT; +use Aviat\AnimeClient\API\CacheTrait; use Aviat\AnimeClient\Kitsu as K; -use Aviat\AnimeClient\API\CacheTrait; use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; use Aviat\Ion\Event; +use const Aviat\AnimeClient\SESSION_SEGMENT; /** * Kitsu API Authentication */ -final class Auth { +final class Auth +{ use CacheTrait; use ContainerAware; @@ -44,8 +45,6 @@ final class Auth { /** * Constructor - * - * @param ContainerInterface $container */ public function __construct(ContainerInterface $container) { @@ -94,7 +93,7 @@ final class Auth { */ public function isAuthenticated(): bool { - return ($this->getAuthToken() !== NULL); + return $this->getAuthToken() !== NULL; } /** @@ -136,7 +135,7 @@ final class Auth { /** * Save the new authentication information */ - private function storeAuth(array|false $auth): bool + private function storeAuth(array|FALSE $auth): bool { if (FALSE !== $auth) { @@ -157,6 +156,7 @@ final class Auth { $this->segment->set('auth_token', $auth['access_token']); $this->segment->set('auth_token_expires', $expire_time); $this->segment->set('refresh_token', $auth['refresh_token']); + return TRUE; } } @@ -165,4 +165,4 @@ final class Auth { } } -// End of KitsuAuth.php \ No newline at end of file +// End of KitsuAuth.php diff --git a/src/AnimeClient/API/Kitsu/Enum/AnimeAiringStatus.php b/src/AnimeClient/API/Kitsu/Enum/AnimeAiringStatus.php index 1460e202..3fb145d6 100644 --- a/src/AnimeClient/API/Kitsu/Enum/AnimeAiringStatus.php +++ b/src/AnimeClient/API/Kitsu/Enum/AnimeAiringStatus.php @@ -21,7 +21,8 @@ use Aviat\Ion\Enum as BaseEnum; /** * Status of when anime is being/was/will be aired */ -final class AnimeAiringStatus extends BaseEnum { +final class AnimeAiringStatus extends BaseEnum +{ public const NOT_YET_AIRED = 'Not Yet Aired'; public const AIRING = 'Currently Airing'; public const FINISHED_AIRING = 'Finished Airing'; diff --git a/src/AnimeClient/API/Kitsu/Enum/MangaPublishingStatus.php b/src/AnimeClient/API/Kitsu/Enum/MangaPublishingStatus.php index c6436855..93966972 100644 --- a/src/AnimeClient/API/Kitsu/Enum/MangaPublishingStatus.php +++ b/src/AnimeClient/API/Kitsu/Enum/MangaPublishingStatus.php @@ -21,7 +21,8 @@ use Aviat\Ion\Enum as BaseEnum; /** * Status of when anime is being/was/will be aired */ -final class MangaPublishingStatus extends BaseEnum { +final class MangaPublishingStatus extends BaseEnum +{ public const NOT_YET_PUBLISHED = 'Not Yet Published'; public const FINISHED = 'Completed'; public const CURRENT = 'Current'; diff --git a/src/AnimeClient/API/Kitsu/ListItem.php b/src/AnimeClient/API/Kitsu/ListItem.php index 3d8bfd9d..cb18b511 100644 --- a/src/AnimeClient/API/Kitsu/ListItem.php +++ b/src/AnimeClient/API/Kitsu/ListItem.php @@ -26,7 +26,8 @@ use Throwable; /** * CRUD operations for Kitsu list items */ -final class ListItem extends AbstractListItem { +final class ListItem extends AbstractListItem +{ use ContainerAware; use RequestBuilderTrait; @@ -50,23 +51,23 @@ final class ListItem extends AbstractListItem { 'type' => 'libraryEntries', 'attributes' => [ 'status' => $data['status'], - 'progress' => $data['progress'] ?? 0 + 'progress' => $data['progress'] ?? 0, ], 'relationships' => [ 'user' => [ 'data' => [ 'id' => $data['user_id'], - 'type' => 'users' - ] + 'type' => 'users', + ], ], 'media' => [ 'data' => [ 'id' => $data['id'], - 'type' => $data['type'] - ] - ] - ] - ] + 'type' => $data['type'], + ], + ], + ], + ], ]; if (array_key_exists('notes', $data)) @@ -93,7 +94,7 @@ final class ListItem extends AbstractListItem { public function delete(string $id): Request { return $this->requestBuilder->mutateRequest('DeleteLibraryItem', [ - 'id' => $id + 'id' => $id, ]); } @@ -115,7 +116,7 @@ final class ListItem extends AbstractListItem { { return $this->requestBuilder->mutateRequest('IncrementLibraryItem', [ 'id' => $id, - 'progress' => $data->progress + 'progress' => $data->progress, ]); } @@ -128,21 +129,21 @@ final class ListItem extends AbstractListItem { $updateData = [ 'id' => $id, 'notes' => $data['notes'], - 'private' => (bool)$data['private'], - 'reconsumeCount' => (int)$data['reconsumeCount'], - 'reconsuming' => (bool)$data['reconsuming'], + 'private' => (bool) $data['private'], + 'reconsumeCount' => (int) $data['reconsumeCount'], + 'reconsuming' => (bool) $data['reconsuming'], 'status' => strtoupper($data['status']), ]; // Only send these variables if they have a value if ($data['progress'] !== NULL) { - $updateData['progress'] = (int)$data['progress']; + $updateData['progress'] = (int) $data['progress']; } if ($data['ratingTwenty'] !== NULL) { - $updateData['ratingTwenty'] = (int)$data['ratingTwenty']; + $updateData['ratingTwenty'] = (int) $data['ratingTwenty']; } return $this->requestBuilder->mutateRequest('UpdateLibraryItem', $updateData); @@ -153,10 +154,11 @@ final class ListItem extends AbstractListItem { $auth = $this->getContainer()->get('auth'); $token = $auth->getAuthToken(); - if ( ! empty($token)) { + if ( ! empty($token)) + { return "bearer {$token}"; } return NULL; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index b0899604..390e2046 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -17,13 +17,6 @@ namespace Aviat\AnimeClient\API\Kitsu; use Amp; -use Aviat\AnimeClient\API\{ - CacheTrait, - Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus, - Enum\MangaReadingStatus\Kitsu as KitsuReadingStatus, - Mapping\AnimeWatchingStatus, - Mapping\MangaReadingStatus -}; use Aviat\AnimeClient\API\Kitsu\Transformer\{ AnimeHistoryTransformer, AnimeListTransformer, @@ -33,10 +26,16 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\{ MangaListTransformer, MangaTransformer }; +use Aviat\AnimeClient\API\{ + CacheTrait, + Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus, + Enum\MangaReadingStatus\Kitsu as KitsuReadingStatus, + Mapping\AnimeWatchingStatus, + Mapping\MangaReadingStatus +}; use Aviat\AnimeClient\Enum\MediaType; use Aviat\AnimeClient\Kitsu as K; -use Aviat\AnimeClient\Types\Anime; -use Aviat\AnimeClient\Types\MangaPage; +use Aviat\AnimeClient\Types\{Anime, MangaPage}; use Aviat\Ion\{ Di\ContainerAware, Json @@ -49,7 +48,8 @@ use const Aviat\AnimeClient\SESSION_SEGMENT; /** * Kitsu API Model */ -final class Model { +final class Model +{ use CacheTrait; use ContainerAware; use RequestBuilderTrait; @@ -57,14 +57,7 @@ final class Model { protected const LIST_PAGE_SIZE = 100; - /** - * @var AnimeTransformer - */ protected AnimeTransformer $animeTransformer; - - /** - * @var MangaTransformer - */ protected MangaTransformer $mangaTransformer; /** @@ -87,13 +80,13 @@ final class Model { 'accept' => NULL, 'Content-type' => 'application/x-www-form-urlencoded', 'client_id' => NULL, - 'client_secret' => NULL + 'client_secret' => NULL, ], 'form_params' => [ 'grant_type' => 'password', 'username' => $username, - 'password' => $password - ] + 'password' => $password, + ], ]); $data = Json::decode(wait($response->getBody()->buffer())); @@ -104,7 +97,8 @@ final class Model { 'error' => $data['error'], 'response' => $response, ]); - die(); + + exit(); } if (array_key_exists('access_token', $data)) @@ -124,12 +118,12 @@ final class Model { 'headers' => [ 'accept' => NULL, 'Content-type' => 'application/x-www-form-urlencoded', - 'Accept-encoding' => '*' + 'Accept-encoding' => '*', ], 'form_params' => [ 'grant_type' => 'refresh_token', - 'refresh_token' => $token - ] + 'refresh_token' => $token, + ], ]); $data = Json::decode(wait($response->getBody()->buffer())); @@ -140,7 +134,8 @@ final class Model { 'error' => $data['error'], 'response' => $response, ]); - die(); + + exit(); } if (array_key_exists('access_token', $data)) @@ -153,19 +148,17 @@ final class Model { /** * Get the userid for a username from Kitsu - * - * @param string|null $username */ - public function getUserIdByUsername(string $username = NULL): string + public function getUserIdByUsername(?string $username = NULL): string { if ($username === NULL) { $username = $this->getUsername(); } - return $this->getCached(K::AUTH_USER_ID_KEY, function(string $username) { + return $this->getCached(K::AUTH_USER_ID_KEY, function (string $username) { $data = $this->requestBuilder->runQuery('GetUserId', [ - 'slug' => $username + 'slug' => $username, ]); return $data['data']['findProfileBySlug']['id'] ?? NULL; @@ -180,7 +173,7 @@ final class Model { public function getCharacter(string $slug): array { return $this->requestBuilder->runQuery('CharacterDetails', [ - 'slug' => $slug + 'slug' => $slug, ]); } @@ -192,7 +185,7 @@ final class Model { public function getPerson(string $slug): array { return $this->getCached("kitsu-person-{$slug}", fn () => $this->requestBuilder->runQuery('PersonDetails', [ - 'slug' => $slug + 'slug' => $slug, ])); } @@ -217,7 +210,7 @@ final class Model { public function getAnime(string $slug): Anime { $baseData = $this->requestBuilder->runQuery('AnimeDetails', [ - 'slug' => $slug + 'slug' => $slug, ]); if (empty($baseData)) @@ -231,7 +224,7 @@ final class Model { public function getRandomAnime(): Anime { $baseData = $this->requestBuilder->runQuery('RandomMedia', [ - 'type' => 'ANIME' + 'type' => 'ANIME', ]); return $this->animeTransformer->transform($baseData); @@ -251,6 +244,7 @@ final class Model { $baseData = $this->requestBuilder->runQuery('AnimeDetailsById', [ 'id' => $animeId, ]); + return $this->animeTransformer->transform($baseData); } @@ -271,7 +265,6 @@ final class Model { $list = (new AnimeHistoryTransformer())->transform($raw); $this->cache->set($key, $list); - } return $list; @@ -303,7 +296,7 @@ final class Model { $transformed = $transformer->transformCollection($data); $keyed = []; - foreach($transformed as $item) + foreach ($transformed as $item) { $keyed[$item['id']] = $item; } @@ -320,7 +313,7 @@ final class Model { * * @param string $status - Optional status to filter by */ - public function getAnimeListCount(string $status = '') : int + public function getAnimeListCount(string $status = ''): int { return $this->getListCount(MediaType::ANIME, $status); } @@ -354,7 +347,7 @@ final class Model { public function getManga(string $slug): MangaPage { $baseData = $this->requestBuilder->runQuery('MangaDetails', [ - 'slug' => $slug + 'slug' => $slug, ]); if (empty($baseData)) @@ -368,7 +361,7 @@ final class Model { public function getRandomManga(): MangaPage { $baseData = $this->requestBuilder->runQuery('RandomMedia', [ - 'type' => 'MANGA' + 'type' => 'MANGA', ]); return $this->mangaTransformer->transform($baseData); @@ -382,6 +375,7 @@ final class Model { $baseData = $this->requestBuilder->runQuery('MangaDetailsById', [ 'id' => $mangaId, ]); + return $this->mangaTransformer->transform($baseData); } @@ -432,7 +426,7 @@ final class Model { $transformed = $transformer->transformCollection($data); $keyed = []; - foreach($transformed as $item) + foreach ($transformed as $item) { $keyed[$item['id']] = $item; } @@ -449,7 +443,7 @@ final class Model { * * @param string $status - Optional status to filter by */ - public function getMangaListCount(string $status = '') : int + public function getMangaListCount(string $status = ''): int { return $this->getListCount(MediaType::MANGA, $status); } @@ -463,6 +457,7 @@ final class Model { { $statuses = KitsuReadingStatus::getConstList(); $output = []; + foreach ($statuses as $status) { $mappedStatus = MangaReadingStatus::KITSU_TO_TITLE[$status]; @@ -506,9 +501,9 @@ final class Model { // Search for MAL mapping if (is_array($item['mappings']['nodes'])) { - foreach($item['mappings']['nodes'] as $mapping) + foreach ($item['mappings']['nodes'] as $mapping) { - if ($mapping['externalSite'] === "MYANIMELIST_" . strtoupper($type)) + if ($mapping['externalSite'] === 'MYANIMELIST_' . strtoupper($type)) { $searchItem['mal_id'] = $mapping['externalId']; break; @@ -517,7 +512,6 @@ final class Model { } $data[] = $searchItem; - } return $data; @@ -528,7 +522,7 @@ final class Model { * * @param string $type "anime" or "manga" */ - public function getKitsuIdFromMALId(string $malId, string $type='anime'): ?string + public function getKitsuIdFromMALId(string $malId, string $type = 'anime'): ?string { $raw = $this->requestBuilder->runQuery('GetIdByMapping', [ 'id' => $malId, @@ -584,10 +578,8 @@ final class Model { } /** - * * Get the data to sync Kitsu anime/manga list with another API * - * @param string $type * @return mixed[] */ public function getSyncList(string $type): array @@ -649,7 +641,7 @@ final class Model { $cursor = ''; $username = $this->getUsername(); - return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): \Generator { + return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): Generator { while (TRUE) { $vars = [ @@ -682,7 +674,8 @@ final class Model { // @TODO Proper Error logging dump($rawData); - die(); + + exit(); } $cursor = $page['endCursor']; @@ -697,11 +690,12 @@ final class Model { }); } - private function getSyncPages(string $type, string $status): Amp\Iterator { + private function getSyncPages(string $type, string $status): Amp\Iterator + { $cursor = ''; $username = $this->getUsername(); - return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): \Generator { + return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): Generator { while (TRUE) { $vars = [ @@ -724,7 +718,8 @@ final class Model { if (empty($data)) { dump($rawData); - die(); + + exit(); } $cursor = $page['endCursor']; @@ -744,7 +739,7 @@ final class Model { $cursor = ''; $username = $this->getUsername(); - return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): \Generator { + return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): Generator { while (TRUE) { $vars = [ @@ -767,7 +762,8 @@ final class Model { if (empty($data)) { dump($rawData); - die(); + + exit(); } $cursor = $page['endCursor']; @@ -818,7 +814,7 @@ final class Model { { $args = [ 'type' => strtoupper($type), - 'slug' => $this->getUsername() + 'slug' => $this->getUsername(), ]; if ($status !== '') { @@ -829,4 +825,4 @@ final class Model { return $res['data']['findProfileBySlug']['library']['all']['totalCount']; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/MutationTrait.php b/src/AnimeClient/API/Kitsu/MutationTrait.php index a3910db9..bf2754fe 100644 --- a/src/AnimeClient/API/Kitsu/MutationTrait.php +++ b/src/AnimeClient/API/Kitsu/MutationTrait.php @@ -22,7 +22,8 @@ use Aviat\AnimeClient\Types\FormItem; /** * Kitsu API calls that mutate data, C/U/D parts of CRUD */ -trait MutationTrait { +trait MutationTrait +{ // ------------------------------------------------------------------------- // ! Generic API calls // ------------------------------------------------------------------------- @@ -65,4 +66,4 @@ trait MutationTrait { { return $this->listItem->delete($id); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/RequestBuilder.php b/src/AnimeClient/API/Kitsu/RequestBuilder.php index 6fb1793d..cc4e15db 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilder.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilder.php @@ -16,26 +16,21 @@ namespace Aviat\AnimeClient\API\Kitsu; -use const Aviat\AnimeClient\SESSION_SEGMENT; -use const Aviat\AnimeClient\USER_AGENT; - -use function Amp\Promise\wait; -use function Aviat\AnimeClient\getResponse; - -use Amp\Http\Client\Request; -use Amp\Http\Client\Response; -use Aviat\AnimeClient\Kitsu as K; +use Amp\Http\Client\{Request, Response}; use Aviat\AnimeClient\API\APIRequestBuilder; use Aviat\AnimeClient\Enum\EventType; -use Aviat\Ion\Di\ContainerAware; -use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Event; -use Aviat\Ion\Json; -use Aviat\Ion\JsonException; +use Aviat\AnimeClient\Kitsu as K; +use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; +use Aviat\Ion\{Event, Json, JsonException}; use LogicException; +use function Amp\Promise\wait; +use function Aviat\AnimeClient\getResponse; +use function in_array; +use const Aviat\AnimeClient\{SESSION_SEGMENT, USER_AGENT}; -final class RequestBuilder extends APIRequestBuilder { +final class RequestBuilder extends APIRequestBuilder +{ use ContainerAware; /** @@ -52,7 +47,7 @@ final class RequestBuilder extends APIRequestBuilder { * HTTP headers to send with every request */ protected array $defaultHeaders = [ - 'User-Agent' => USER_AGENT, + 'User-Agent' => USER_AGENT, 'Accept' => 'application/vnd.api+json', 'Content-Type' => 'application/vnd.api+json', 'CLIENT_ID' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd', @@ -76,13 +71,13 @@ final class RequestBuilder extends APIRequestBuilder { ->getSegment(SESSION_SEGMENT); $cache = $this->getContainer()->get('cache'); - $token = null; + $token = NULL; if ($cache->has(K::AUTH_TOKEN_CACHE_KEY)) { $token = $cache->get(K::AUTH_TOKEN_CACHE_KEY); } - else if ($url !== K::AUTH_URL && $sessionSegment->get('auth_token') !== NULL) + elseif ($url !== K::AUTH_URL && $sessionSegment->get('auth_token') !== NULL) { $token = $sessionSegment->get('auth_token'); if ( ! (empty($token) || $cache->has(K::AUTH_TOKEN_CACHE_KEY))) @@ -130,12 +125,12 @@ final class RequestBuilder extends APIRequestBuilder { $response = getResponse($request); $validResponseCodes = [200, 201]; - if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE)) + if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE)) { $logger = $this->container->getLogger('kitsu-graphql'); if ($logger !== NULL) { - $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); + $logger->warning('Non 200 response for GraphQL call', (array) $response->getBody()); } } @@ -153,12 +148,12 @@ final class RequestBuilder extends APIRequestBuilder { $response = getResponse($request); $validResponseCodes = [200, 201]; - if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE)) + if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE)) { $logger = $this->container->getLogger('kitsu-graphql'); if ($logger !== NULL) { - $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); + $logger->warning('Non 200 response for GraphQL call', (array) $response->getBody()); } } @@ -198,13 +193,14 @@ final class RequestBuilder extends APIRequestBuilder { $query = file_get_contents($file); $body = [ - 'query' => $query + 'query' => $query, ]; if ( ! empty($variables)) { $body['variables'] = []; - foreach($variables as $key => $val) + + foreach ($variables as $key => $val) { $body['variables'][$key] = $val; } @@ -218,7 +214,7 @@ final class RequestBuilder extends APIRequestBuilder { /** * Create a GraphQL mutation request, and return the Request object */ - public function mutateRequest (string $name, array $variables = []): Request + public function mutateRequest(string $name, array $variables = []): Request { $file = realpath("{$this->filePath}/Mutations/{$name}.graphql"); if ($file === FALSE || ! file_exists($file)) @@ -228,11 +224,13 @@ final class RequestBuilder extends APIRequestBuilder { $query = file_get_contents($file); $body = [ - 'query' => $query + 'query' => $query, ]; - if (!empty($variables)) { + if ( ! empty($variables)) + { $body['variables'] = []; + foreach ($variables as $key => $val) { $body['variables'][$key] = $val; @@ -266,7 +264,7 @@ final class RequestBuilder extends APIRequestBuilder { { if ($logger !== NULL) { - $logger->warning('Non 2xx response for api call', (array)$response); + $logger->warning('Non 2xx response for api call', (array) $response); } } @@ -278,7 +276,8 @@ final class RequestBuilder extends APIRequestBuilder { { // dump($e); dump($rawBody); - die(); + + exit(); } } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php b/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php index 03d5d63b..9cee531a 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php @@ -16,7 +16,8 @@ namespace Aviat\AnimeClient\API\Kitsu; -trait RequestBuilderTrait { +trait RequestBuilderTrait +{ /** * The request builder for the Kitsu API */ @@ -25,11 +26,12 @@ trait RequestBuilderTrait { /** * Set the request builder object * - * @return RequestBuilderTrait|ListItem|Model + * @return ListItem|Model|RequestBuilderTrait */ public function setRequestBuilder(RequestBuilder $requestBuilder): self { $this->requestBuilder = $requestBuilder; + return $this; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/AnimeHistoryTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/AnimeHistoryTransformer.php index f70c4e0b..12db67fb 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/AnimeHistoryTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/AnimeHistoryTransformer.php @@ -18,16 +18,12 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; -class AnimeHistoryTransformer extends HistoryTransformer { +class AnimeHistoryTransformer extends HistoryTransformer +{ protected string $type = 'anime'; - protected string $progressAction = 'Watched episode'; - protected string $reconsumeAction = 'Rewatched episode'; - protected string $largeAggregateAction = 'Marathoned episodes'; - protected string $reconsumingStatus = 'Rewatching'; - protected array $statusMap = AnimeWatchingStatus::KITSU_TO_TITLE; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/AnimeListTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/AnimeListTransformer.php index fd313446..296ede7b 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/AnimeListTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/AnimeListTransformer.php @@ -18,8 +18,8 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\Kitsu; use Aviat\AnimeClient\Types\{ - FormItem, - AnimeListItem + AnimeListItem, + FormItem }; use Aviat\Ion\Transformer\AbstractTransformer; use Aviat\Ion\Type\StringType; @@ -27,25 +27,24 @@ use Aviat\Ion\Type\StringType; /** * Transformer for anime list */ -final class AnimeListTransformer extends AbstractTransformer { - +final class AnimeListTransformer extends AbstractTransformer +{ /** * Convert raw api response to a more * logical and workable structure * - * @param array|object $item API library item - * @return AnimeListItem + * @param array|object $item API library item */ public function transform(array|object $item): AnimeListItem { - $item = (array)$item; + $item = (array) $item; $animeId = $item['media']['id']; $anime = $item['media']; $genres = []; $rating = (int) $item['rating'] !== 0 - ? (int)$item['rating'] / 2 + ? (int) $item['rating'] / 2 : '-'; $total_episodes = (int) $anime['episodeCount'] !== 0 @@ -87,7 +86,7 @@ final class AnimeListTransformer extends AbstractTransformer { 'airing' => [ 'status' => Kitsu::getAiringStatus($anime['startDate'], $anime['endDate']), 'started' => $anime['startDate'], - 'ended' => $anime['endDate'] + 'ended' => $anime['endDate'], ], 'anime' => [ 'id' => $animeId, @@ -95,7 +94,7 @@ final class AnimeListTransformer extends AbstractTransformer { 'title' => $title, 'titles' => $titles, 'slug' => $anime['slug'], - 'show_type' => (string)StringType::from($anime['subtype'])->upperCaseFirst(), + 'show_type' => (string) StringType::from($anime['subtype'])->upperCaseFirst(), 'cover_image' => Kitsu::getPosterImage($anime), 'genres' => $genres, 'streaming_links' => $streamingLinks, @@ -129,8 +128,8 @@ final class AnimeListTransformer extends AbstractTransformer { 'reconsuming' => $rewatching, 'reconsumeCount' => $item['rewatched'], 'notes' => $item['notes'], - 'private' => $privacy - ] + 'private' => $privacy, + ], ]); if (is_numeric($item['episodes_watched']) && $item['episodes_watched'] > 0) @@ -147,4 +146,4 @@ final class AnimeListTransformer extends AbstractTransformer { } } -// End of AnimeListTransformer.php \ No newline at end of file +// End of AnimeListTransformer.php diff --git a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php index 862ddb36..d3e823ab 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php @@ -23,22 +23,22 @@ use Aviat\Ion\Transformer\AbstractTransformer; /** * Transformer for anime description page */ -final class AnimeTransformer extends AbstractTransformer { - +final class AnimeTransformer extends AbstractTransformer +{ /** * Convert raw api response to a more * logical and workable structure * - * @param array|object $item API library item + * @param array|object $item API library item */ public function transform(array|object $item): AnimePage { - $item = (array)$item; + $item = (array) $item; $base = $item['data']['findAnimeBySlug'] ?? $item['data']['findAnimeById'] ?? $item['data']['randomMedia']; $characters = []; $links = []; $staff = []; - $genres = array_map(fn ($genre) => $genre['title']['en'], $base['categories']['nodes']); + $genres = array_map(static fn ($genre) => $genre['title']['en'], $base['categories']['nodes']); sort($genres); @@ -72,7 +72,7 @@ final class AnimeTransformer extends AbstractTransformer { } else { - uasort($characters[$type], fn($a, $b) => $a['name'] <=> $b['name']); + uasort($characters[$type], static fn ($a, $b) => $a['name'] <=> $b['name']); } } @@ -89,7 +89,7 @@ final class AnimeTransformer extends AbstractTransformer { // If this person object is so broken as to not have a proper image object, // just skip it. No point in showing a role with nothing in it. - if ($person === null || $person['id'] === null || $person['image'] === null) + if ($person === NULL || $person['id'] === NULL || $person['image'] === NULL) { continue; } @@ -102,11 +102,11 @@ final class AnimeTransformer extends AbstractTransformer { $staff[$role][$person['id']] = [ 'id' => $person['id'], 'name' => $name, - 'image' => $person['image']['original']['url'], + 'image' => $person['image']['original']['url'], 'slug' => $person['slug'], ]; - usort($staff[$role], fn ($a, $b) => $a['name'] <=> $b['name']); + usort($staff[$role], static fn ($a, $b) => $a['name'] <=> $b['name']); } ksort($staff); @@ -142,4 +142,4 @@ final class AnimeTransformer extends AbstractTransformer { 'url' => "https://kitsu.io/anime/{$base['slug']}", ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php index 6735e655..6b3f76e3 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php @@ -25,11 +25,11 @@ use Locale; /** * Data transformation class for character pages */ -final class CharacterTransformer extends AbstractTransformer { - +final class CharacterTransformer extends AbstractTransformer +{ public function transform(array|object $item): Character { - $item = (array)$item; + $item = (array) $item; $data = $item['data']['findCharacterBySlug'] ?? []; $castings = []; $media = [ @@ -62,19 +62,19 @@ final class CharacterTransformer extends AbstractTransformer { /** * @return array */ - protected function organizeMediaAndVoices (array $data): array + protected function organizeMediaAndVoices(array $data): array { if (empty($data)) { return [[], []]; } - $titleSort = fn ($a, $b) => $a['title'] <=> $b['title']; + $titleSort = static fn ($a, $b) => $a['title'] <=> $b['title']; // First, let's deal with related media $rawMedia = array_column($data, 'media'); - $rawAnime = array_filter($rawMedia, fn ($item) => $item['type'] === 'Anime'); - $rawManga = array_filter($rawMedia, fn ($item) => $item['type'] === 'Manga'); + $rawAnime = array_filter($rawMedia, static fn ($item) => $item['type'] === 'Anime'); + $rawManga = array_filter($rawMedia, static fn ($item) => $item['type'] === 'Manga'); $anime = array_map(static function ($item) { $output = $item; @@ -102,7 +102,7 @@ final class CharacterTransformer extends AbstractTransformer { ]; // And now, reorganize voice actor relationships - $rawVoices = array_filter($data, fn($item) => (! empty($item['voices'])) && (array)$item['voices']['nodes'] !== []); + $rawVoices = array_filter($data, static fn ($item) => ( ! empty($item['voices'])) && (array) $item['voices']['nodes'] !== []); if (empty($rawVoices)) { @@ -135,7 +135,7 @@ final class CharacterTransformer extends AbstractTransformer { 'image' => $voice['person']['image']['original']['url'], 'name' => $voice['person']['name'], ], - 'series' => [] + 'series' => [], ]; } @@ -154,4 +154,4 @@ final class CharacterTransformer extends AbstractTransformer { return [$media, $castings]; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php index 7087dffb..1f0fbe89 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php @@ -16,13 +16,14 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; -use Aviat\AnimeClient\Types\HistoryItem; use Aviat\AnimeClient\Kitsu; +use Aviat\AnimeClient\Types\HistoryItem; use DateTimeImmutable; use DateTimeInterface; use DateTimeZone; -abstract class HistoryTransformer { +abstract class HistoryTransformer +{ /** * @var string The media type */ @@ -70,7 +71,7 @@ abstract class HistoryTransformer { } // Hide private library entries - if ($entry['libraryEntry']['private'] === true) + if ($entry['libraryEntry']['private'] === TRUE) { continue; } @@ -85,7 +86,7 @@ abstract class HistoryTransformer { $output[] = $transformed; } } - else if ($kind === 'updated') + elseif ($kind === 'updated') { $output[] = $this->transformUpdated($entry); } @@ -97,11 +98,12 @@ abstract class HistoryTransformer { /** * Combine consecutive 'progressed' events */ - protected function aggregate (array $singles): array + protected function aggregate(array $singles): array { $output = []; $count = count($singles); + for ($i = 0; $i < $count; $i++) { $entries = []; @@ -109,9 +111,10 @@ abstract class HistoryTransformer { $prevTitle = $entry['title']; $nextId = $i; $next = $singles[$nextId]; + while ( - $next['kind'] === 'progressed' && - $next['title'] === $prevTitle + $next['kind'] === 'progressed' + && $next['title'] === $prevTitle ) { $entries[] = $next; $prevTitle = $next['title']; @@ -120,6 +123,7 @@ abstract class HistoryTransformer { { $nextId++; $next = $singles[$nextId]; + continue; } @@ -160,7 +164,7 @@ abstract class HistoryTransformer { 'action' => $action, 'coverImg' => $entries[0]['coverImg'], 'dateRange' => [$firstUpdate, $lastUpdate], - 'isAggregate' => true, + 'isAggregate' => TRUE, 'original' => $entries, 'title' => $title, 'updated' => $entries[0]['updated'], @@ -169,6 +173,7 @@ abstract class HistoryTransformer { // Skip the rest of the aggregate in the main loop $i += count($entries) - 1; + continue; } @@ -178,14 +183,14 @@ abstract class HistoryTransformer { return $output; } - protected function transformProgress (array $entry): ?HistoryItem + protected function transformProgress(array $entry): ?HistoryItem { $data = $entry['media']; $title = $this->linkTitle($data); $item = end($entry['changedData']['progress']); // No showing episode 0 nonsense - if (((int)$item) === 0) + if (((int) $item) === 0) { return NULL; } @@ -251,12 +256,12 @@ abstract class HistoryTransformer { return HistoryItem::from($entry); } - protected function linkTitle (array $data): string + protected function linkTitle(array $data): string { return $data['titles']['canonical']; } - protected function parseDate (string $date): DateTimeImmutable + protected function parseDate(string $date): DateTimeImmutable { $dateTime = DateTimeImmutable::createFromFormat( DateTimeInterface::RFC3339, @@ -271,13 +276,13 @@ abstract class HistoryTransformer { return $dateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); } - protected function getUrl (array $data): string + protected function getUrl(array $data): string { return "/{$this->type}/details/{$data['slug']}"; } - protected function isReconsuming (array $entry): bool + protected function isReconsuming(array $entry): bool { return $entry['libraryEntry']['reconsuming']; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/LibraryEntryTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/LibraryEntryTransformer.php index e15d1ae8..d0b3c16a 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/LibraryEntryTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/LibraryEntryTransformer.php @@ -17,7 +17,7 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\Kitsu; -use Aviat\AnimeClient\Types\{FormItem, AnimeListItem, MangaListItem, MangaListItemDetail}; +use Aviat\AnimeClient\Types\{AnimeListItem, FormItem, MangaListItem, MangaListItemDetail}; use Aviat\Ion\Transformer\AbstractTransformer; use Aviat\Ion\Type\StringType; @@ -28,7 +28,7 @@ final class LibraryEntryTransformer extends AbstractTransformer { public function transform(array|object $item): AnimeListItem|MangaListItem { - $item = (array)$item; + $item = (array) $item; $type = $item['media']['type'] ?? ''; $genres = []; @@ -93,7 +93,7 @@ final class LibraryEntryTransformer extends AbstractTransformer 'airing' => [ 'status' => Kitsu::getAiringStatus($anime['startDate'], $anime['endDate']), 'started' => $anime['startDate'], - 'ended' => $anime['endDate'] + 'ended' => $anime['endDate'], ], 'anime' => [ 'id' => $animeId, @@ -101,7 +101,7 @@ final class LibraryEntryTransformer extends AbstractTransformer 'title' => $title, 'titles' => $titles, 'slug' => $anime['slug'], - 'show_type' => (string)StringType::from($anime['subtype'])->upperCaseFirst(), + 'show_type' => (string) StringType::from($anime['subtype'])->upperCaseFirst(), 'cover_image' => Kitsu::getPosterImage($anime), 'genres' => $genres, 'streaming_links' => $streamingLinks, @@ -158,11 +158,11 @@ final class LibraryEntryTransformer extends AbstractTransformer 'mal_id' => $MALid, 'chapters' => [ 'read' => $readChapters, - 'total' => $totalChapters + 'total' => $totalChapters, ], 'volumes' => [ 'read' => '-', //$item['attributes']['volumes_read'], - 'total' => $totalVolumes + 'total' => $totalVolumes, ], 'manga' => MangaListItemDetail::from([ 'genres' => $genres, @@ -171,14 +171,14 @@ final class LibraryEntryTransformer extends AbstractTransformer 'slug' => $manga['slug'], 'title' => $title, 'titles' => $titles, - 'type' => (string)StringType::from($manga['subtype'])->upperCaseFirst(), + 'type' => (string) StringType::from($manga['subtype'])->upperCaseFirst(), 'url' => 'https://kitsu.io/manga/' . $manga['slug'], ]), 'reading_status' => strtolower($item['status']), 'notes' => $item['notes'], - 'rereading' => (bool)$item['reconsuming'], + 'rereading' => (bool) $item['reconsuming'], 'reread' => $item['reconsumeCount'], 'user_rating' => $rating, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/MangaHistoryTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/MangaHistoryTransformer.php index ed9b10c6..f21fdab7 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/MangaHistoryTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/MangaHistoryTransformer.php @@ -18,16 +18,12 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\API\Mapping\MangaReadingStatus; -class MangaHistoryTransformer extends HistoryTransformer { +class MangaHistoryTransformer extends HistoryTransformer +{ protected string $type = 'manga'; - protected string $progressAction = 'Read chapter'; - protected string $reconsumeAction = 'Reread chapter'; - protected string $largeAggregateAction = 'Blew through chapters'; - protected string $reconsumingStatus = 'Rereading'; - protected array $statusMap = MangaReadingStatus::KITSU_TO_TITLE; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php index 42d2cfcf..e9fec650 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php @@ -27,16 +27,16 @@ use Aviat\Ion\Type\StringType; /** * Data transformation class for zippered Hummingbird manga */ -final class MangaListTransformer extends AbstractTransformer { +final class MangaListTransformer extends AbstractTransformer +{ /** * Remap zipped anime data to a more logical form * - * @param array|object $item manga entry item - * @return MangaListItem + * @param array|object $item manga entry item */ public function transform(array|object $item): MangaListItem { - $item = (array)$item; + $item = (array) $item; $mangaId = $item['media']['id']; $manga = $item['media']; @@ -82,11 +82,11 @@ final class MangaListTransformer extends AbstractTransformer { 'mal_id' => $MALid, 'chapters' => [ 'read' => $readChapters, - 'total' => $totalChapters + 'total' => $totalChapters, ], 'volumes' => [ 'read' => '-', //$item['attributes']['volumes_read'], - 'total' => $totalVolumes + 'total' => $totalVolumes, ], 'manga' => MangaListItemDetail::from([ 'genres' => $genres, @@ -95,12 +95,12 @@ final class MangaListTransformer extends AbstractTransformer { 'slug' => $manga['slug'], 'title' => $title, 'titles' => $titles, - 'type' => (string)StringType::from($manga['subtype'])->toLowerCase()->upperCaseFirst(), + 'type' => (string) StringType::from($manga['subtype'])->toLowerCase()->upperCaseFirst(), 'url' => 'https://kitsu.io/manga/' . $manga['slug'], ]), 'reading_status' => strtolower($item['status']), 'notes' => $item['notes'], - 'rereading' => (bool)$item['reconsuming'], + 'rereading' => (bool) $item['reconsuming'], 'reread' => $item['reconsumeCount'], 'user_rating' => $rating, ]); @@ -109,12 +109,11 @@ final class MangaListTransformer extends AbstractTransformer { /** * Untransform data to update the api * - * @param array $item - * @return FormItem + * @param array $item */ public function untransform($item): FormItem { - $rereading = array_key_exists('rereading', $item) && (bool)$item['rereading']; + $rereading = array_key_exists('rereading', $item) && (bool) $item['rereading']; $map = FormItem::from([ 'id' => $item['id'], @@ -122,14 +121,14 @@ final class MangaListTransformer extends AbstractTransformer { 'data' => FormItemData::from([ 'status' => $item['status'], 'reconsuming' => $rereading, - 'reconsumeCount' => (int)$item['reread_count'], + 'reconsumeCount' => (int) $item['reread_count'], 'notes' => $item['notes'], ]), ]); if (is_numeric($item['chapters_read']) && $item['chapters_read'] > 0) { - $map['data']['progress'] = (int)$item['chapters_read']; + $map['data']['progress'] = (int) $item['chapters_read']; } if (is_numeric($item['new_rating']) && $item['new_rating'] > 0) @@ -141,4 +140,4 @@ final class MangaListTransformer extends AbstractTransformer { } } -// End of MangaListTransformer.php \ No newline at end of file +// End of MangaListTransformer.php diff --git a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php index fba80154..122244db 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php @@ -23,22 +23,22 @@ use Aviat\Ion\Transformer\AbstractTransformer; /** * Transformer for manga description page */ -final class MangaTransformer extends AbstractTransformer { - +final class MangaTransformer extends AbstractTransformer +{ /** * Convert raw api response to a more * logical and workable structure * - * @param array|object $item API library item + * @param array|object $item API library item */ public function transform(array|object $item): MangaPage { - $item = (array)$item; + $item = (array) $item; $base = $item['data']['findMangaBySlug'] ?? $item['data']['findMangaById'] ?? $item['data']['randomMedia']; $characters = []; $links = []; $staff = []; - $genres = array_map(fn ($genre) => $genre['title']['en'], $base['categories']['nodes']); + $genres = array_map(static fn ($genre) => $genre['title']['en'], $base['categories']['nodes']); sort($genres); $title = $base['titles']['canonical']; @@ -71,7 +71,7 @@ final class MangaTransformer extends AbstractTransformer { } else { - uasort($characters[$type], fn($a, $b) => $a['name'] <=> $b['name']); + uasort($characters[$type], static fn ($a, $b) => $a['name'] <=> $b['name']); } } @@ -88,7 +88,7 @@ final class MangaTransformer extends AbstractTransformer { // If this person object is so broken as to not have a proper image object, // just skip it. No point in showing a role with nothing in it. - if ($person === null || $person['id'] === null || $person['image'] === null) + if ($person === NULL || $person['id'] === NULL || $person['image'] === NULL) { continue; } @@ -105,7 +105,7 @@ final class MangaTransformer extends AbstractTransformer { 'image' => $person['image']['original']['url'], ]; - usort($staff[$role], fn ($a, $b) => $a['name'] <=> $b['name']); + usort($staff[$role], static fn ($a, $b) => $a['name'] <=> $b['name']); } ksort($staff); @@ -138,4 +138,4 @@ final class MangaTransformer extends AbstractTransformer { return MangaPage::from($data); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php index 8152a6ef..6c9524ee 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php @@ -23,11 +23,11 @@ use Aviat\Ion\Transformer\AbstractTransformer; /** * Data transformation class for people pages */ -final class PersonTransformer extends AbstractTransformer { - +final class PersonTransformer extends AbstractTransformer +{ public function transform(array|object $item): Person { - $item = (array)$item; + $item = (array) $item; $data = $item['data']['findPersonBySlug'] ?? []; $canonicalName = $data['names']['localized'][$data['names']['canonical']] ?? array_shift($data['names']['localized']); @@ -61,6 +61,7 @@ final class PersonTransformer extends AbstractTransformer { if ((is_countable($data['mediaStaff']['nodes']) ? count($data['mediaStaff']['nodes']) : 0) > 0) { $roles = array_unique(array_column($data['mediaStaff']['nodes'], 'role')); + foreach ($roles as $role) { $staff[$role] = []; @@ -88,7 +89,7 @@ final class PersonTransformer extends AbstractTransformer { 'slug' => $media['slug'], ]; - uasort($staff[$role][$type], fn ($a, $b) => $a['title'] <=> $b['title']); + uasort($staff[$role][$type], static fn ($a, $b) => $a['title'] <=> $b['title']); } $output['staff'] = $staff; @@ -128,7 +129,7 @@ final class PersonTransformer extends AbstractTransformer { 'canonicalName' => $character['names']['canonical'], ], 'media' => [ - $media['id'] => $media + $media['id'] => $media, ], ]; } @@ -143,7 +144,7 @@ final class PersonTransformer extends AbstractTransformer { // Sort the characters by name uasort( $characters[$role], - fn($a, $b) => $a['character']['canonicalName'] <=> $b['character']['canonicalName'] + static fn ($a, $b) => $a['character']['canonicalName'] <=> $b['character']['canonicalName'] ); // Sort the media for the character @@ -151,7 +152,7 @@ final class PersonTransformer extends AbstractTransformer { { uasort( $characters[$role][$charId]['media'], - fn ($a, $b) => $a['titles'][0] <=> $b['titles'][0] + static fn ($a, $b) => $a['titles'][0] <=> $b['titles'][0] ); } } @@ -163,4 +164,4 @@ final class PersonTransformer extends AbstractTransformer { return $output; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/UserTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/UserTransformer.php index 632b4598..c0f7ed51 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/UserTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/UserTransformer.php @@ -17,7 +17,6 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\Kitsu; -use function Aviat\AnimeClient\getLocalImg; use Aviat\AnimeClient\Types\User; use Aviat\Ion\Transformer\AbstractTransformer; @@ -28,10 +27,11 @@ use Aviat\Ion\Transformer\AbstractTransformer; * @param array|object $profileData * @return User */ -final class UserTransformer extends AbstractTransformer { +final class UserTransformer extends AbstractTransformer +{ public function transform(array|object $item): User { - $item = (array)$item; + $item = (array) $item; $base = $item['data']['findProfileBySlug'] ?? []; $favorites = $base['favorites']['nodes'] ?? []; $stats = $base['stats'] ?? []; @@ -108,4 +108,4 @@ final class UserTransformer extends AbstractTransformer { return array_merge($animeStats, $mangaStats, $otherStats); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Mapping/AnimeWatchingStatus.php b/src/AnimeClient/API/Mapping/AnimeWatchingStatus.php index 31b720f3..b90839ce 100644 --- a/src/AnimeClient/API/Mapping/AnimeWatchingStatus.php +++ b/src/AnimeClient/API/Mapping/AnimeWatchingStatus.php @@ -23,54 +23,50 @@ use Aviat\Ion\Enum; * Anime watching status mappings, among Kitsu, MAL, Page titles * and url route segments */ -final class AnimeWatchingStatus extends Enum { +final class AnimeWatchingStatus extends Enum +{ public const ANILIST_TO_KITSU = [ Anilist::WATCHING => Kitsu::WATCHING, Anilist::PLAN_TO_WATCH => Kitsu::PLAN_TO_WATCH, Anilist::COMPLETED => Kitsu::COMPLETED, Anilist::ON_HOLD => Kitsu::ON_HOLD, - Anilist::DROPPED => Kitsu::DROPPED + Anilist::DROPPED => Kitsu::DROPPED, ]; - public const KITSU_TO_ANILIST = [ Kitsu::WATCHING => Anilist::WATCHING, Kitsu::PLAN_TO_WATCH => Anilist::PLAN_TO_WATCH, Kitsu::COMPLETED => Anilist::COMPLETED, Kitsu::ON_HOLD => Anilist::ON_HOLD, - Kitsu::DROPPED => Anilist::DROPPED + Kitsu::DROPPED => Anilist::DROPPED, ]; - public const KITSU_TO_TITLE = [ Kitsu::WATCHING => Title::WATCHING, Kitsu::PLAN_TO_WATCH => Title::PLAN_TO_WATCH, Kitsu::ON_HOLD => Title::ON_HOLD, Kitsu::DROPPED => Title::DROPPED, - Kitsu::COMPLETED => Title::COMPLETED + Kitsu::COMPLETED => Title::COMPLETED, ]; - public const ROUTE_TO_KITSU = [ Route::WATCHING => Kitsu::WATCHING, Route::PLAN_TO_WATCH => Kitsu::PLAN_TO_WATCH, Route::ON_HOLD => Kitsu::ON_HOLD, Route::DROPPED => Kitsu::DROPPED, - Route::COMPLETED => Kitsu::COMPLETED + Route::COMPLETED => Kitsu::COMPLETED, ]; - public const ROUTE_TO_TITLE = [ Route::ALL => Title::ALL, Route::WATCHING => Title::WATCHING, Route::PLAN_TO_WATCH => Title::PLAN_TO_WATCH, Route::ON_HOLD => Title::ON_HOLD, Route::DROPPED => Title::DROPPED, - Route::COMPLETED => Title::COMPLETED + Route::COMPLETED => Title::COMPLETED, ]; - public const TITLE_TO_ROUTE = [ Title::ALL => Route::ALL, Title::WATCHING => Route::WATCHING, Title::PLAN_TO_WATCH => Route::PLAN_TO_WATCH, Title::ON_HOLD => Route::ON_HOLD, Title::DROPPED => Route::DROPPED, - Title::COMPLETED => Route::COMPLETED + Title::COMPLETED => Route::COMPLETED, ]; } diff --git a/src/AnimeClient/API/Mapping/MangaReadingStatus.php b/src/AnimeClient/API/Mapping/MangaReadingStatus.php index fdf5ebaf..c4c9da5b 100644 --- a/src/AnimeClient/API/Mapping/MangaReadingStatus.php +++ b/src/AnimeClient/API/Mapping/MangaReadingStatus.php @@ -16,30 +16,29 @@ namespace Aviat\AnimeClient\API\Mapping; -use Aviat\AnimeClient\API\Enum\MangaReadingStatus\{Anilist, Kitsu, Title, Route}; +use Aviat\AnimeClient\API\Enum\MangaReadingStatus\{Anilist, Kitsu, Route, Title}; use Aviat\Ion\Enum; /** * Manga reading status mappings, among Kitsu, MAL, Page titles * and url route segments */ -final class MangaReadingStatus extends Enum { +final class MangaReadingStatus extends Enum +{ public const ANILIST_TO_KITSU = [ Anilist::READING => Kitsu::READING, Anilist::PLAN_TO_READ => Kitsu::PLAN_TO_READ, Anilist::COMPLETED => Kitsu::COMPLETED, Anilist::ON_HOLD => Kitsu::ON_HOLD, - Anilist::DROPPED => Kitsu::DROPPED + Anilist::DROPPED => Kitsu::DROPPED, ]; - public const KITSU_TO_ANILIST = [ Kitsu::READING => Anilist::READING, Kitsu::PLAN_TO_READ => Anilist::PLAN_TO_READ, Kitsu::COMPLETED => Anilist::COMPLETED, Kitsu::ON_HOLD => Anilist::ON_HOLD, - Kitsu::DROPPED => Anilist::DROPPED + Kitsu::DROPPED => Anilist::DROPPED, ]; - public const KITSU_TO_TITLE = [ Kitsu::READING => Title::READING, Kitsu::PLAN_TO_READ => Title::PLAN_TO_READ, @@ -47,15 +46,13 @@ final class MangaReadingStatus extends Enum { Kitsu::ON_HOLD => Title::ON_HOLD, Kitsu::DROPPED => Title::DROPPED, ]; - - public const ROUTE_TO_KITSU = [ + public const ROUTE_TO_KITSU = [ Route::PLAN_TO_READ => Kitsu::PLAN_TO_READ, Route::READING => Kitsu::READING, Route::COMPLETED => Kitsu::COMPLETED, Route::DROPPED => Kitsu::DROPPED, Route::ON_HOLD => Kitsu::ON_HOLD, ]; - public const ROUTE_TO_TITLE = [ Route::ALL => Title::ALL, Route::PLAN_TO_READ => Title::PLAN_TO_READ, @@ -64,7 +61,6 @@ final class MangaReadingStatus extends Enum { Route::DROPPED => Title::DROPPED, Route::ON_HOLD => Title::ON_HOLD, ]; - public const TITLE_TO_KITSU = [ Title::PLAN_TO_READ => Kitsu::PLAN_TO_READ, Title::READING => Kitsu::READING, @@ -72,4 +68,4 @@ final class MangaReadingStatus extends Enum { Title::DROPPED => Kitsu::DROPPED, Title::ON_HOLD => Kitsu::ON_HOLD, ]; -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/ParallelAPIRequest.php b/src/AnimeClient/API/ParallelAPIRequest.php index 8ab46011..c9140320 100644 --- a/src/AnimeClient/API/ParallelAPIRequest.php +++ b/src/AnimeClient/API/ParallelAPIRequest.php @@ -17,17 +17,18 @@ namespace Aviat\AnimeClient\API; use Amp\Http\Client\Request; +use Generator; +use Throwable; use function Amp\call; + use function Amp\Promise\{all, wait}; use function Aviat\AnimeClient\getApiClient; -use Throwable; - /** * Class to simplify making and validating simultaneous requests */ -final class ParallelAPIRequest { - +final class ParallelAPIRequest +{ /** * Set of requests to make in parallel */ @@ -36,26 +37,29 @@ final class ParallelAPIRequest { /** * Add a request */ - public function addRequest(string|Request $request, string|int|null $key = NULL): self + public function addRequest(string|Request $request, string|int|NULL $key = NULL): self { if ($key !== NULL) { $this->requests[$key] = $request; + return $this; } $this->requests[] = $request; + return $this; } /** * Add multiple requests * - * @param string[]|Request[] $requests + * @param Request[]|string[] $requests */ public function addRequests(array $requests): self { array_walk($requests, [$this, 'addRequest']); + return $this; } @@ -73,7 +77,7 @@ final class ParallelAPIRequest { foreach ($this->requests as $key => $url) { - $promises[$key] = call(static function () use ($client, $url): \Generator { + $promises[$key] = call(static function () use ($client, $url): Generator { $response = yield $client->request($url); return yield $response->getBody()->buffer(); }); @@ -96,9 +100,9 @@ final class ParallelAPIRequest { foreach ($this->requests as $key => $url) { - $promises[$key] = call(fn () => yield $client->request($url)); + $promises[$key] = call(static fn () => yield $client->request($url)); } return wait(all($promises)); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Anilist.php b/src/AnimeClient/Anilist.php index 192dcc68..c1d85565 100644 --- a/src/AnimeClient/Anilist.php +++ b/src/AnimeClient/Anilist.php @@ -16,23 +16,23 @@ namespace Aviat\AnimeClient; -use Aviat\AnimeClient\API\Enum\{ - AnimeWatchingStatus\Kitsu as KAWS, - MangaReadingStatus\Kitsu as KMRS -}; use Aviat\AnimeClient\API\Enum\{ AnimeWatchingStatus\Anilist as AnimeWatchingStatus, MangaReadingStatus\Anilist as MangaReadingStatus }; +use Aviat\AnimeClient\API\Enum\{ + AnimeWatchingStatus\Kitsu as KAWS, + MangaReadingStatus\Kitsu as KMRS +}; /** * Constants and mappings for the Anilist API */ -final class Anilist { +final class Anilist +{ public const AUTH_URL = 'https://anilist.co/api/v2/oauth/authorize'; public const TOKEN_URL = 'https://anilist.co/api/v2/oauth/token'; public const BASE_URL = 'https://graphql.anilist.co'; - public const KITSU_ANILIST_WATCHING_STATUS_MAP = [ KAWS::WATCHING => AnimeWatchingStatus::WATCHING, KAWS::COMPLETED => AnimeWatchingStatus::COMPLETED, @@ -40,7 +40,6 @@ final class Anilist { KAWS::DROPPED => AnimeWatchingStatus::DROPPED, KAWS::PLAN_TO_WATCH => AnimeWatchingStatus::PLAN_TO_WATCH, ]; - public const ANILIST_KITSU_WATCHING_STATUS_MAP = [ AnimeWatchingStatus::WATCHING => KAWS::WATCHING, AnimeWatchingStatus::COMPLETED => KAWS::COMPLETED, @@ -48,7 +47,6 @@ final class Anilist { AnimeWatchingStatus::DROPPED => KAWS::DROPPED, AnimeWatchingStatus::PLAN_TO_WATCH => KAWS::PLAN_TO_WATCH, ]; - public const KITSU_ANILIST_READING_STATUS_MAP = [ KMRS::READING => MangaReadingStatus::READING, KMRS::COMPLETED => MangaReadingStatus::COMPLETED, @@ -56,7 +54,6 @@ final class Anilist { KMRS::DROPPED => MangaReadingStatus::DROPPED, KMRS::PLAN_TO_READ => MangaReadingStatus::PLAN_TO_READ, ]; - public const ANILIST_KITSU_READING_STATUS_MAP = [ MangaReadingStatus::READING => KMRS::READING, MangaReadingStatus::COMPLETED => KMRS::COMPLETED, @@ -64,4 +61,4 @@ final class Anilist { MangaReadingStatus::DROPPED => KMRS::DROPPED, MangaReadingStatus::PLAN_TO_READ => KMRS::PLAN_TO_READ, ]; -} \ No newline at end of file +} diff --git a/src/AnimeClient/AnimeClient.php b/src/AnimeClient/AnimeClient.php index 94aac807..80c11972 100644 --- a/src/AnimeClient/AnimeClient.php +++ b/src/AnimeClient/AnimeClient.php @@ -16,21 +16,17 @@ namespace Aviat\AnimeClient; -use Aviat\Ion\ImageBuilder; +use Amp\Http\Client\{HttpClient, HttpClientBuilder, Request, Response}; + +use Aviat\Ion\{ConfigInterface, ImageBuilder}; use Psr\SimpleCache\CacheInterface; - -use Amp\Http\Client\Request; -use Amp\Http\Client\Response; -use Amp\Http\Client\HttpClient; -use Amp\Http\Client\HttpClientBuilder; - -use Aviat\Ion\ConfigInterface; -use Yosymfony\Toml\{Toml, TomlBuilder}; - use Throwable; +use Yosymfony\Toml\{Toml, TomlBuilder}; + use function Amp\Promise\wait; use function Aviat\Ion\_dir; + // ---------------------------------------------------------------------------- //! TOML Functions // ---------------------------------------------------------------------------- @@ -62,7 +58,7 @@ function loadConfig(string $path): array if ($key === 'config') { - foreach($config as $name => $value) + foreach ($config as $name => $value) { $output[$name] = $value; } @@ -96,10 +92,10 @@ function _iterateToml(TomlBuilder $builder, iterable $data, mixed $parentKey = N continue; } - if (is_scalar($value) || isSequentialArray($value)) { $builder->addValue($key, $value); + continue; } @@ -188,6 +184,7 @@ function checkFolderPermissions(ConfigInterface $config): array if ( ! is_dir($actual)) { $errors['missing'][] = $pretty; + continue; } @@ -207,7 +204,7 @@ function checkFolderPermissions(ConfigInterface $config): array /** * Get an API Client, with better defaults */ -function getApiClient (): HttpClient +function getApiClient(): HttpClient { static $client; @@ -224,7 +221,7 @@ function getApiClient (): HttpClient * * @throws Throwable */ -function getResponse (Request|string $request): Response +function getResponse(Request|string $request): Response { $client = getApiClient(); @@ -239,7 +236,7 @@ function getResponse (Request|string $request): Response /** * Generate the path for the cached image from the original image */ -function getLocalImg (string $kitsuUrl, bool $webp = TRUE): string +function getLocalImg(string $kitsuUrl, bool $webp = TRUE): string { if (empty($kitsuUrl) || ( ! is_string($kitsuUrl))) { @@ -272,7 +269,7 @@ function getLocalImg (string $kitsuUrl, bool $webp = TRUE): string * * @codeCoverageIgnore */ -function createPlaceholderImage (string $path, int $width = 200, int $height = 200, string $text = 'Image Unavailable'): bool +function createPlaceholderImage(string $path, int $width = 200, int $height = 200, string $text = 'Image Unavailable'): bool { $img = ImageBuilder::new($width, $height) ->enableAlphaBlending(TRUE) @@ -295,6 +292,7 @@ function createPlaceholderImage (string $path, int $width = 200, int $height = 2 function colNotEmpty(array $search, string $key): bool { $items = array_filter(array_column($search, $key), static fn ($x) => ( ! empty($x))); + return $items !== []; } @@ -311,11 +309,11 @@ function clearCache(CacheInterface $cache): bool Kitsu::AUTH_TOKEN_REFRESH_CACHE_KEY, ]); - $userData = array_filter((array)$userData, static fn ($value) => $value !== NULL); + $userData = array_filter((array) $userData, static fn ($value) => $value !== NULL); $cleared = $cache->clear(); - $saved = ( empty($userData)) ? TRUE : $cache->setMultiple($userData); + $saved = (empty($userData)) ? TRUE : $cache->setMultiple($userData); return $cleared && $saved; } @@ -331,5 +329,6 @@ function renderTemplate(string $path, array $data): string extract($data, EXTR_OVERWRITE); include $path; $rawOutput = ob_get_clean(); + return (is_string($rawOutput)) ? $rawOutput : ''; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Command/BaseCommand.php b/src/AnimeClient/Command/BaseCommand.php index c49a3f09..a363478e 100644 --- a/src/AnimeClient/Command/BaseCommand.php +++ b/src/AnimeClient/Command/BaseCommand.php @@ -16,38 +16,37 @@ namespace Aviat\AnimeClient\Command; -use Monolog\Formatter\JsonFormatter; - -use function Aviat\Ion\_dir; -use const Aviat\AnimeClient\SRC_DIR; - -use function Aviat\AnimeClient\loadConfig; -use function Aviat\AnimeClient\loadTomlFile; - use Aura\Router\RouterContainer; + use Aura\Session\SessionFactory; -use Aviat\AnimeClient\{Model, UrlGenerator, Util}; use Aviat\AnimeClient\API\{Anilist, CacheTrait, Kitsu}; + +use Aviat\AnimeClient\{Model, UrlGenerator, Util}; use Aviat\Banker\Teller; use Aviat\Ion\Config; -use Aviat\Ion\Di\{Container, ContainerInterface, ContainerAware}; -use ConsoleKit\{Colors, Command, ConsoleException}; +use Aviat\Ion\Di\{Container, ContainerAware, ContainerInterface}; use ConsoleKit\Widgets\Box; +use ConsoleKit\{Colors, Command, ConsoleException}; use Laminas\Diactoros\{Response, ServerRequestFactory}; +use Monolog\Formatter\JsonFormatter; use Monolog\Handler\RotatingFileHandler; use Monolog\Logger; +use function Aviat\AnimeClient\{loadConfig, loadTomlFile}; +use function Aviat\Ion\_dir; +use const Aviat\AnimeClient\SRC_DIR; /** * Base class for console command setup */ -abstract class BaseCommand extends Command { +abstract class BaseCommand extends Command +{ use CacheTrait; use ContainerAware; /** * Echo text in a box */ - public function echoBox(string|array $message, string|int|null $fgColor = NULL, string|int|null $bgColor = NULL): void + public function echoBox(string|array $message, string|int|NULL $fgColor = NULL, string|int|NULL $bgColor = NULL): void { if (is_array($message)) { @@ -56,12 +55,12 @@ abstract class BaseCommand extends Command { if ($fgColor !== NULL) { - $fgColor = (int)$fgColor; + $fgColor = (int) $fgColor; } if ($bgColor !== NULL) { - $bgColor = (int)$bgColor; + $bgColor = (int) $bgColor; } // Colorize the CLI output @@ -114,15 +113,13 @@ abstract class BaseCommand extends Command { /** * Setup the Di container - * - * @return Containerinterface */ public function setupContainer(): ContainerInterface { $APP_DIR = _dir(dirname(SRC_DIR, 2), 'app'); $APPCONF_DIR = _dir($APP_DIR, 'appConf'); $CONF_DIR = _dir($APP_DIR, 'config'); - $baseConfig = require _dir($APPCONF_DIR, 'base_config.php'); + $baseConfig = require _dir($APPCONF_DIR, 'base_config.php'); $config = loadConfig($CONF_DIR); @@ -136,16 +133,16 @@ abstract class BaseCommand extends Command { return $this->_di($configArray, $APP_DIR); } - private function _line(string $message, int|string|null $fgColor = NULL, int|string|null $bgColor = NULL): void + private function _line(string $message, int|string|NULL $fgColor = NULL, int|string|NULL $bgColor = NULL): void { if ($fgColor !== NULL) { - $fgColor = (int)$fgColor; + $fgColor = (int) $fgColor; } if ($bgColor !== NULL) { - $bgColor = (int)$bgColor; + $bgColor = (int) $bgColor; } // Colorize the CLI output @@ -171,7 +168,7 @@ abstract class BaseCommand extends Command { foreach (['kitsu-request', 'anilist-request', 'anilist-request-cli', 'kitsu-request-cli'] as $channel) { $logger = new Logger($channel); - $handler = new RotatingFileHandler( "{$APP_DIR}/logs/{$channel}.log", 2, Logger::WARNING); + $handler = new RotatingFileHandler("{$APP_DIR}/logs/{$channel}.log", 2, Logger::WARNING); $handler->setFormatter(new JsonFormatter()); $logger->pushHandler($handler); @@ -179,33 +176,34 @@ abstract class BaseCommand extends Command { } // Create Config Object - $container->set('config', fn () => new Config($configArray)); + $container->set('config', static fn () => new Config($configArray)); // Create Cache Object - $container->set('cache', static function($container): \Aviat\Banker\Teller { + $container->set('cache', static function ($container): Teller { $logger = $container->getLogger(); $config = $container->get('config')->get('cache'); + return new Teller($config, $logger); }); // Create Aura Router Object - $container->set('aura-router', fn () => new RouterContainer); + $container->set('aura-router', static fn () => new RouterContainer()); // Create Request/Response Objects - $container->set('request', fn () => ServerRequestFactory::fromGlobals( + $container->set('request', static fn () => ServerRequestFactory::fromGlobals( $GLOBALS['_SERVER'], $_GET, $_POST, $_COOKIE, $_FILES )); - $container->set('response', fn () => new Response); + $container->set('response', static fn () => new Response()); // Create session Object - $container->set('session', fn () => (new SessionFactory())->newInstance($_COOKIE)); + $container->set('session', static fn () => (new SessionFactory())->newInstance($_COOKIE)); // Models - $container->set('kitsu-model', static function($container): Kitsu\Model { + $container->set('kitsu-model', static function ($container): Kitsu\Model { $requestBuilder = new Kitsu\RequestBuilder($container); $requestBuilder->setLogger($container->getLogger('kitsu-request')); @@ -219,6 +217,7 @@ abstract class BaseCommand extends Command { $cache = $container->get('cache'); $model->setCache($cache); + return $model; }); $container->set('anilist-model', static function ($container): Anilist\Model { @@ -235,18 +234,19 @@ abstract class BaseCommand extends Command { return $model; }); - $container->set('settings-model', static function($container): Model\Settings { - $model = new Model\Settings($container->get('config')); + $container->set('settings-model', static function ($container): Model\Settings { + $model = new Model\Settings($container->get('config')); $model->setContainer($container); + return $model; }); - $container->set('auth', fn ($container) => new Kitsu\Auth($container)); + $container->set('auth', static fn ($container) => new Kitsu\Auth($container)); - $container->set('url-generator', fn ($container) => new UrlGenerator($container)); + $container->set('url-generator', static fn ($container) => new UrlGenerator($container)); - $container->set('util', fn ($container) => new Util($container)); + $container->set('util', static fn ($container) => new Util($container)); return $container; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Command/CacheClear.php b/src/AnimeClient/Command/CacheClear.php index 844bebc8..3afa1240 100644 --- a/src/AnimeClient/Command/CacheClear.php +++ b/src/AnimeClient/Command/CacheClear.php @@ -16,14 +16,14 @@ namespace Aviat\AnimeClient\Command; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use function Aviat\AnimeClient\clearCache; /** * Clears the API Cache */ -final class CacheClear extends BaseCommand { +final class CacheClear extends BaseCommand +{ /** * Clear the API cache * diff --git a/src/AnimeClient/Command/CachePrime.php b/src/AnimeClient/Command/CachePrime.php index 9967d9e4..ca8a9d56 100644 --- a/src/AnimeClient/Command/CachePrime.php +++ b/src/AnimeClient/Command/CachePrime.php @@ -16,14 +16,14 @@ namespace Aviat\AnimeClient\Command; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use function Aviat\AnimeClient\clearCache; /** * Clears the API Cache */ -final class CachePrime extends BaseCommand { +final class CachePrime extends BaseCommand +{ /** * Clear, then prime the API cache * @@ -39,6 +39,7 @@ final class CachePrime extends BaseCommand { if ( ! $cleared) { $this->echoErrorBox('Failed to clear cache.'); + return; } diff --git a/src/AnimeClient/Command/ClearThumbnails.php b/src/AnimeClient/Command/ClearThumbnails.php index f1ba1670..b776a6f1 100644 --- a/src/AnimeClient/Command/ClearThumbnails.php +++ b/src/AnimeClient/Command/ClearThumbnails.php @@ -19,8 +19,8 @@ namespace Aviat\AnimeClient\Command; /** * Clears out image cache directories */ -class ClearThumbnails extends BaseCommand { - +class ClearThumbnails extends BaseCommand +{ public function execute(array $args, array $options = []): void { $this->clearThumbs(); @@ -50,10 +50,10 @@ class ClearThumbnails extends BaseCommand { 'people/*.webp', ]; - foreach($paths as $path) + foreach ($paths as $path) { $cmd = "find {$imgDir} -path \"*/{$path}\" | xargs rm -f"; exec($cmd); } } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Command/SyncLists.php b/src/AnimeClient/Command/SyncLists.php index c8b3d1d7..1906c3fc 100644 --- a/src/AnimeClient/Command/SyncLists.php +++ b/src/AnimeClient/Command/SyncLists.php @@ -16,30 +16,27 @@ namespace Aviat\AnimeClient\Command; -use Aviat\Ion\JsonException; -use ConsoleKit\Widgets; +use Aviat\AnimeClient\API\Anilist; +use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus}; use Aviat\AnimeClient\API\{ Anilist\MissingIdException, ParallelAPIRequest }; -use Aviat\AnimeClient\API; -use Aviat\AnimeClient\API\Anilist; -use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus}; -use Aviat\AnimeClient\Enum; use Aviat\AnimeClient\Enum\{MediaType, SyncAction}; use Aviat\AnimeClient\Types\FormItem; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; -use Aviat\Ion\Json; +use Aviat\AnimeClient\{API, Enum}; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; +use Aviat\Ion\{Json, JsonException}; +use ConsoleKit\Widgets; use DateTime; use Throwable; -use function in_array; /** * Syncs list data between Anilist and Kitsu */ -final class SyncLists extends BaseCommand { +final class SyncLists extends BaseCommand +{ protected const KITSU_GREATER = 1; protected const ANILIST_GREATER = -1; protected const SAME = 0; @@ -103,6 +100,7 @@ final class SyncLists extends BaseCommand { if ( ! $anilistEnabled) { $this->echoErrorBox('Anlist API is not enabled. Can not sync.'); + exit(); } @@ -259,7 +257,7 @@ final class SyncLists extends BaseCommand { foreach ($list['data']['MediaListCollection']['lists'] as $subList) { - $count += array_reduce($subList, fn ($carry, $item) => $carry + count(array_values($item)), 0); + $count += array_reduce($subList, static fn ($carry, $item) => $carry + count(array_values($item)), 0); } return $count; @@ -285,7 +283,8 @@ final class SyncLists extends BaseCommand { catch (JsonException) { $this->echoErrorBox('Anlist API exception. Can not sync.'); - die(); + + exit(); } } @@ -322,7 +321,7 @@ final class SyncLists extends BaseCommand { $output = []; - foreach($data as $listItem) + foreach ($data as $listItem) { // If there's no mapping, we can't sync, so continue if ( ! is_array($listItem['media']['mappings']['nodes'])) @@ -363,7 +362,7 @@ final class SyncLists extends BaseCommand { 'reconsuming' => $listItem['reconsuming'], 'status' => strtolower($listItem['status']), 'updatedAt' => $listItem['progressedAt'], - ] + ], ]; } @@ -377,7 +376,7 @@ final class SyncLists extends BaseCommand { { $uType = ucfirst($type); $className = "\\Aviat\\AnimeClient\\API\\Anilist\\Transformer\\{$uType}ListTransformer"; - $transformer = new $className; + $transformer = new $className(); $firstTransformed = []; @@ -390,6 +389,7 @@ final class SyncLists extends BaseCommand { // Key the array by mal_id $output = []; + foreach ($transformed as $item) { $output[$item['mal_id']] = $item->toArray(); @@ -413,10 +413,10 @@ final class SyncLists extends BaseCommand { $malIds = array_keys($anilistList); $kitsuMalIds = array_map('intval', array_column($kitsuList, 'malId')); - $missingMalIds = array_filter($malIds, fn ($id) => ! in_array($id, $kitsuMalIds)); + $missingMalIds = array_filter($malIds, static fn ($id) => ! in_array($id, $kitsuMalIds, TRUE)); // Add items on Anilist, but not Kitsu to Kitsu - foreach($missingMalIds as $mid) + foreach ($missingMalIds as $mid) { if ( ! array_key_exists($mid, $anilistList)) { @@ -424,13 +424,13 @@ final class SyncLists extends BaseCommand { } $data = $anilistList[$mid]['data']; - $data['id'] = $this->kitsuModel->getKitsuIdFromMALId((string)$mid, $type); + $data['id'] = $this->kitsuModel->getKitsuIdFromMALId((string) $mid, $type); $data['type'] = $type; $itemsToAddToKitsu[] = $data; } - foreach($kitsuList as $kitsuItem) + foreach ($kitsuList as $kitsuItem) { $malId = $kitsuItem['malId']; @@ -462,7 +462,7 @@ final class SyncLists extends BaseCommand { // Looks like this item only exists on Kitsu $kItem = $kitsuItem['data']; - $newItemStatus = ($kItem['reconsuming'] === true) ? 'REPEATING' : $statusMap::KITSU_TO_ANILIST[$kItem['status']]; + $newItemStatus = ($kItem['reconsuming'] === TRUE) ? 'REPEATING' : $statusMap::KITSU_TO_ANILIST[$kItem['status']]; $itemsToAddToAnilist[] = [ 'mal_id' => $malId, 'data' => [ @@ -480,7 +480,7 @@ final class SyncLists extends BaseCommand { 'addToAnilist' => $itemsToAddToAnilist, 'updateAnilist' => $anilistUpdateItems, 'addToKitsu' => $itemsToAddToKitsu, - 'updateKitsu' => $kitsuUpdateItems + 'updateKitsu' => $kitsuUpdateItems, ]; } @@ -499,10 +499,10 @@ final class SyncLists extends BaseCommand { ]; $diff = []; $dateDiff = ($kitsuItem['data']['updatedAt'] !== NULL) - ? new DateTime($kitsuItem['data']['updatedAt']) <=> new DateTime((string)$anilistItem['data']['updatedAt']) + ? new DateTime($kitsuItem['data']['updatedAt']) <=> new DateTime((string) $anilistItem['data']['updatedAt']) : 0; - foreach($compareKeys as $key) + foreach ($compareKeys as $key) { $diff[$key] = $kitsuItem['data'][$key] <=> $anilistItem['data'][$key]; } @@ -518,10 +518,10 @@ final class SyncLists extends BaseCommand { $update = [ 'id' => $kitsuItem['id'], 'mal_id' => $kitsuItem['malId'], - 'data' => [] + 'data' => [], ]; $return = [ - 'updateType' => [] + 'updateType' => [], ]; $sameNotes = $diff['notes'] === 0; @@ -545,7 +545,7 @@ final class SyncLists extends BaseCommand { $update['data']['progress'] = $kitsuItem['data']['progress']; $return['updateType'][] = Enum\API::ANILIST; } - else if($diff['progress'] === self::ANILIST_GREATER) + elseif ($diff['progress'] === self::ANILIST_GREATER) { $update['data']['progress'] = $anilistItem['data']['progress']; $return['updateType'][] = Enum\API::KITSU; @@ -560,7 +560,7 @@ final class SyncLists extends BaseCommand { $update['data']['status'] = $kitsuItem['data']['status']; $return['updateType'][] = Enum\API::ANILIST; } - else if ($dateDiff === self::ANILIST_GREATER) + elseif ($dateDiff === self::ANILIST_GREATER) { $update['data']['status'] = $anilistItem['data']['status']; $return['updateType'][] = Enum\API::KITSU; @@ -575,18 +575,18 @@ final class SyncLists extends BaseCommand { { $update['data']['status'] = $kitsuItem['data']['status']; - if ((int)$kitsuItem['data']['progress'] !== 0) + if ((int) $kitsuItem['data']['progress'] !== 0) { $update['data']['progress'] = $kitsuItem['data']['progress']; } $return['updateType'][] = Enum\API::ANILIST; } - else if($dateDiff === self::ANILIST_GREATER) + elseif ($dateDiff === self::ANILIST_GREATER) { $update['data']['status'] = $anilistItem['data']['status']; - if ((int)$anilistItem['data']['progress'] !== 0) + if ((int) $anilistItem['data']['progress'] !== 0) { $update['data']['progress'] = $kitsuItem['data']['progress']; } @@ -599,15 +599,14 @@ final class SyncLists extends BaseCommand { if ( ! $sameRating) { if ( - $dateDiff === self::KITSU_GREATER && - $kitsuItem['data']['rating'] !== 0 && - $kitsuItem['data']['ratingTwenty'] !== 0 - ) - { + $dateDiff === self::KITSU_GREATER + && $kitsuItem['data']['rating'] !== 0 + && $kitsuItem['data']['ratingTwenty'] !== 0 + ) { $update['data']['ratingTwenty'] = $kitsuItem['data']['rating']; $return['updateType'][] = Enum\API::ANILIST; } - else if($dateDiff === self::ANILIST_GREATER && $anilistItem['data']['rating'] !== 0) + elseif ($dateDiff === self::ANILIST_GREATER && $anilistItem['data']['rating'] !== 0) { $update['data']['ratingTwenty'] = $anilistItem['data']['rating'] * 2; $return['updateType'][] = Enum\API::KITSU; @@ -637,7 +636,7 @@ final class SyncLists extends BaseCommand { $update['data']['reconsumeCount'] = $kitsuItem['data']['reconsumeCount']; $return['updateType'][] = Enum\API::ANILIST; } - else if ($diff['reconsumeCount'] === self::ANILIST_GREATER) + elseif ($diff['reconsumeCount'] === self::ANILIST_GREATER) { $update['data']['reconsumeCount'] = $anilistItem['data']['reconsumeCount']; $return['updateType'][] = Enum\API::KITSU; @@ -679,7 +678,7 @@ final class SyncLists extends BaseCommand { $return['data']['data'] = array_merge($prevData, $return['data']['data']); } - else if ($return['updateType'][0] === Enum\API::KITSU) + elseif ($return['updateType'][0] === Enum\API::KITSU) { $prevData = [ 'notes' => $anilistItem['data']['notes'], @@ -687,7 +686,7 @@ final class SyncLists extends BaseCommand { 'progress' => $anilistItem['data']['progress'] ?? 0, // Anilist returns a rating between 1-100 // Kitsu expects a rating from 1-20 - 'rating' => (((int)$anilistItem['data']['rating']) > 0) + 'rating' => (((int) $anilistItem['data']['rating']) > 0) ? (int) $anilistItem['data']['rating'] / 5 : 0, 'reconsumeCount' => $anilistItem['data']['reconsumeCount'], @@ -712,7 +711,8 @@ final class SyncLists extends BaseCommand { private function updateKitsuListItems(array $itemsToUpdate, string $action = SyncAction::UPDATE, string $type = MediaType::ANIME): void { $requester = new ParallelAPIRequest(); - foreach($itemsToUpdate as $item) + + foreach ($itemsToUpdate as $item) { if ($action === SyncAction::UPDATE) { @@ -720,12 +720,13 @@ final class SyncLists extends BaseCommand { $this->kitsuModel->updateListItem(FormItem::from($item)) ); } - else if ($action === SyncAction::CREATE) + elseif ($action === SyncAction::CREATE) { $maybeRequest = $this->kitsuModel->createListItem($item); if ($maybeRequest === NULL) { - $this->echoWarning("Skipped creating Kitsu {$type} due to missing id ¯\_(ツ)_/¯"); + $this->echoWarning("Skipped creating Kitsu {$type} due to missing id ¯\\_(ツ)_/¯"); + continue; } @@ -735,7 +736,7 @@ final class SyncLists extends BaseCommand { $responses = $requester->makeRequests(); - foreach($responses as $key => $response) + foreach ($responses as $key => $response) { $responseData = Json::decode($response); @@ -745,6 +746,7 @@ final class SyncLists extends BaseCommand { { $verb = ($action === SyncAction::UPDATE) ? 'updated' : 'created'; $this->echoSuccess("Successfully {$verb} Kitsu {$type} list item with id: {$id}"); + continue; } @@ -756,6 +758,7 @@ final class SyncLists extends BaseCommand { if ($errorTitle === 'cannot exceed length of media') { $this->echoWarning("Skipped Kitsu {$type} {$id} due to episode count mismatch with other API"); + continue; } } @@ -767,7 +770,6 @@ final class SyncLists extends BaseCommand { ]); $verb = ($action === SyncAction::UPDATE) ? SyncAction::UPDATE : SyncAction::CREATE; $this->echoError("Failed to {$verb} Kitsu {$type} list item with id: {$id}, and mal_id: {$mal_id}"); - } } @@ -780,7 +782,7 @@ final class SyncLists extends BaseCommand { { $requester = new ParallelAPIRequest(); - foreach($itemsToUpdate as $item) + foreach ($itemsToUpdate as $item) { if ($action === SyncAction::UPDATE) { @@ -790,24 +792,27 @@ final class SyncLists extends BaseCommand { $requester->addRequest($maybeRequest); } } - else if ($action === SyncAction::CREATE) + else { - try + if ($action === SyncAction::CREATE) { - $requester->addRequest($this->anilistModel->createFullListItem($item, $type)); - } - catch (MissingIdException) - { - // Case where there's a MAL mapping from Kitsu, but no equivalent Anlist item - $id = $item['mal_id']; - $this->echoWarning("Skipping Anilist {$type} with MAL id: {$id} due to missing mapping"); + try + { + $requester->addRequest($this->anilistModel->createFullListItem($item, $type)); + } + catch (MissingIdException) + { + // Case where there's a MAL mapping from Kitsu, but no equivalent Anlist item + $id = $item['mal_id']; + $this->echoWarning("Skipping Anilist {$type} with MAL id: {$id} due to missing mapping"); + } } } } $responses = $requester->makeRequests(); - foreach($responses as $key => $response) + foreach ($responses as $key => $response) { $id = $itemsToUpdate[$key]['mal_id']; diff --git a/src/AnimeClient/Command/UpdateThumbnails.php b/src/AnimeClient/Command/UpdateThumbnails.php index b4c23825..f4699a67 100644 --- a/src/AnimeClient/Command/UpdateThumbnails.php +++ b/src/AnimeClient/Command/UpdateThumbnails.php @@ -23,7 +23,8 @@ use Aviat\AnimeClient\Controller\Images; * Clears out image cache directories, then re-creates the image cache * for manga and anime */ -final class UpdateThumbnails extends ClearThumbnails { +final class UpdateThumbnails extends ClearThumbnails +{ /** * Model for making requests to Kitsu API */ @@ -48,7 +49,7 @@ final class UpdateThumbnails extends ClearThumbnails { $ids = $this->getImageList(); // Resave the images - foreach($ids as $type => $typeIds) + foreach ($ids as $type => $typeIds) { foreach ($typeIds as $id) { @@ -81,4 +82,4 @@ final class UpdateThumbnails extends ClearThumbnails { 'manga' => $mangaIds, ]; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Component/AnimeCover.php b/src/AnimeClient/Component/AnimeCover.php index 8cb269e2..b27debe1 100644 --- a/src/AnimeClient/Component/AnimeCover.php +++ b/src/AnimeClient/Component/AnimeCover.php @@ -18,7 +18,8 @@ namespace Aviat\AnimeClient\Component; use Aviat\AnimeClient\Types\AnimeListItem; -final class AnimeCover { +final class AnimeCover +{ use ComponentTrait; public function __invoke(AnimeListItem $item): string @@ -27,4 +28,4 @@ final class AnimeCover { 'item' => $item, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Component/Character.php b/src/AnimeClient/Component/Character.php index dce44978..ef4b0554 100644 --- a/src/AnimeClient/Component/Character.php +++ b/src/AnimeClient/Component/Character.php @@ -16,7 +16,8 @@ namespace Aviat\AnimeClient\Component; -final class Character { +final class Character +{ use ComponentTrait; public function __invoke(string $name, string $link, string $picture, string $className = 'character'): string @@ -28,4 +29,4 @@ final class Character { 'className' => $className, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Component/ComponentTrait.php b/src/AnimeClient/Component/ComponentTrait.php index 0e99b432..7a15c9ec 100644 --- a/src/AnimeClient/Component/ComponentTrait.php +++ b/src/AnimeClient/Component/ComponentTrait.php @@ -17,13 +17,13 @@ namespace Aviat\AnimeClient\Component; use Aviat\Ion\Di\ContainerAware; -use const TEMPLATE_DIR; use function Aviat\AnimeClient\renderTemplate; /** * Shared logic for component-based functionality, like Tabs */ -trait ComponentTrait { +trait ComponentTrait +{ use ContainerAware; /** @@ -43,4 +43,4 @@ trait ComponentTrait { return renderTemplate(TEMPLATE_DIR . '/' . $path, array_merge($baseData, $data)); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Component/MangaCover.php b/src/AnimeClient/Component/MangaCover.php index 44b2e51c..ffcb8fe1 100644 --- a/src/AnimeClient/Component/MangaCover.php +++ b/src/AnimeClient/Component/MangaCover.php @@ -18,7 +18,8 @@ namespace Aviat\AnimeClient\Component; use Aviat\AnimeClient\Types\MangaListItem; -final class MangaCover { +final class MangaCover +{ use ComponentTrait; public function __invoke(MangaListItem $item, string $name): string @@ -28,4 +29,4 @@ final class MangaCover { 'name' => $name, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Component/Media.php b/src/AnimeClient/Component/Media.php index 4ee36aaa..123e5e5c 100644 --- a/src/AnimeClient/Component/Media.php +++ b/src/AnimeClient/Component/Media.php @@ -16,7 +16,8 @@ namespace Aviat\AnimeClient\Component; -final class Media { +final class Media +{ use ComponentTrait; public function __invoke(array $titles, string $link, string $picture, string $className = 'media'): string @@ -28,4 +29,4 @@ final class Media { 'className' => $className, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Component/Tabs.php b/src/AnimeClient/Component/Tabs.php index c3c06960..2bba66bb 100644 --- a/src/AnimeClient/Component/Tabs.php +++ b/src/AnimeClient/Component/Tabs.php @@ -16,14 +16,15 @@ namespace Aviat\AnimeClient\Component; -final class Tabs { +final class Tabs +{ use ComponentTrait; /** * Creates a tabbed content view * * @param string $name the name attribute for the input[type-option] form elements - * also used to generate id attributes + * also used to generate id attributes * @param array $tabData The data used to create the tab content, indexed by the tab label * @param callable $cb The function to generate the tab content */ @@ -32,9 +33,8 @@ final class Tabs { array $tabData, callable $cb, string $className = 'content media-wrap flex flex-wrap flex-justify-start', - bool $hasSectionWrapper = false - ): string - { + bool $hasSectionWrapper = FALSE + ): string { if (count($tabData) < 2) { return $this->render('single-tab.php', [ @@ -54,4 +54,4 @@ final class Tabs { 'hasSectionWrapper' => $hasSectionWrapper, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Component/VerticalTabs.php b/src/AnimeClient/Component/VerticalTabs.php index a377a019..949b0891 100644 --- a/src/AnimeClient/Component/VerticalTabs.php +++ b/src/AnimeClient/Component/VerticalTabs.php @@ -16,14 +16,15 @@ namespace Aviat\AnimeClient\Component; -final class VerticalTabs { +final class VerticalTabs +{ use ComponentTrait; /** * Creates a vertical tab content view * * @param string $name the name attribute for the input[type-option] form elements - * also used to generate id attributes + * also used to generate id attributes * @param array $tabData The data used to create the tab content, indexed by the tab label * @param callable $cb The function to generate the tab content */ @@ -31,9 +32,8 @@ final class VerticalTabs { string $name, array $tabData, callable $cb, - string $className='content media-wrap flex flex-wrap flex-justify-start' - ): string - { + string $className = 'content media-wrap flex flex-wrap flex-justify-start' + ): string { return $this->render('vertical-tabs.php', [ 'name' => $name, 'data' => $tabData, @@ -41,4 +41,4 @@ final class VerticalTabs { 'className' => $className, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Controller.php b/src/AnimeClient/Controller.php index f95032b4..d291d8e6 100644 --- a/src/AnimeClient/Controller.php +++ b/src/AnimeClient/Controller.php @@ -16,32 +16,32 @@ namespace Aviat\AnimeClient; -use function Aviat\Ion\_dir; - -use Aviat\AnimeClient\Enum\EventType; use Aura\Router\Generator; + use Aura\Session\Segment; use Aviat\AnimeClient\API\Kitsu\Auth; -use Aviat\Ion\ConfigInterface; -use Psr\Http\Message\ServerRequestInterface; -use Psr\SimpleCache\CacheInterface; - +use Aviat\AnimeClient\Enum\EventType; use Aviat\Ion\Di\{ ContainerAware, ContainerInterface, Exception\ContainerException, Exception\NotFoundException }; -use Aviat\Ion\Event; use Aviat\Ion\Exception\DoubleRenderException; use Aviat\Ion\View\{HtmlView, HttpView, JsonView}; + +use Aviat\Ion\{ConfigInterface, Event}; use InvalidArgumentException; +use Psr\Http\Message\ServerRequestInterface; +use Psr\SimpleCache\CacheInterface; +use function Aviat\Ion\_dir; +use function is_array; /** * Controller base, defines output methods */ -class Controller { - +class Controller +{ use ContainerAware; /** @@ -87,7 +87,6 @@ class Controller { /** * Controller constructor. * - * @param ContainerInterface $container * @throws ContainerException * @throws NotFoundException */ @@ -100,7 +99,7 @@ class Controller { $urlGenerator = $container->get('url-generator'); $this->auth = $container->get('auth'); - $this->cache = $container->get('cache'); + $this->cache = $container->get('cache'); $this->config = $container->get('config'); $this->request = $container->get('request'); $this->session = $session->getSegment(SESSION_SEGMENT); @@ -127,11 +126,10 @@ class Controller { * Set the current url in the session as the target of a future redirect * * @codeCoverageIgnore - * @param string|NULL $url * @throws ContainerException * @throws NotFoundException */ - public function setSessionRedirect(string $url = NULL): void + public function setSessionRedirect(?string $url = NULL): void { $serverParams = $this->request->getServerParams(); @@ -198,7 +196,6 @@ class Controller { * Get the string output of a partial template * * @codeCoverageIgnore - * @param HtmlView $view */ protected function loadPartial(HtmlView $view, string $template, array $data = []): string { @@ -212,7 +209,6 @@ class Controller { $route = $router->getRoute(); $data['route_path'] = $route !== FALSE ? $route->path : ''; - $templatePath = _dir($this->config->get('view_path'), "{$template}.php"); if ( ! is_file($templatePath)) @@ -227,8 +223,6 @@ class Controller { * Render a template with header and footer * * @codeCoverageIgnore - * @param HtmlView $view - * @return HtmlView */ protected function renderFullPage(HtmlView $view, string $template, array $data): HtmlView { @@ -241,7 +235,7 @@ class Controller { $view->addHeader('Content-Security-Policy', implode('; ', $csp)); $view->appendOutput($this->loadPartial($view, 'header', $data)); - if (array_key_exists('message', $data) && \is_array($data['message'])) + if (array_key_exists('message', $data) && is_array($data['message'])) { $view->appendOutput($this->loadPartial($view, 'message', $data['message'])); } @@ -261,12 +255,12 @@ class Controller { public function notFound( string $title = 'Sorry, page not found', string $message = 'Page Not Found' - ): void - { + ): void { $this->outputHTML('404', [ 'title' => $title, 'message' => $message, ], NULL, 404); + exit(); } @@ -281,7 +275,7 @@ class Controller { $this->outputHTML('error', [ 'title' => $title, 'message' => $message, - 'long_message' => $longMessage + 'long_message' => $longMessage, ], NULL, $httpCode); } @@ -314,7 +308,7 @@ class Controller { $messages[] = [ 'message_type' => $type, - 'message' => $message + 'message' => $message, ]; $this->session->setFlash('message', $messages); @@ -325,7 +319,7 @@ class Controller { * * @param string ...$parts Title segments */ - public function formatTitle(string ...$parts) : string + public function formatTitle(string ...$parts): string { return implode(' · ', $parts); } @@ -334,14 +328,13 @@ class Controller { * Add a message box to the page * * @codeCoverageIgnore - * @param HtmlView $view * @throws InvalidArgumentException */ protected function showMessage(HtmlView $view, string $type, string $message): string { return $this->loadPartial($view, 'message', [ 'message_type' => $type, - 'message' => $message + 'message' => $message, ]); } @@ -349,10 +342,9 @@ class Controller { * Output a template to HTML, using the provided data * * @codeCoverageIgnore - * @param HtmlView|NULL $view *@throws InvalidArgumentException */ - protected function outputHTML(string $template, array $data = [], HtmlView $view = NULL, int $code = 200): void + protected function outputHTML(string $template, array $data = [], ?HtmlView $view = NULL, int $code = 200): void { if (NULL === $view) { @@ -389,8 +381,10 @@ class Controller { { (new HttpView())->redirect($url, $code)->send(); } - catch (\Throwable) {} + catch (\Throwable) + { + } } } -// End of BaseController.php \ No newline at end of file +// End of BaseController.php diff --git a/src/AnimeClient/Controller/Anime.php b/src/AnimeClient/Controller/Anime.php index 924fde68..049db781 100644 --- a/src/AnimeClient/Controller/Anime.php +++ b/src/AnimeClient/Controller/Anime.php @@ -17,15 +17,14 @@ namespace Aviat\AnimeClient\Controller; use Aura\Router\Exception\RouteNotFound; -use Aviat\AnimeClient\Controller as BaseController; -use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer; use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus; +use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer; use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; +use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Model\Anime as AnimeModel; use Aviat\AnimeClient\Types\FormItem; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Json; use InvalidArgumentException; @@ -35,8 +34,8 @@ use TypeError; /** * Controller for Anime-related pages */ -final class Anime extends BaseController { - +final class Anime extends BaseController +{ /** * The anime list model */ @@ -92,7 +91,7 @@ final class Anime extends BaseController { $viewMap = [ '' => 'cover', - 'list' => 'list' + 'list' => 'list', ]; $data = ($status !== 'all') @@ -101,7 +100,7 @@ final class Anime extends BaseController { $this->outputHTML('anime/' . $viewMap[$view], [ 'title' => $title, - 'sections' => $data + 'sections' => $data, ]); } @@ -109,9 +108,9 @@ final class Anime extends BaseController { * Form to add an anime * * @throws ContainerException + * @throws InvalidArgumentException * @throws NotFoundException * @throws RouteNotFound - * @throws InvalidArgumentException * @throws Throwable */ public function addForm(): void @@ -125,7 +124,7 @@ final class Anime extends BaseController { 'Add' ), 'action_url' => $this->url->generate('anime.add.post'), - 'status_list' => AnimeWatchingStatus::KITSU_TO_TITLE + 'status_list' => AnimeWatchingStatus::KITSU_TO_TITLE, ]); } @@ -138,7 +137,7 @@ final class Anime extends BaseController { { $this->checkAuth(); - $data = (array)$this->request->getParsedBody(); + $data = (array) $this->request->getParsedBody(); if (empty($data['mal_id'])) { @@ -183,7 +182,7 @@ final class Anime extends BaseController { 'item' => $item, 'statuses' => AnimeWatchingStatus::KITSU_TO_TITLE, 'action' => $this->url->generate('update.post', [ - 'controller' => 'anime' + 'controller' => 'anime', ]), ]); } @@ -207,7 +206,7 @@ final class Anime extends BaseController { { $this->checkAuth(); - $data = (array)$this->request->getParsedBody(); + $data = (array) $this->request->getParsedBody(); // Do some minor data manipulation for // large form-based updates @@ -239,16 +238,17 @@ final class Anime extends BaseController { if (str_contains($this->request->getHeader('content-type')[0], 'application/json')) { - $data = Json::decode((string)$this->request->getBody()); + $data = Json::decode((string) $this->request->getBody()); } else { - $data = (array)$this->request->getParsedBody(); + $data = (array) $this->request->getParsedBody(); } if (empty($data)) { $this->errorPage(400, 'Bad Request', ''); + exit(); } @@ -267,7 +267,7 @@ final class Anime extends BaseController { { $this->checkAuth(); - $body = (array)$this->request->getParsedBody(); + $body = (array) $this->request->getParsedBody(); $response = $this->model->deleteLibraryItem($body['id'], $body['mal_id']); if ($response === TRUE) @@ -365,4 +365,4 @@ final class Anime extends BaseController { } } -// End of AnimeController.php \ No newline at end of file +// End of AnimeController.php diff --git a/src/AnimeClient/Controller/AnimeCollection.php b/src/AnimeClient/Controller/AnimeCollection.php index a5304054..df5f2e25 100644 --- a/src/AnimeClient/Controller/AnimeCollection.php +++ b/src/AnimeClient/Controller/AnimeCollection.php @@ -23,8 +23,7 @@ use Aviat\AnimeClient\Model\{ AnimeCollection as AnimeCollectionModel }; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Exception\DoubleRenderException; use InvalidArgumentException; @@ -32,17 +31,15 @@ use InvalidArgumentException; /** * Controller for Anime collection pages */ -final class AnimeCollection extends BaseController { - +final class AnimeCollection extends BaseController +{ /** * The anime collection model - * @var AnimeCollectionModel $animeCollectionModel */ private AnimeCollectionModel $animeCollectionModel; /** * The anime API model - * @var AnimeModel $animeModel */ private AnimeModel $animeModel; @@ -87,14 +84,14 @@ final class AnimeCollection extends BaseController { * Show the anime collection page * * @throws ContainerException - * @throws NotFoundException * @throws InvalidArgumentException + * @throws NotFoundException */ public function view(?string $view = ''): void { $viewMap = [ '' => 'cover', - 'list' => 'list' + 'list' => 'list', ]; $sections = array_merge( @@ -111,11 +108,11 @@ final class AnimeCollection extends BaseController { /** * Show the anime collection add/edit form * - * @param integer|null $id + * @param int|null $id * @throws ContainerException + * @throws InvalidArgumentException * @throws NotFoundException * @throws RouteNotFound - * @throws InvalidArgumentException */ public function form($id = NULL): void { @@ -134,7 +131,7 @@ final class AnimeCollection extends BaseController { $action ), 'media_items' => $this->animeCollectionModel->getMediaTypeList(), - 'item' => ($action === 'Edit' && $id !== NULL) ? $this->animeCollectionModel->get($id) : [] + 'item' => ($action === 'Edit' && $id !== NULL) ? $this->animeCollectionModel->get($id) : [], ]); } @@ -142,27 +139,27 @@ final class AnimeCollection extends BaseController { * Update a collection item * * @throws ContainerException - * @throws NotFoundException * @throws InvalidArgumentException + * @throws NotFoundException */ public function edit(): void { $this->checkAuth(); - $this->update((array)$this->request->getParsedBody()); + $this->update((array) $this->request->getParsedBody()); } /** * Add a collection item * * @throws ContainerException - * @throws NotFoundException * @throws InvalidArgumentException + * @throws NotFoundException */ public function add(): void { $this->checkAuth(); - $data = (array)$this->request->getParsedBody(); + $data = (array) $this->request->getParsedBody(); if (array_key_exists('id', $data)) { // Check for existing entry @@ -184,6 +181,7 @@ final class AnimeCollection extends BaseController { } $this->update($data); + return; } @@ -194,6 +192,7 @@ final class AnimeCollection extends BaseController { { $this->setFlashMessage('Successfully added collection item', 'success'); $this->sessionRedirect(); + return; } } @@ -209,7 +208,7 @@ final class AnimeCollection extends BaseController { { $this->checkAuth(); - $data = (array)$this->request->getParsedBody(); + $data = (array) $this->request->getParsedBody(); if ( ! array_key_exists('hummingbird_id', $data)) { $this->setFlashMessage("Can't delete item that doesn't exist", 'error'); @@ -249,4 +248,4 @@ final class AnimeCollection extends BaseController { } } -// End of AnimeCollection.php \ No newline at end of file +// End of AnimeCollection.php diff --git a/src/AnimeClient/Controller/Character.php b/src/AnimeClient/Controller/Character.php index feab22cc..e896174f 100644 --- a/src/AnimeClient/Controller/Character.php +++ b/src/AnimeClient/Controller/Character.php @@ -17,18 +17,17 @@ namespace Aviat\AnimeClient\Controller; use Aviat\AnimeClient\API\Kitsu\Model; -use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\API\Kitsu\Transformer\CharacterTransformer; +use Aviat\AnimeClient\Controller as BaseController; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; /** * Controller for character description pages */ -final class Character extends BaseController { - +final class Character extends BaseController +{ private Model $model; /** @@ -73,4 +72,4 @@ final class Character extends BaseController { 'data' => $data, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Controller/History.php b/src/AnimeClient/Controller/History.php index a18f0165..cd153a95 100644 --- a/src/AnimeClient/Controller/History.php +++ b/src/AnimeClient/Controller/History.php @@ -16,26 +16,24 @@ namespace Aviat\AnimeClient\Controller; -use Aviat\AnimeClient\Controller as BaseController; -use Aviat\AnimeClient\Model\Anime as AnimeModel; -use Aviat\AnimeClient\Model\Manga as MangaModel; +use Aviat\AnimeClient\{Controller as BaseController, Model}; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; /** * Controller for Anime-related pages */ -final class History extends BaseController { +final class History extends BaseController +{ /** * The anime list model */ - protected AnimeModel $animeModel; + protected Model\Anime $animeModel; /** * The manga list model */ - protected MangaModel $mangaModel; + protected Model\Manga $mangaModel; /** * Constructor @@ -55,7 +53,8 @@ final class History extends BaseController { { if (method_exists($this, $type)) { - $this->$type(); + $this->{$type}(); + return; } diff --git a/src/AnimeClient/Controller/Images.php b/src/AnimeClient/Controller/Images.php index 7af2df68..4fe2f923 100644 --- a/src/AnimeClient/Controller/Images.php +++ b/src/AnimeClient/Controller/Images.php @@ -16,18 +16,19 @@ namespace Aviat\AnimeClient\Controller; -use function Amp\Promise\wait; -use function Aviat\AnimeClient\getResponse; -use function Aviat\AnimeClient\createPlaceholderImage; - use Aviat\AnimeClient\Controller as BaseController; - use Throwable; +use function Amp\Promise\wait; +use function Aviat\AnimeClient\{createPlaceholderImage, getResponse}; +use function imagepalletetotruecolor; + +use function in_array; /** * Controller for handling routes that don't fit elsewhere */ -final class Images extends BaseController { +final class Images extends BaseController +{ /** * Get image covers from kitsu * @@ -38,7 +39,7 @@ final class Images extends BaseController { */ public function cache(string $type, string $file, bool $display = TRUE): void { - $currentUrl = (string)$this->request->getUri(); + $currentUrl = (string) $this->request->getUri(); $kitsuUrl = 'https://media.kitsu.io/'; $fileName = str_replace('-original', '', $file); @@ -48,8 +49,8 @@ final class Images extends BaseController { // Kitsu doesn't serve webp, but for most use cases, // jpg is a safe assumption - $tryJpg = ['anime','characters','manga','people']; - if ($ext === 'webp' && \in_array($type, $tryJpg, TRUE)) + $tryJpg = ['anime', 'characters', 'manga', 'people']; + if ($ext === 'webp' && in_array($type, $tryJpg, TRUE)) { $ext = 'jpg'; $currentUrl = str_replace('webp', 'jpg', $currentUrl); @@ -63,8 +64,8 @@ final class Images extends BaseController { ], 'avatars' => [ 'kitsuUrl' => "users/avatars/{$id}/original.{$ext}", - 'width' => null, - 'height' => null, + 'width' => NULL, + 'height' => NULL, ], 'characters' => [ 'kitsuUrl' => "characters/images/{$id}/original.{$ext}", @@ -78,8 +79,8 @@ final class Images extends BaseController { ], 'people' => [ 'kitsuUrl' => "people/images/{$id}/original.{$ext}", - 'width' => null, - 'height' => null, + 'width' => NULL, + 'height' => NULL, ], ]; @@ -88,6 +89,7 @@ final class Images extends BaseController { if (NULL === $imageType) { $this->getPlaceholder($baseSavePath, 200, 200); + return; } @@ -111,6 +113,7 @@ final class Images extends BaseController { { $newUrl = str_replace($ext, $nextType[$ext], $currentUrl); $this->redirect($newUrl, 303); + return; } @@ -144,7 +147,7 @@ final class Images extends BaseController { if ($ext === 'gif') { file_put_contents("{$filePrefix}.gif", $data); - \imagepalletetotruecolor($gdImg); + imagepalletetotruecolor($gdImg); } // save the webp versions @@ -178,7 +181,7 @@ final class Images extends BaseController { /** * Get a placeholder for a missing image */ - private function getPlaceholder (string $path, ?int $width = 200, ?int $height = NULL): void + private function getPlaceholder(string $path, ?int $width = 200, ?int $height = NULL): void { $height ??= $width; @@ -192,4 +195,4 @@ final class Images extends BaseController { header('Content-Type: image/png'); echo file_get_contents($filename); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Controller/Manga.php b/src/AnimeClient/Controller/Manga.php index 794c2fe7..ac185f02 100644 --- a/src/AnimeClient/Controller/Manga.php +++ b/src/AnimeClient/Controller/Manga.php @@ -17,9 +17,9 @@ namespace Aviat\AnimeClient\Controller; use Aura\Router\Exception\RouteNotFound; -use Aviat\AnimeClient\Controller; use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer; use Aviat\AnimeClient\API\Mapping\MangaReadingStatus; +use Aviat\AnimeClient\Controller; use Aviat\AnimeClient\Model\Manga as MangaModel; use Aviat\AnimeClient\Types\FormItem; use Aviat\Ion\Di\ContainerInterface; @@ -32,8 +32,8 @@ use Throwable; /** * Controller for manga list */ -final class Manga extends Controller { - +final class Manga extends Controller +{ /** * The manga model */ @@ -86,11 +86,11 @@ final class Manga extends Controller { $view_map = [ '' => 'cover', - 'list' => 'list' + 'list' => 'list', ]; $data = ($status !== 'all') - ? [ $statusTitle => $this->model->getList($statusTitle) ] + ? [$statusTitle => $this->model->getList($statusTitle)] : $this->model->getList('All'); $this->outputHTML('manga/' . $view_map[$view], [ @@ -103,9 +103,9 @@ final class Manga extends Controller { * Form to add an manga * * @throws ContainerException + * @throws InvalidArgumentException * @throws NotFoundException * @throws RouteNotFound - * @throws InvalidArgumentException */ public function addForm(): void { @@ -120,7 +120,7 @@ final class Manga extends Controller { 'Add' ), 'action_url' => $this->url->generate('manga.add.post'), - 'status_list' => $statuses + 'status_list' => $statuses, ]); } @@ -133,7 +133,7 @@ final class Manga extends Controller { { $this->checkAuth(); - $data = (array)$this->request->getParsedBody(); + $data = (array) $this->request->getParsedBody(); if ( ! array_key_exists('id', $data)) { $this->redirect('manga/add', 303); @@ -163,9 +163,9 @@ final class Manga extends Controller { * Show the manga edit form * * @throws ContainerException + * @throws InvalidArgumentException * @throws NotFoundException * @throws RouteNotFound - * @throws InvalidArgumentException */ public function edit(string $id, string $status = 'All'): void { @@ -183,7 +183,7 @@ final class Manga extends Controller { 'status_list' => MangaReadingStatus::KITSU_TO_TITLE, 'item' => $item, 'action' => $this->url->generate('update.post', [ - 'controller' => 'manga' + 'controller' => 'manga', ]), ]); } @@ -207,7 +207,7 @@ final class Manga extends Controller { { $this->checkAuth(); - $data = (array)$this->request->getParsedBody(); + $data = (array) $this->request->getParsedBody(); // Do some minor data manipulation for // large form-based updates @@ -223,7 +223,6 @@ final class Manga extends Controller { else { $this->setFlashMessage('Failed to update manga.', 'error'); - } $this->sessionRedirect(); @@ -239,7 +238,7 @@ final class Manga extends Controller { if (str_contains($this->request->getHeader('content-type')[0], 'application/json')) { - $data = Json::decode((string)$this->request->getBody()); + $data = Json::decode((string) $this->request->getBody()); } else { @@ -263,7 +262,7 @@ final class Manga extends Controller { { $this->checkAuth(); - $body = (array)$this->request->getParsedBody(); + $body = (array) $this->request->getParsedBody(); $response = $this->model->deleteLibraryItem($body['id'], $body['mal_id']); if ($response) @@ -296,6 +295,7 @@ final class Manga extends Controller { 'Manga not found', 'Manga Not Found' ); + return; } @@ -326,6 +326,7 @@ final class Manga extends Controller { 'Manga not found', 'Manga Not Found' ); + return; } diff --git a/src/AnimeClient/Controller/Misc.php b/src/AnimeClient/Controller/Misc.php index 2be2e64b..e9a08855 100644 --- a/src/AnimeClient/Controller/Misc.php +++ b/src/AnimeClient/Controller/Misc.php @@ -24,7 +24,8 @@ use Aviat\Ion\View\HtmlView; /** * Controller for handling routes that don't fit elsewhere */ -final class Misc extends BaseController { +final class Misc extends BaseController +{ /** * Purges the API cache */ @@ -35,7 +36,7 @@ final class Misc extends BaseController { Event::emit(EventType::CLEAR_CACHE); $this->outputHTML('blank', [ - 'title' => 'Cache cleared' + 'title' => 'Cache cleared', ]); } @@ -58,7 +59,7 @@ final class Misc extends BaseController { $this->outputHTML('login', [ 'title' => 'Api login', - 'message' => $message + 'message' => $message, ], $view); } @@ -67,11 +68,12 @@ final class Misc extends BaseController { */ public function loginAction(): void { - $post = (array)$this->request->getParsedBody(); + $post = (array) $this->request->getParsedBody(); if ($this->auth->authenticate($post['password'])) { $this->sessionRedirect(); + return; } @@ -100,4 +102,4 @@ final class Misc extends BaseController { { $this->outputJSON(['hasAuth' => $this->auth->isAuthenticated()], 200); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Controller/People.php b/src/AnimeClient/Controller/People.php index 3d9d8d73..aa098ed3 100644 --- a/src/AnimeClient/Controller/People.php +++ b/src/AnimeClient/Controller/People.php @@ -17,18 +17,17 @@ namespace Aviat\AnimeClient\Controller; use Aviat\AnimeClient\API\Kitsu\Model; -use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\API\Kitsu\Transformer\PersonTransformer; +use Aviat\AnimeClient\Controller as BaseController; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; /** * Controller for People pages */ -final class People extends BaseController { - +final class People extends BaseController +{ private Model $model; /** @@ -72,4 +71,4 @@ final class People extends BaseController { 'data' => $data, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Controller/Settings.php b/src/AnimeClient/Controller/Settings.php index 6a1840b2..0f4a113e 100644 --- a/src/AnimeClient/Controller/Settings.php +++ b/src/AnimeClient/Controller/Settings.php @@ -21,16 +21,14 @@ use Aviat\AnimeClient\API\Anilist\Model as AnilistModel; use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Model\Settings as SettingsModel; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; /** * Controller for user settings */ -final class Settings extends BaseController { - +final class Settings extends BaseController +{ private AnilistModel $anilistModel; - private SettingsModel $settingsModel; /** @@ -77,7 +75,7 @@ final class Settings extends BaseController { */ public function update(): void { - $post = (array)$this->request->getParsedBody(); + $post = (array) $this->request->getParsedBody(); unset($post['settings-tabs']); $saved = $this->settingsModel->saveSettingsFile($post); @@ -123,6 +121,7 @@ final class Settings extends BaseController { if (array_key_exists('error', $authData)) { $this->errorPage(400, 'Error Linking Account', $authData['hint']); + return; } @@ -154,4 +153,4 @@ final class Settings extends BaseController { $this->redirect($redirectUrl, 303); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Controller/User.php b/src/AnimeClient/Controller/User.php index 8ed4ef17..402bd9f2 100644 --- a/src/AnimeClient/Controller/User.php +++ b/src/AnimeClient/Controller/User.php @@ -21,14 +21,13 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\UserTransformer; use Aviat\AnimeClient\Controller as BaseController; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; /** * Controller for handling routes that don't fit elsewhere */ -final class User extends BaseController { - +final class User extends BaseController +{ private Model $kitsuModel; /** @@ -75,4 +74,4 @@ final class User extends BaseController { 'data' => $data, ]); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Dispatcher.php b/src/AnimeClient/Dispatcher.php index a5edb1c2..3f513bd0 100644 --- a/src/AnimeClient/Dispatcher.php +++ b/src/AnimeClient/Dispatcher.php @@ -16,9 +16,6 @@ namespace Aviat\AnimeClient; -use Aviat\AnimeClient\Enum\EventType; -use Aviat\Ion\Event; -use Aviat\Ion\Json; use Aura\Router\{ Map, Matcher, @@ -26,9 +23,10 @@ use Aura\Router\{ Rule, }; use Aviat\AnimeClient\API\FailedResponseException; +use Aviat\AnimeClient\Enum\EventType; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Friend; use Aviat\Ion\Type\StringType; +use Aviat\Ion\{Event, Friend, Json}; use LogicException; use ReflectionException; @@ -37,17 +35,15 @@ use function Aviat\Ion\_dir; /** * Basic routing/ dispatch */ -final class Dispatcher extends RoutingBase { - +final class Dispatcher extends RoutingBase +{ /** * The route-matching object - * @var Map $router */ protected Map $router; /** * The route matcher - * @var Matcher $matcher */ protected Matcher $matcher; @@ -77,10 +73,8 @@ final class Dispatcher extends RoutingBase { /** * Get the current route object, if one matches - * - * @return Route|false */ - public function getRoute(): Route | false + public function getRoute(): Route|false { $logger = $this->container->getLogger(); @@ -91,7 +85,7 @@ final class Dispatcher extends RoutingBase { { $logger->info('Dispatcher - Routing data from get_route method'); $logger->info(print_r([ - 'route_path' => $routePath + 'route_path' => $routePath, ], TRUE)); } @@ -111,10 +105,9 @@ final class Dispatcher extends RoutingBase { /** * Handle the current route * - * @param object|null $route * @throws ReflectionException */ - public function __invoke(object $route = NULL): void + public function __invoke(?object $route = NULL): void { $logger = $this->container->getLogger(); @@ -138,6 +131,7 @@ final class Dispatcher extends RoutingBase { $actionMethod = $errorRoute['action_method']; $params = $errorRoute['params']; $this->call($controllerName, $actionMethod, $params); + return; } @@ -180,6 +174,7 @@ final class Dispatcher extends RoutingBase { if ( ! empty($route->__get('tokens'))) { $tokens = array_keys($route->__get('tokens')); + foreach ($tokens as $param) { if (array_key_exists($param, $route->attributes)) @@ -198,7 +193,7 @@ final class Dispatcher extends RoutingBase { return [ 'controller_name' => $controllerName, 'action_method' => $actionMethod, - 'params' => $params + 'params' => $params, ]; } @@ -254,7 +249,7 @@ final class Dispatcher extends RoutingBase { foreach ($classFiles as $file) { $rawClassName = basename(str_replace('.php', '', $file)); - $path = (string)StringType::from($rawClassName)->dasherize(); + $path = (string) StringType::from($rawClassName)->dasherize(); $className = trim($defaultNamespace . '\\' . $rawClassName, '\\'); $controllers[$path] = $className; @@ -267,7 +262,7 @@ final class Dispatcher extends RoutingBase { * Create the controller object and call the appropriate * method * - * @param string $controllerName - The full namespace of the controller class + * @param string $controllerName - The full namespace of the controller class */ protected function call(string $controllerName, string $method, array $params): void { @@ -281,15 +276,17 @@ final class Dispatcher extends RoutingBase { $logger?->debug('Dispatcher - controller arguments', $params); $params = array_values($params); - $controller->$method(...$params); + $controller->{$method}(...$params); } catch (FailedResponseException) { $controllerName = DEFAULT_CONTROLLER; $controller = new $controllerName($this->container); - $controller->errorPage(500, + $controller->errorPage( + 500, 'API request timed out', - 'Failed to retrieve data from API (╯°□°)╯︵ ┻━┻'); + 'Failed to retrieve data from API (╯°□°)╯︵ ┻━┻' + ); } /* finally @@ -322,12 +319,12 @@ final class Dispatcher extends RoutingBase { $params = []; - switch($failure->failedRule) { + switch ($failure->failedRule) { case Rule\Allows::class: $params = [ 'http_code' => 405, 'title' => '405 Method Not Allowed', - 'message' => 'Invalid HTTP Verb' + 'message' => 'Invalid HTTP Verb', ]; break; @@ -335,7 +332,7 @@ final class Dispatcher extends RoutingBase { $params = [ 'http_code' => 406, 'title' => '406 Not Acceptable', - 'message' => 'Unacceptable content type' + 'message' => 'Unacceptable content type', ]; break; @@ -347,7 +344,7 @@ final class Dispatcher extends RoutingBase { return [ 'params' => $params, - 'action_method' => $actionMethod + 'action_method' => $actionMethod, ]; } @@ -362,6 +359,7 @@ final class Dispatcher extends RoutingBase { // Add routes $routes = []; + foreach ($this->routes as $name => &$route) { $path = $route['path']; @@ -394,14 +392,15 @@ final class Dispatcher extends RoutingBase { // Add the route to the router object if ( ! array_key_exists('tokens', $route)) { - $routes[] = $this->router->$verb($name, $path)->defaults($route); + $routes[] = $this->router->{$verb}($name, $path)->defaults($route); + continue; } $tokens = $route['tokens']; unset($route['tokens']); - $routes[] = $this->router->$verb($name, $path) + $routes[] = $this->router->{$verb}($name, $path) ->defaults($route) ->tokens($tokens); } @@ -410,4 +409,4 @@ final class Dispatcher extends RoutingBase { } } -// End of Dispatcher.php \ No newline at end of file +// End of Dispatcher.php diff --git a/src/AnimeClient/Enum/API.php b/src/AnimeClient/Enum/API.php index e787b659..f574461c 100644 --- a/src/AnimeClient/Enum/API.php +++ b/src/AnimeClient/Enum/API.php @@ -18,7 +18,8 @@ namespace Aviat\AnimeClient\Enum; use Aviat\Ion\Enum; -final class API extends Enum { +final class API extends Enum +{ public const ANILIST = 'anilist'; public const KITSU = 'kitsu'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Enum/EventType.php b/src/AnimeClient/Enum/EventType.php index 022b5c6c..f6804596 100644 --- a/src/AnimeClient/Enum/EventType.php +++ b/src/AnimeClient/Enum/EventType.php @@ -18,8 +18,9 @@ namespace Aviat\AnimeClient\Enum; use Aviat\Ion\Enum as BaseEnum; -final class EventType extends BaseEnum { +final class EventType extends BaseEnum +{ public const CLEAR_CACHE = '::clear-cache::'; public const RESET_CACHE_KEY = '::reset-cache-key::'; public const UNAUTHORIZED = '::unauthorized::'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Enum/MediaType.php b/src/AnimeClient/Enum/MediaType.php index b0275804..71b5baca 100644 --- a/src/AnimeClient/Enum/MediaType.php +++ b/src/AnimeClient/Enum/MediaType.php @@ -21,8 +21,9 @@ use Aviat\Ion\Enum as BaseEnum; /** * Types of media */ -final class MediaType extends BaseEnum { +final class MediaType extends BaseEnum +{ public const ANIME = 'anime'; public const DRAMA = 'drama'; public const MANGA = 'manga'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Enum/SyncAction.php b/src/AnimeClient/Enum/SyncAction.php index 235a2dc1..bad7703f 100644 --- a/src/AnimeClient/Enum/SyncAction.php +++ b/src/AnimeClient/Enum/SyncAction.php @@ -21,8 +21,9 @@ use Aviat\Ion\Enum as BaseEnum; /** * Types of actions when syncing lists from different APIs */ -final class SyncAction extends BaseEnum { +final class SyncAction extends BaseEnum +{ public const CREATE = 'create'; public const UPDATE = 'update'; public const DELETE = 'delete'; -} \ No newline at end of file +} diff --git a/src/AnimeClient/FormGenerator.php b/src/AnimeClient/FormGenerator.php index fda9c007..ba7386cc 100644 --- a/src/AnimeClient/FormGenerator.php +++ b/src/AnimeClient/FormGenerator.php @@ -18,13 +18,13 @@ namespace Aviat\AnimeClient; use Aura\Html\HelperLocator; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; /** * Helper object to manage form generation, especially for config editing */ -final class FormGenerator { +final class FormGenerator +{ /** * Html generation helper */ @@ -60,7 +60,7 @@ final class FormGenerator { if ($display === FALSE) { - return (string)$this->helper->input([ + return (string) $this->helper->input([ 'type' => 'hidden', 'name' => $name, 'value' => $value, @@ -75,7 +75,7 @@ final class FormGenerator { ], ]; - switch($type) + switch ($type) { case 'boolean': $params['type'] = 'radio'; @@ -83,7 +83,7 @@ final class FormGenerator { '1' => 'Yes', '0' => 'No', ]; - $params['strict'] = true; + $params['strict'] = TRUE; unset($params['attribs']['id']); break; @@ -108,6 +108,6 @@ final class FormGenerator { } } - return (string)$this->helper->input($params); + return (string) $this->helper->input($params); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Helper/Form.php b/src/AnimeClient/Helper/Form.php index 642fb735..f1bc05a6 100644 --- a/src/AnimeClient/Helper/Form.php +++ b/src/AnimeClient/Helper/Form.php @@ -22,8 +22,8 @@ use Aviat\Ion\Di\ContainerAware; /** * FormGenerator helper wrapper */ -final class Form { - +final class Form +{ use ContainerAware; /** diff --git a/src/AnimeClient/Helper/Menu.php b/src/AnimeClient/Helper/Menu.php index 32194482..e0247c88 100644 --- a/src/AnimeClient/Helper/Menu.php +++ b/src/AnimeClient/Helper/Menu.php @@ -22,8 +22,8 @@ use Aviat\Ion\Di\ContainerAware; /** * MenuGenerator helper wrapper */ -final class Menu { - +final class Menu +{ use ContainerAware; /** @@ -35,7 +35,6 @@ final class Menu { { return MenuGenerator::new($this->container)->generate($menuName); } - } -// End of Menu.php \ No newline at end of file +// End of Menu.php diff --git a/src/AnimeClient/Helper/Picture.php b/src/AnimeClient/Helper/Picture.php index 012fa989..702f895c 100644 --- a/src/AnimeClient/Helper/Picture.php +++ b/src/AnimeClient/Helper/Picture.php @@ -17,12 +17,13 @@ namespace Aviat\AnimeClient\Helper; use Aviat\Ion\Di\ContainerAware; +use function in_array; /** * Simplify picture elements */ -final class Picture { - +final class Picture +{ use ContainerAware; private const SIMPLE_IMAGE_TYPES = [ @@ -60,7 +61,8 @@ final class Picture { $ext = array_pop($urlParts); $path = implode('.', $urlParts); - $mime = match ($ext) { + $mime = match ($ext) + { 'avif' => 'image/avif', 'apng' => 'image/vnd.mozilla.apng', 'bmp' => 'image/bmp', @@ -74,7 +76,8 @@ final class Picture { default => 'image/jpeg', }; - $fallbackMime = match ($fallbackExt) { + $fallbackMime = match ($fallbackExt) + { 'gif' => 'image/gif', 'png' => 'image/png', default => 'image/jpeg', @@ -83,10 +86,9 @@ final class Picture { // For image types that are well-established, just return a // simple element instead if ( - $ext === $fallbackExt || - \in_array($ext, Picture::SIMPLE_IMAGE_TYPES, TRUE) - ) - { + $ext === $fallbackExt + || in_array($ext, Picture::SIMPLE_IMAGE_TYPES, TRUE) + ) { $attrs = (count($imgAttrs) > 1) ? $imgAttrs : $picAttrs; @@ -103,7 +105,7 @@ final class Picture { ]), $helper->void('source', [ 'srcset' => $fallbackImg, - 'type' => $fallbackMime + 'type' => $fallbackMime, ]), $helper->img($fallbackImg, array_merge(['alt' => ''], $imgAttrs)), ]; @@ -114,4 +116,4 @@ final class Picture { } } -// End of Picture.php \ No newline at end of file +// End of Picture.php diff --git a/src/AnimeClient/Kitsu.php b/src/AnimeClient/Kitsu.php index 16cf774f..92c05544 100644 --- a/src/AnimeClient/Kitsu.php +++ b/src/AnimeClient/Kitsu.php @@ -16,14 +16,15 @@ namespace Aviat\AnimeClient; -use Aviat\AnimeClient\API\Kitsu\Enum\AnimeAiringStatus; -use Aviat\AnimeClient\API\Kitsu\Enum\MangaPublishingStatus; +use Aviat\AnimeClient\API\Kitsu\Enum\{AnimeAiringStatus, MangaPublishingStatus}; use DateTimeImmutable; +use const PHP_URL_HOST; /** * Data massaging helpers for the Kitsu API */ -final class Kitsu { +final class Kitsu +{ public const AUTH_URL = 'https://kitsu.io/api/oauth/token'; public const AUTH_USER_ID_KEY = 'kitsu-auth-userid'; public const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token'; @@ -31,9 +32,7 @@ final class Kitsu { public const AUTH_TOKEN_REFRESH_CACHE_KEY = 'kitsu-auth-token-refresh'; public const ANIME_HISTORY_LIST_CACHE_KEY = 'kitsu-anime-history-list'; public const MANGA_HISTORY_LIST_CACHE_KEY = 'kitsu-manga-history-list'; - public const GRAPHQL_ENDPOINT = 'https://kitsu.io/api/graphql'; - public const SECONDS_IN_MINUTE = 60; public const MINUTES_IN_HOUR = 60; public const MINUTES_IN_DAY = 1440; @@ -41,11 +40,8 @@ final class Kitsu { /** * Determine whether an anime is airing, finished airing, or has not yet aired - * - * @param string|null $startDate - * @param string|null $endDate */ - public static function getAiringStatus(string $startDate = NULL, string $endDate = NULL): string + public static function getAiringStatus(?string $startDate = NULL, ?string $endDate = NULL): string { $startAirDate = new DateTimeImmutable($startDate ?? 'tomorrow'); $endAirDate = new DateTimeImmutable($endDate ?? 'next year'); @@ -69,11 +65,8 @@ final class Kitsu { /** * Reformat the airing date range for an Anime - * - * @param string|null $startDate - * @param string|null $endDate */ - public static function formatAirDates(string $startDate = NULL, string $endDate = NULL): string + public static function formatAirDates(?string $startDate = NULL, ?string $endDate = NULL): string { if (empty($startDate)) { @@ -117,7 +110,7 @@ final class Kitsu { return "{$monthMap[$startMonth]} {$startYear} - {$monthMap[$endMonth]} {$endYear}"; } - public static function getPublishingStatus(string $kitsuStatus, string $startDate = NULL, string $endDate = NULL): string + public static function getPublishingStatus(string $kitsuStatus, ?string $startDate = NULL, ?string $endDate = NULL): string { $startPubDate = new DateTimeImmutable($startDate ?? 'tomorrow'); $endPubDate = new DateTimeImmutable($endDate ?? 'next year'); @@ -196,7 +189,6 @@ final class Kitsu { $key = $uMap['key']; $url = str_replace('{}', $mapping['externalId'], $uMap['url']); - $output[$key] = $url; } @@ -235,7 +227,7 @@ final class Kitsu { $url = '//' . $url; } - $host = parse_url($url, \PHP_URL_HOST); + $host = parse_url($url, PHP_URL_HOST); if ($host === FALSE) { return []; @@ -245,7 +237,7 @@ final class Kitsu { 'meta' => self::getServiceMetaData($host), 'link' => $streamingLink['url'], 'subs' => $streamingLink['subs'], - 'dubs' => $streamingLink['dubs'] + 'dubs' => $streamingLink['dubs'], ]; } @@ -266,7 +258,7 @@ final class Kitsu { ...array_values($titles['localized']), ]); - return array_diff($raw,[$titles['canonical']]); + return array_diff($raw, [$titles['canonical']]); } /** @@ -283,7 +275,7 @@ final class Kitsu { { if (array_key_exists($search, $titles) && is_array($titles[$search])) { - foreach($titles[$search] as $alternateTitle) + foreach ($titles[$search] as $alternateTitle) { if (self::titleIsUnique($alternateTitle, $valid)) { @@ -311,11 +303,11 @@ final class Kitsu { if (array_key_exists('localized', $titles) && is_array($titles['localized'])) { - foreach($titles['localized'] as $locale => $alternateTitle) + foreach ($titles['localized'] as $locale => $alternateTitle) { // Really don't care about languages that aren't english // or Japanese for titles - if ( ! in_array($locale, ['en', 'en_us', 'en_jp', 'ja_jp'])) + if ( ! in_array($locale, ['en', 'en_us', 'en_jp', 'ja_jp'], TRUE)) { continue; } @@ -338,22 +330,21 @@ final class Kitsu { */ public static function getPosterImage(array $base, int $size = 1): string { - $rawUrl = $base['posterImage']['views'][$size]['url'] + $rawUrl = $base['posterImage']['views'][$size]['url'] ?? $base['posterImage']['original']['url'] ?? '/public/images/placeholder.png'; $parts = explode('?', $rawUrl); - return ( empty($parts)) ? $rawUrl : $parts[0]; + return (empty($parts)) ? $rawUrl : $parts[0]; } /** * Get the name and logo for the streaming service of the current link * - * @param string|null $hostname - * @return string[]|bool[] + * @return bool[]|string[] */ - protected static function getServiceMetaData(string $hostname = NULL): array + private static function getServiceMetaData(?string $hostname = NULL): array { $hostname = str_replace('www.', '', $hostname ?? ''); @@ -376,7 +367,7 @@ final class Kitsu { 'daisuki.net' => [ 'name' => 'Daisuki', 'link' => TRUE, - 'image' => 'streaming-logos/daisuki.svg' + 'image' => 'streaming-logos/daisuki.svg', ], 'funimation.com' => [ 'name' => 'Funimation', @@ -401,13 +392,13 @@ final class Kitsu { 'viewster.com' => [ 'name' => 'Viewster', 'link' => TRUE, - 'image' => 'streaming-logos/viewster.svg' + 'image' => 'streaming-logos/viewster.svg', ], 'vrv.co' => [ 'name' => 'VRV', 'link' => TRUE, 'image' => 'streaming-logos/vrv.svg', - ] + ], ]; if (array_key_exists($hostname, $serviceMap)) @@ -434,7 +425,7 @@ final class Kitsu { $minutes = ($seconds - $remSeconds) / self::SECONDS_IN_MINUTE; // Minutes short of a year - $years = (int)floor($minutes / self::MINUTES_IN_YEAR); + $years = (int) floor($minutes / self::MINUTES_IN_YEAR); $minutes %= self::MINUTES_IN_YEAR; // Minutes short of a day @@ -446,13 +437,14 @@ final class Kitsu { $hours = ($extraMinutes - $remMinutes) / self::MINUTES_IN_HOUR; $parts = []; + foreach ([ 'year' => $years, 'day' => $days, 'hour' => $hours, 'minute' => $remMinutes, - 'second' => $remSeconds - ] as $label => $value) + 'second' => $remSeconds, + ] as $label => $value) { if ($value === 0) { @@ -482,14 +474,14 @@ final class Kitsu { /** * Determine if an alternate title is unique enough to list */ - protected static function titleIsUnique(?string $title = '', array $existingTitles = []): bool + private static function titleIsUnique(?string $title = '', array $existingTitles = []): bool { if (empty($title)) { return FALSE; } - foreach($existingTitles as $existing) + foreach ($existingTitles as $existing) { $isSubset = mb_substr_count($existing, $title) > 0; $diff = levenshtein(mb_strtolower($existing), mb_strtolower($title)); @@ -502,4 +494,4 @@ final class Kitsu { return TRUE; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/MenuGenerator.php b/src/AnimeClient/MenuGenerator.php index 84258aab..7bed66c8 100644 --- a/src/AnimeClient/MenuGenerator.php +++ b/src/AnimeClient/MenuGenerator.php @@ -16,19 +16,18 @@ namespace Aviat\AnimeClient; -use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aura\Html\HelperLocator; use Aviat\Ion\Di\ContainerInterface; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Exception\ConfigException; -use Aviat\Ion\Type\ArrayType; -use Aviat\Ion\Type\StringType; +use Aviat\Ion\Type\{ArrayType, StringType}; use Psr\Http\Message\ServerRequestInterface; /** * Helper object to manage menu creation and selection */ -final class MenuGenerator extends UrlGenerator { - +final class MenuGenerator extends UrlGenerator +{ /** * Html generation helper */ @@ -49,7 +48,7 @@ final class MenuGenerator extends UrlGenerator { * * @throws ConfigException */ - public function generate(string $menu) : string + public function generate(string $menu): string { $menus = $this->config->get('menus'); $parsedConfig = $this->parseConfig($menus); @@ -101,17 +100,18 @@ final class MenuGenerator extends UrlGenerator { * * @return array> */ - private function parseConfig(array $menus) : array + private function parseConfig(array $menus): array { $parsed = []; foreach ($menus as $name => $menu) { $parsed[$name] = []; + foreach ($menu['items'] as $pathName => $partialPath) { - $title = (string)StringType::from($pathName)->humanize()->titleize(); - $parsed[$name][$title] = (string)StringType::from($menu['route_prefix'])->append($partialPath); + $title = (string) StringType::from($pathName)->humanize()->titleize(); + $parsed[$name][$title] = (string) StringType::from($menu['route_prefix'])->append($partialPath); } } @@ -119,4 +119,4 @@ final class MenuGenerator extends UrlGenerator { } } -// End of MenuGenerator.php \ No newline at end of file +// End of MenuGenerator.php diff --git a/src/AnimeClient/Model/API.php b/src/AnimeClient/Model/API.php index 814b1db8..f455a280 100644 --- a/src/AnimeClient/Model/API.php +++ b/src/AnimeClient/Model/API.php @@ -19,7 +19,8 @@ namespace Aviat\AnimeClient\Model; /** * Base model for api interaction */ -abstract class API { +abstract class API +{ /** * Sort the list entries by their title */ @@ -40,11 +41,11 @@ abstract class API { array_multisort($sort, SORT_ASC, $array); // Re-key array items by their ids - if (array_key_exists('id', (array)$array[0])) + if (array_key_exists('id', (array) $array[0])) { $keyed = []; - foreach($array as $item) + foreach ($array as $item) { $keyed[$item['id']] = $item; } @@ -52,4 +53,4 @@ abstract class API { $array = $keyed; } } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Model/Anime.php b/src/AnimeClient/Model/Anime.php index 768d8fb3..45101008 100644 --- a/src/AnimeClient/Model/Anime.php +++ b/src/AnimeClient/Model/Anime.php @@ -22,7 +22,8 @@ use Aviat\AnimeClient\Types\Anime as AnimeType; /** * Model for handling requests dealing with the anime list */ -class Anime extends API { +class Anime extends API +{ use MediaTrait; protected string $type = 'anime'; @@ -52,9 +53,9 @@ class Anime extends API { */ public function getAllLists(): array { - $data = $this->kitsuModel->getFullOrganizedAnimeList(); + $data = $this->kitsuModel->getFullOrganizedAnimeList(); - foreach($data as &$list) + foreach ($data as &$list) { $this->sortByName($list, 'anime'); } @@ -95,6 +96,4 @@ class Anime extends API { { return $this->kitsuModel->getAnimeHistory(); } - - -} \ No newline at end of file +} diff --git a/src/AnimeClient/Model/AnimeCollection.php b/src/AnimeClient/Model/AnimeCollection.php index 8290e027..c573da80 100644 --- a/src/AnimeClient/Model/AnimeCollection.php +++ b/src/AnimeClient/Model/AnimeCollection.php @@ -19,13 +19,12 @@ namespace Aviat\AnimeClient\Model; use Aviat\Ion\Di\ContainerInterface; use PDO; use PDOException; -use function in_array; /** * Model for getting anime collection data */ -final class AnimeCollection extends Collection { - +final class AnimeCollection extends Collection +{ /** * Anime API Model */ @@ -76,7 +75,7 @@ final class AnimeCollection extends Collection { * * @return mixed[] */ - public function getFlatCollection(): array + public function getFlatCollection(): array { if ($this->db === NULL) { @@ -99,7 +98,7 @@ final class AnimeCollection extends Collection { return []; } - foreach($rows as &$row) + foreach ($rows as &$row) { $id = $row['hummingbird_id']; @@ -164,7 +163,7 @@ final class AnimeCollection extends Collection { 'Other' => [ 10 => $flatList[10], // UMD 11 => $flatList[11], // Other - ] + ], ]; } @@ -185,7 +184,7 @@ final class AnimeCollection extends Collection { } $id = $data['id']; - $anime = (object)$this->animeModel->getAnimeById($id); + $anime = (object) $this->animeModel->getAnimeById($id); $this->db->set([ 'hummingbird_id' => $id, @@ -197,7 +196,7 @@ final class AnimeCollection extends Collection { 'cover_image' => $anime->cover_image, 'episode_count' => $anime->episode_count, 'episode_length' => $anime->episode_length, - 'notes' => $data['notes'] + 'notes' => $data['notes'], ])->insert('anime_set'); $this->updateMediaLink($id, $data['media_id']); @@ -216,7 +215,7 @@ final class AnimeCollection extends Collection { $row = $this->get($data['id']); - return ! empty($row); + return ! empty($row); } /** @@ -256,8 +255,6 @@ final class AnimeCollection extends Collection { /** * Verify that the collection item was updated - * - * */ public function wasUpdated(array $data): bool { @@ -275,7 +272,7 @@ final class AnimeCollection extends Collection { continue; } - if ((string)$row[$key] !== (string)$value) + if ((string) $row[$key] !== (string) $value) { return FALSE; } @@ -406,7 +403,6 @@ final class AnimeCollection extends Collection { ->from('anime_set_genre_link gl') ->join('genres g', 'g.id=gl.genre_id', 'left'); - if ( ! empty($filter)) { $this->db->whereIn('hummingbird_id', $filter); @@ -443,7 +439,9 @@ final class AnimeCollection extends Collection { } } } - catch (PDOException) {} + catch (PDOException) + { + } $this->db->resetQuery(); @@ -473,7 +471,6 @@ final class AnimeCollection extends Collection { ->from('anime_set_media_link ml') ->join('media m', 'm.id=ml.media_id', 'left'); - if ( ! empty($filter)) { $this->db->whereIn('hummingbird_id', $filter); @@ -510,7 +507,9 @@ final class AnimeCollection extends Collection { } } } - catch (PDOException) {} + catch (PDOException) + { + } $this->db->resetQuery(); @@ -532,6 +531,7 @@ final class AnimeCollection extends Collection { // Add the new entries $entries = []; + foreach ($media as $id) { $entries[] = [ @@ -592,7 +592,9 @@ final class AnimeCollection extends Collection { { $this->db->insertBatch('anime_set_genre_link', $linksToInsert); } - catch (PDOException) {} + catch (PDOException) + { + } } } @@ -744,7 +746,7 @@ final class AnimeCollection extends Collection { $genres = $this->getGenreList(); - foreach($rows as &$row) + foreach ($rows as &$row) { $id = $row['hummingbird_id']; @@ -759,4 +761,4 @@ final class AnimeCollection extends Collection { } } -// End of AnimeCollectionModel.php \ No newline at end of file +// End of AnimeCollectionModel.php diff --git a/src/AnimeClient/Model/Collection.php b/src/AnimeClient/Model/Collection.php index 7d5af31a..94b7cf1f 100644 --- a/src/AnimeClient/Model/Collection.php +++ b/src/AnimeClient/Model/Collection.php @@ -25,8 +25,8 @@ use function Query; /** * Base model for anime and manga collections */ -class Collection extends DB { - +class Collection extends DB +{ /** * The query builder object */ @@ -67,4 +67,4 @@ class Collection extends DB { } } -// End of Collection.php \ No newline at end of file +// End of Collection.php diff --git a/src/AnimeClient/Model/DB.php b/src/AnimeClient/Model/DB.php index d610aefb..0a78fc73 100644 --- a/src/AnimeClient/Model/DB.php +++ b/src/AnimeClient/Model/DB.php @@ -21,7 +21,8 @@ use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; /** * Base model for database interaction */ -abstract class DB { +abstract class DB +{ use ContainerAware; /** @@ -31,8 +32,6 @@ abstract class DB { /** * Constructor - * - * @param ContainerInterface $container */ public function __construct(ContainerInterface $container) { @@ -41,4 +40,4 @@ abstract class DB { } } -// End of DB.php \ No newline at end of file +// End of DB.php diff --git a/src/AnimeClient/Model/Manga.php b/src/AnimeClient/Model/Manga.php index fa4c2a07..135f6b13 100644 --- a/src/AnimeClient/Model/Manga.php +++ b/src/AnimeClient/Model/Manga.php @@ -27,7 +27,8 @@ use Aviat\AnimeClient\Types\{ /** * Model for handling requests dealing with the manga list */ -class Manga extends API { +class Manga extends API +{ use MediaTrait; protected string $type = 'manga'; @@ -42,7 +43,8 @@ class Manga extends API { if ($status === 'All') { $data = $this->kitsuModel->getFullOrganizedMangaList(); - foreach($data as &$section) + + foreach ($data as &$section) { $this->sortByName($section, 'manga'); } @@ -53,13 +55,12 @@ class Manga extends API { $APIstatus = MangaReadingStatus::TITLE_TO_KITSU[$status]; $data = $this->mapByStatus($this->kitsuModel->getMangaList($APIstatus)); $this->sortByName($data[$status], 'manga'); + return $data[$status]; } /** * Get the details of a manga - * - * @return MangaPage */ public function getManga(string $manga_id): MangaPage { @@ -68,8 +69,6 @@ class Manga extends API { /** * Get the details of a random manga - * - * @return MangaPage */ public function getRandomManga(): MangaPage { @@ -78,8 +77,6 @@ class Manga extends API { /** * Get anime by its kitsu id - * - * @return MangaPage */ public function getMangaById(string $animeId): MangaPage { @@ -111,7 +108,8 @@ class Manga extends API { Title::COMPLETED => [], ]; - foreach ($data as $entry) { + foreach ($data as $entry) + { $statusMap = MangaReadingStatus::KITSU_TO_TITLE; $key = $statusMap[$entry['reading_status']]; $output[$key][] = $entry; @@ -123,4 +121,4 @@ class Manga extends API { } } -// End of MangaModel.php \ No newline at end of file +// End of MangaModel.php diff --git a/src/AnimeClient/Model/MediaTrait.php b/src/AnimeClient/Model/MediaTrait.php index 15751c9d..c9a97fd6 100644 --- a/src/AnimeClient/Model/MediaTrait.php +++ b/src/AnimeClient/Model/MediaTrait.php @@ -16,12 +16,8 @@ namespace Aviat\AnimeClient\Model; -use Aviat\AnimeClient\API\Anilist; -use Aviat\AnimeClient\API\Kitsu; -use Aviat\AnimeClient\API\ParallelAPIRequest; -use Aviat\AnimeClient\Types\AnimeListItem; -use Aviat\AnimeClient\Types\FormItem; -use Aviat\AnimeClient\Types\MangaListItem; +use Aviat\AnimeClient\API\{Anilist, Kitsu, ParallelAPIRequest}; +use Aviat\AnimeClient\Types\{AnimeListItem, FormItem, MangaListItem}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Json; @@ -30,8 +26,8 @@ use Throwable; /** * Common functionality for Anime/Manga Models */ -trait MediaTrait { - +trait MediaTrait +{ /** * Is the Anilist API enabled? */ @@ -64,7 +60,7 @@ trait MediaTrait { * * @return mixed[] */ - public function search(string $name, bool $inCollection = false): array + public function search(string $name, bool $inCollection = FALSE): array { $data = $this->kitsuModel->search($this->type, urldecode($name)); @@ -101,7 +97,7 @@ trait MediaTrait { $requester->addRequest($kitsuRequest, 'kitsu'); - if ($this->anilistEnabled && $data['mal_id'] !== null) + if ($this->anilistEnabled && $data['mal_id'] !== NULL) { // If can't map MAL id, this will be null $maybeRequest = $this->anilistModel->createListItem($data, strtoupper($this->type)); @@ -144,7 +140,7 @@ trait MediaTrait { return [ 'body' => Json::decode($results['kitsu']), - 'statusCode' => $statusCode + 'statusCode' => $statusCode, ]; } @@ -172,26 +168,25 @@ trait MediaTrait { $results = $requester->makeRequests(); $body = Json::decode($results['kitsu']); - $statusCode = array_key_exists('errors', $body) ? 400: 200; + $statusCode = array_key_exists('errors', $body) ? 400 : 200; return [ 'body' => Json::decode($results['kitsu']), - 'statusCode' => $statusCode + 'statusCode' => $statusCode, ]; } /** * Delete a list entry * - * @param string|null $malId * @throws Throwable */ - public function deleteLibraryItem(string $id, string $malId = NULL): bool + public function deleteLibraryItem(string $id, ?string $malId = NULL): bool { $requester = new ParallelAPIRequest(); $requester->addRequest($this->kitsuModel->deleteListItem($id), 'kitsu'); - if ($this->anilistEnabled && $malId !== null) + if ($this->anilistEnabled && $malId !== NULL) { // If can't map MAL id, this will be null $maybeRequest = $this->anilistModel->deleteListItem($malId, strtoupper($this->type)); @@ -205,4 +200,4 @@ trait MediaTrait { return $results !== []; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Model/Settings.php b/src/AnimeClient/Model/Settings.php index 426b620c..b6f01fd1 100644 --- a/src/AnimeClient/Model/Settings.php +++ b/src/AnimeClient/Model/Settings.php @@ -16,21 +16,21 @@ namespace Aviat\AnimeClient\Model; -use function is_array; -use const Aviat\AnimeClient\SETTINGS_MAP; - -use function Aviat\AnimeClient\arrayToToml; -use function Aviat\Ion\_dir; - use Aviat\AnimeClient\Types\{Config, UndefinedPropertyException}; use Aviat\Ion\ConfigInterface; use Aviat\Ion\Di\ContainerAware; +use function Aviat\AnimeClient\arrayToToml; + +use function Aviat\Ion\_dir; +use const Aviat\AnimeClient\SETTINGS_MAP; + /** * Model for handling settings control panel */ -final class Settings { +final class Settings +{ use ContainerAware; public function __construct(private ConfigInterface $config) @@ -46,12 +46,13 @@ final class Settings { 'config' => [], ]; - foreach(SETTINGS_MAP as $file => $values) + foreach (SETTINGS_MAP as $file => $values) { if ($file === 'config') { $keys = array_keys($values); - foreach($keys as $key) + + foreach ($keys as $key) { $settings['config'][$key] = $this->config->get($key); } @@ -72,19 +73,20 @@ final class Settings { { $output = []; - foreach($this->getSettings() as $file => $values) + foreach ($this->getSettings() as $file => $values) { $values ??= []; - foreach(SETTINGS_MAP[$file] as $key => $value) + foreach (SETTINGS_MAP[$file] as $key => $value) { if ($value['type'] === 'subfield') { - foreach($value['fields'] as $k => $field) + foreach ($value['fields'] as $k => $field) { if (empty($values[$key][$k])) { unset($value['fields'][$k]); + continue; } @@ -159,13 +161,13 @@ final class Settings { } elseif (is_array($val) && ! empty($val)) { - foreach($val as $k => $v) + foreach ($val as $k => $v) { if ($v === '1') { $keyedConfig[$key][$k] = TRUE; } - elseif($v === '0') + elseif ($v === '0') { $keyedConfig[$key][$k] = FALSE; } @@ -182,12 +184,12 @@ final class Settings { $output = []; - foreach($looseConfig as $k => $v) + foreach ($looseConfig as $k => $v) { $output[$k] = $v; } - foreach($keyedConfig as $k => $v) + foreach ($keyedConfig as $k => $v) { $output[$k] = $v; } @@ -211,6 +213,7 @@ final class Settings { { dump($e); dump($settings); + return FALSE; } @@ -221,4 +224,4 @@ final class Settings { return $saved !== FALSE; } -} \ No newline at end of file +} diff --git a/src/AnimeClient/RoutingBase.php b/src/AnimeClient/RoutingBase.php index c2d2daf7..60327930 100644 --- a/src/AnimeClient/RoutingBase.php +++ b/src/AnimeClient/RoutingBase.php @@ -18,8 +18,7 @@ namespace Aviat\AnimeClient; use Aviat\Ion\ConfigInterface; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Exception\ConfigException; use Aviat\Ion\Type\StringType; use Psr\Http\Message\ServerRequestInterface; @@ -27,8 +26,8 @@ use Psr\Http\Message\ServerRequestInterface; /** * Base for routing/url classes */ -class RoutingBase { - +class RoutingBase +{ /** * Config Object */ @@ -42,9 +41,9 @@ class RoutingBase { /** * Constructor * + * @throws ConfigException * @throws ContainerException * @throws NotFoundException - * @throws ConfigException */ public function __construct(protected ContainerInterface $container) { @@ -64,7 +63,7 @@ class RoutingBase { ->trimRight('/') ->ensureLeft('/'); - return (string)$cleanedPath; + return (string) $cleanedPath; } /** @@ -73,17 +72,17 @@ class RoutingBase { public function segments(): array { $path = $this->path(); + return explode('/', $path); } /** * Get a segment of the current url - * - * */ public function getSegment(int $num): ?string { $segments = $this->segments(); + return $segments[$num] ?? NULL; } @@ -93,6 +92,7 @@ class RoutingBase { public function lastSegment(): string { $segments = $this->segments(); + return end($segments); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/AbstractType.php b/src/AnimeClient/Types/AbstractType.php index 4b4f52ce..0aa24ee8 100644 --- a/src/AnimeClient/Types/AbstractType.php +++ b/src/AnimeClient/Types/AbstractType.php @@ -18,8 +18,10 @@ namespace Aviat\AnimeClient\Types; use ArrayAccess; use Countable; +use Stringable; -abstract class AbstractType implements ArrayAccess, Countable, \Stringable { +abstract class AbstractType implements ArrayAccess, Countable, Stringable +{ /** * Populate values for un-serializing data */ @@ -56,8 +58,8 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { */ final private function __construct(mixed $data = []) { - $typeKeys = array_keys((array)$this); - $dataKeys = array_keys((array)$data); + $typeKeys = array_keys((array) $this); + $dataKeys = array_keys((array) $data); $unsetKeys = array_diff($typeKeys, $dataKeys); @@ -69,7 +71,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { // Remove unset keys so that they aren't serialized foreach ($unsetKeys as $k) { - unset($this->$k); + unset($this->{$k}); } } @@ -78,7 +80,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { */ final public function __isset(string $name): bool { - return property_exists($this, $name) && isset($this->$name); + return property_exists($this, $name) && isset($this->{$name}); } /** @@ -90,7 +92,8 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { if (method_exists($this, $setterMethod)) { - $this->$setterMethod($value); + $this->{$setterMethod}($value); + return; } @@ -101,7 +104,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { throw new UndefinedPropertyException("Trying to set undefined property: '{$name}'. Existing properties: {$existing}"); } - $this->$name = $value; + $this->{$name} = $value; } /** @@ -111,7 +114,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { { // Be a bit more lenient here, so that you can easily typecast missing // values to reasonable defaults, and not have to resort to array indexes - return ($this->__isset($name)) ? $this->$name : NULL; + return ($this->__isset($name)) ? $this->{$name} : NULL; } /** @@ -127,7 +130,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { */ final public function offsetExists(mixed $offset): bool { - return $this->__isset((string)$offset); + return $this->__isset((string) $offset); } /** @@ -135,7 +138,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { */ final public function offsetGet(mixed $offset): mixed { - return $this->__get((string)$offset); + return $this->__get((string) $offset); } /** @@ -143,7 +146,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { */ final public function offsetSet(mixed $offset, mixed $value): void { - $this->__set((string)$offset, $value); + $this->__set((string) $offset, $value); } /** @@ -153,8 +156,8 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { { if ($this->offsetExists($offset)) { - $strOffset = (string)$offset; - unset($this->$strOffset); + $strOffset = (string) $offset; + unset($this->{$strOffset}); } } @@ -164,6 +167,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { final public function count(): int { $keys = array_keys($this->toArray()); + return count($keys); } @@ -174,9 +178,10 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { * * @param mixed $parent */ - final public function toArray(mixed $parent = null): array + final public function toArray(mixed $parent = NULL): array { $fromObject = $this->fromObject($parent); + return (is_array($fromObject)) ? $fromObject : []; } @@ -186,6 +191,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { final public function isEmpty(): bool { $self = $this->toArray(); + foreach ($self as $value) { if ( ! empty($value)) @@ -200,7 +206,7 @@ abstract class AbstractType implements ArrayAccess, Countable, \Stringable { /** * @codeCoverageIgnore */ - final protected function fromObject(mixed $parent = null): float|null|bool|int|array|string + final protected function fromObject(mixed $parent = NULL): float|NULL|bool|int|array|string { $object = $parent ?? $this; diff --git a/src/AnimeClient/Types/Anime.php b/src/AnimeClient/Types/Anime.php index e201f8a5..18f905ea 100644 --- a/src/AnimeClient/Types/Anime.php +++ b/src/AnimeClient/Types/Anime.php @@ -21,37 +21,23 @@ use Aviat\AnimeClient\API\Kitsu\Enum\AnimeAiringStatus; /** * Type representing an anime within a watch list */ -class Anime extends AbstractType { +class Anime extends AbstractType +{ public ?string $age_rating; - public ?string $age_rating_guide; - public ?string $cover_image; - public ?int $episode_count; - public ?int $episode_length; - public array $genres = []; - public string $id = ''; - public ?string $show_type; - public ?string $slug; - public string $status = AnimeAiringStatus::FINISHED_AIRING; - public ?array $streaming_links = []; - public ?string $synopsis; - public ?string $title; - public array $titles = []; - public array $titles_more = []; - public ?string $trailer_id; /** @@ -63,4 +49,4 @@ class Anime extends AbstractType { * Kitsu detail page url */ public ?string $url; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/AnimeListItem.php b/src/AnimeClient/Types/AnimeListItem.php index dda4285e..0338aff6 100644 --- a/src/AnimeClient/Types/AnimeListItem.php +++ b/src/AnimeClient/Types/AnimeListItem.php @@ -19,35 +19,26 @@ namespace Aviat\AnimeClient\Types; /** * Type representing an anime watch list item */ -final class AnimeListItem extends AbstractType { +final class AnimeListItem extends AbstractType +{ public ?string $id; - public ?string $anilist_id; - public ?string $mal_id; - public array $episodes = [ 'length' => 0, 'total' => 0, 'watched' => '', ]; - public array $airing = [ 'status' => '', 'started' => '', 'ended' => '', ]; - public ?Anime $anime; - public ?string $notes; - public bool $private = FALSE; - public bool $rewatching = FALSE; - public int $rewatched = 0; - public string|int $user_rating = ''; /** diff --git a/src/AnimeClient/Types/AnimePage.php b/src/AnimeClient/Types/AnimePage.php index a9f851ff..8021ad55 100644 --- a/src/AnimeClient/Types/AnimePage.php +++ b/src/AnimeClient/Types/AnimePage.php @@ -19,12 +19,10 @@ namespace Aviat\AnimeClient\Types; /** * Type representing an Anime object for a detail page */ -final class AnimePage extends Anime { +final class AnimePage extends Anime +{ public array $characters = []; - public array $links = []; - public array $staff = []; - public ?string $airDate = ''; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/Character.php b/src/AnimeClient/Types/Character.php index 4d619a0b..57aa94c1 100644 --- a/src/AnimeClient/Types/Character.php +++ b/src/AnimeClient/Types/Character.php @@ -19,25 +19,19 @@ namespace Aviat\AnimeClient\Types; /** * Type representing a character for display */ -final class Character extends AbstractType { +final class Character extends AbstractType +{ public array $castings = []; - public ?string $description; - public string $id; - public ?Media $media; - public string $image; - public ?string $name; - public array $names = []; - public array $otherNames = []; - public function setMedia (mixed $media): void + public function setMedia(mixed $media): void { $this->media = Media::from($media); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/Characters.php b/src/AnimeClient/Types/Characters.php index b951e2d6..37606c89 100644 --- a/src/AnimeClient/Types/Characters.php +++ b/src/AnimeClient/Types/Characters.php @@ -16,8 +16,8 @@ namespace Aviat\AnimeClient\Types; -final class Characters extends AbstractType { +final class Characters extends AbstractType +{ public array $main = []; - public array $supporting = []; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/Config.php b/src/AnimeClient/Types/Config.php index 84ff5c12..0cf324e9 100644 --- a/src/AnimeClient/Types/Config.php +++ b/src/AnimeClient/Types/Config.php @@ -16,16 +16,14 @@ namespace Aviat\AnimeClient\Types; -class Config extends AbstractType { - +class Config extends AbstractType +{ // ------------------------------------------------------------------------ // Config files/namespaces // ------------------------------------------------------------------------ public ?Config\Anilist $anilist; - public ?Config\Cache $cache; - public ?Config\Database $database; // ------------------------------------------------------------------------ @@ -33,7 +31,6 @@ class Config extends AbstractType { // ------------------------------------------------------------------------ public string $root; // Path to app root - public ?string $asset_path; // Path to public folder for urls /** @@ -66,11 +63,8 @@ class Config extends AbstractType { public ?string $default_view_type; public ?string $kitsu_username; - public bool $secure_urls = TRUE; - public string|bool $show_anime_collection = FALSE; - public string|bool $show_manga_collection = FALSE; /** @@ -80,9 +74,7 @@ class Config extends AbstractType { public ?string $theme = 'auto'; public ?string $whose_list; - public array $menus = []; - public array $routes = []; // ------------------------------------------------------------------------ @@ -90,29 +82,24 @@ class Config extends AbstractType { // ------------------------------------------------------------------------ public ?string $asset_dir; // Path to public folder for local files - public ?string $base_config_dir; - public ?string $config_dir; - public ?string $data_cache_path; - public ?string $img_cache_path; - public ?string $view_path; - public function setAnilist (mixed $data): void + public function setAnilist(mixed $data): void { $this->anilist = Config\Anilist::from($data); } - public function setCache (mixed $data): void + public function setCache(mixed $data): void { $this->cache = Config\Cache::from($data); } - public function setDatabase (mixed $data): void + public function setDatabase(mixed $data): void { $this->database = Config\Database::from($data); } -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/Config/Anilist.php b/src/AnimeClient/Types/Config/Anilist.php index a44133ad..7b850dab 100644 --- a/src/AnimeClient/Types/Config/Anilist.php +++ b/src/AnimeClient/Types/Config/Anilist.php @@ -18,18 +18,13 @@ namespace Aviat\AnimeClient\Types\Config; use Aviat\AnimeClient\Types\AbstractType; -class Anilist extends AbstractType { +class Anilist extends AbstractType +{ public bool|string $enabled = FALSE; - public ?string $client_id; - public ?string $client_secret; - public ?string $access_token; - - public int|string|null $access_token_expires; - + public int|string|NULL $access_token_expires; public ?string $refresh_token; - public ?string $username; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/Config/Cache.php b/src/AnimeClient/Types/Config/Cache.php index 46b85145..5b19a64f 100644 --- a/src/AnimeClient/Types/Config/Cache.php +++ b/src/AnimeClient/Types/Config/Cache.php @@ -18,16 +18,12 @@ namespace Aviat\AnimeClient\Types\Config; use Aviat\AnimeClient\Types\AbstractType; -class Cache extends AbstractType { +class Cache extends AbstractType +{ public string $driver = 'null'; - public ?string $host; - - public string|int|null $port; - + public string|int|NULL $port; public ?string $database; - public array $connection = []; - public ?array $options; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/Config/Database.php b/src/AnimeClient/Types/Config/Database.php index 07813bd2..1eb3bfcb 100644 --- a/src/AnimeClient/Types/Config/Database.php +++ b/src/AnimeClient/Types/Config/Database.php @@ -18,19 +18,13 @@ namespace Aviat\AnimeClient\Types\Config; use Aviat\AnimeClient\Types\AbstractType; -class Database extends AbstractType { - +class Database extends AbstractType +{ public string $type = 'sqlite'; - public ?string $host; - public ?string $user; - public ?string $pass; - - public string|int|null $port; - + public string|int|NULL $port; public ?string $database; - public ?string $file; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/FormItem.php b/src/AnimeClient/Types/FormItem.php index ad1919da..ba877146 100644 --- a/src/AnimeClient/Types/FormItem.php +++ b/src/AnimeClient/Types/FormItem.php @@ -19,11 +19,10 @@ namespace Aviat\AnimeClient\Types; /** * Type representing an Anime object for display */ -class FormItem extends AbstractType { +class FormItem extends AbstractType +{ public string|int $id; - - public string|int|null $mal_id; - + public string|int|NULL $mal_id; public ?FormItemData $data; public function setData(mixed $value): void @@ -31,4 +30,3 @@ class FormItem extends AbstractType { $this->data = FormItemData::from($value); } } - diff --git a/src/AnimeClient/Types/FormItemData.php b/src/AnimeClient/Types/FormItemData.php index 446bcb1a..8d3b93bf 100644 --- a/src/AnimeClient/Types/FormItemData.php +++ b/src/AnimeClient/Types/FormItemData.php @@ -19,21 +19,15 @@ namespace Aviat\AnimeClient\Types; /** * Type representing a Media object for editing/syncing */ -class FormItemData extends AbstractType { +class FormItemData extends AbstractType +{ public ?string $notes; - public ?bool $private = FALSE; - public ?int $progress = NULL; - public ?int $rating; - public ?int $ratingTwenty = NULL; - public string|int $reconsumeCount; - public bool $reconsuming = FALSE; - public string $status; /** diff --git a/src/AnimeClient/Types/HistoryItem.php b/src/AnimeClient/Types/HistoryItem.php index 795f98d6..ee015d15 100644 --- a/src/AnimeClient/Types/HistoryItem.php +++ b/src/AnimeClient/Types/HistoryItem.php @@ -18,7 +18,8 @@ namespace Aviat\AnimeClient\Types; use DateTimeImmutable; -class HistoryItem extends AbstractType { +class HistoryItem extends AbstractType +{ /** * Title of the anime/manga */ @@ -63,4 +64,4 @@ class HistoryItem extends AbstractType { * The item before transformation */ public array $original = []; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/MangaListItem.php b/src/AnimeClient/Types/MangaListItem.php index 47cf64de..60bc4fc7 100644 --- a/src/AnimeClient/Types/MangaListItem.php +++ b/src/AnimeClient/Types/MangaListItem.php @@ -19,34 +19,23 @@ namespace Aviat\AnimeClient\Types; /** * Type representing an Anime object for display */ -final class MangaListItem extends AbstractType { - +final class MangaListItem extends AbstractType +{ public string $id; - public ?string $anilist_id; - public ?string $mal_id; - public array $chapters = [ 'read' => 0, 'total' => 0, ]; - public array $volumes = [ 'read' => '-', 'total' => 0, ]; - public object $manga; - public string $reading_status; - public ?string $notes; - - public bool $rereading = false; - + public bool $rereading = FALSE; public ?int $reread; - - public string|int|null $user_rating; + public string|int|NULL $user_rating; } - diff --git a/src/AnimeClient/Types/MangaListItemDetail.php b/src/AnimeClient/Types/MangaListItemDetail.php index e8c19980..99c1912a 100644 --- a/src/AnimeClient/Types/MangaListItemDetail.php +++ b/src/AnimeClient/Types/MangaListItemDetail.php @@ -19,20 +19,14 @@ namespace Aviat\AnimeClient\Types; /** * Type representing the manga represented by the list item */ -final class MangaListItemDetail extends AbstractType { +final class MangaListItemDetail extends AbstractType +{ public array $genres = []; - public string $id; - public string $image; - public string $slug; - public string $title; - public array $titles; - public ?string $type; - public string $url; } diff --git a/src/AnimeClient/Types/MangaPage.php b/src/AnimeClient/Types/MangaPage.php index 78499988..03f34c95 100644 --- a/src/AnimeClient/Types/MangaPage.php +++ b/src/AnimeClient/Types/MangaPage.php @@ -21,33 +21,21 @@ use Aviat\AnimeClient\API\Kitsu\Enum\MangaPublishingStatus; /** * Type representing an Anime object for display */ -final class MangaPage extends AbstractType { +final class MangaPage extends AbstractType +{ public ?string $age_rating; - public ?string $age_rating_guide; - public array $characters; - public ?int $chapter_count; - public ?string $cover_image; - public array $genres; - public array $links; - public string $id; - public string $manga_type; - public string $status = MangaPublishingStatus::FINISHED; - public array $staff; - public string $synopsis; - public string $title; - public array $titles; /** @@ -56,6 +44,5 @@ final class MangaPage extends AbstractType { public array $titles_more; public string $url; - public ?int $volume_count; } diff --git a/src/AnimeClient/Types/Media.php b/src/AnimeClient/Types/Media.php index f61dfbd5..3a3f89e1 100644 --- a/src/AnimeClient/Types/Media.php +++ b/src/AnimeClient/Types/Media.php @@ -16,8 +16,8 @@ namespace Aviat\AnimeClient\Types; -final class Media extends AbstractType { +final class Media extends AbstractType +{ public array $anime = []; - public array $manga = []; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/Person.php b/src/AnimeClient/Types/Person.php index 13cafc9d..2d9fd143 100644 --- a/src/AnimeClient/Types/Person.php +++ b/src/AnimeClient/Types/Person.php @@ -19,19 +19,13 @@ namespace Aviat\AnimeClient\Types; /** * Type representing a person for display */ -final class Person extends AbstractType { - +final class Person extends AbstractType +{ public string $id; - public ?string $name; - public string $image; - public array $names = []; - public ?string $description; - public array $characters = []; - public array $staff = []; -} \ No newline at end of file +} diff --git a/src/AnimeClient/Types/UndefinedPropertyException.php b/src/AnimeClient/Types/UndefinedPropertyException.php index 224ea573..3a38e1a6 100644 --- a/src/AnimeClient/Types/UndefinedPropertyException.php +++ b/src/AnimeClient/Types/UndefinedPropertyException.php @@ -18,4 +18,6 @@ namespace Aviat\AnimeClient\Types; use LogicException; -class UndefinedPropertyException extends LogicException {} \ No newline at end of file +class UndefinedPropertyException extends LogicException +{ +} diff --git a/src/AnimeClient/Types/User.php b/src/AnimeClient/Types/User.php index e9a199a8..c348d3b1 100644 --- a/src/AnimeClient/Types/User.php +++ b/src/AnimeClient/Types/User.php @@ -19,22 +19,15 @@ namespace Aviat\AnimeClient\Types; /** * Type representing a Kitsu user for display */ -final class User extends AbstractType { +final class User extends AbstractType +{ public ?string $about; - public ?string $avatar; - public ?array $favorites; - public ?string $location; - public ?string $name; - public ?string $slug; - public ?array $stats; - public ?array $waifu; - public ?string $website; -} \ No newline at end of file +} diff --git a/src/AnimeClient/UrlGenerator.php b/src/AnimeClient/UrlGenerator.php index 019855b1..30dc6816 100644 --- a/src/AnimeClient/UrlGenerator.php +++ b/src/AnimeClient/UrlGenerator.php @@ -17,15 +17,14 @@ namespace Aviat\AnimeClient; use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; +use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use InvalidArgumentException; /** * UrlGenerator class. */ -class UrlGenerator extends RoutingBase { - +class UrlGenerator extends RoutingBase +{ /** * The current HTTP host */ @@ -64,7 +63,7 @@ class UrlGenerator extends RoutingBase { { $path = trim($path, '/'); - $path = preg_replace('`{/.*?}`i', '', $path) ?? ""; + $path = preg_replace('`{/.*?}`i', '', $path) ?? ''; // Remove any optional parameters from the route // and replace them with existing route parameters, if they exist @@ -110,4 +109,4 @@ class UrlGenerator extends RoutingBase { } } -// End of UrlGenerator.php \ No newline at end of file +// End of UrlGenerator.php diff --git a/src/AnimeClient/Util.php b/src/AnimeClient/Util.php index 6c3458e3..219e8bab 100644 --- a/src/AnimeClient/Util.php +++ b/src/AnimeClient/Util.php @@ -16,14 +16,14 @@ namespace Aviat\AnimeClient; -use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; +use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; /** * Utility method class */ -class Util { - +class Util +{ use ContainerAware; /** @@ -38,13 +38,11 @@ class Util { 'logout', 'details', 'character', - 'me' + 'me', ]; /** * Set up the Util class - * - * @param ContainerInterface $container */ public function __construct(ContainerInterface $container) { @@ -117,4 +115,3 @@ class Util { return ! $this->isViewPage(); } } - diff --git a/src/AnimeClient/constants.php b/src/AnimeClient/constants.php index c3888d77..95d2cdaf 100644 --- a/src/AnimeClient/constants.php +++ b/src/AnimeClient/constants.php @@ -94,7 +94,7 @@ const SETTINGS_MAP = [ 'options' => [ 'Memcached' => 'memcached', 'Redis' => 'redis', - 'No Cache' => 'null' + 'No Cache' => 'null', ], ], 'connection' => [ @@ -150,7 +150,7 @@ const SETTINGS_MAP = [ 'type' => 'string', 'title' => 'Timezone', 'default' => 'America/Detroit', - 'description' => 'See https://www.php.net/manual/en/timezones.php for options' + 'description' => 'See https://www.php.net/manual/en/timezones.php for options', ], 'theme' => [ 'type' => 'select', @@ -161,7 +161,7 @@ const SETTINGS_MAP = [ 'Automatically match OS theme' => 'auto', 'Original Light Theme' => 'light', 'Dark Theme' => 'dark', - ] + ], ], 'show_anime_collection' => [ 'type' => 'boolean', @@ -195,7 +195,7 @@ const SETTINGS_MAP = [ 'Dropped' => 'dropped', 'Completed' => 'completed', 'All' => 'all', - ] + ], ], 'default_manga_list_path' => [ //reading|plan_to_read|on_hold|dropped|completed|all 'type' => 'select', @@ -208,8 +208,8 @@ const SETTINGS_MAP = [ 'Dropped' => 'dropped', 'Completed' => 'completed', 'All' => 'all', - ] - ] + ], + ], ], 'database' => [ 'type' => [ @@ -236,7 +236,7 @@ const SETTINGS_MAP = [ 'pass' => [ 'type' => 'string', 'title' => 'Password', - 'description' => 'Database connection password' + 'description' => 'Database connection password', ], 'port' => [ 'type' => 'string', @@ -256,4 +256,4 @@ const SETTINGS_MAP = [ 'default' => 'anime_collection.sqlite', ], ], -]; \ No newline at end of file +]; diff --git a/src/Ion/Config.php b/src/Ion/Config.php index 9454c565..77f691c1 100644 --- a/src/Ion/Config.php +++ b/src/Ion/Config.php @@ -19,12 +19,13 @@ namespace Aviat\Ion; use Aviat\Ion\Exception\ConfigException; use Aviat\Ion\Type\ArrayType; use InvalidArgumentException; +use function is_array; /** * Wrapper for configuration values */ -class Config implements ConfigInterface { - +class Config implements ConfigInterface +{ /** * Config object */ @@ -49,12 +50,11 @@ class Config implements ConfigInterface { /** * Get a config value * - * @param array|string|null $key * @throws ConfigException */ public function get(array|string $key = NULL): mixed { - if (\is_array($key)) + if (is_array($key)) { return $this->map->getDeepKey($key); } @@ -67,7 +67,7 @@ class Config implements ConfigInterface { */ public function delete(array|string $key): void { - if (\is_array($key)) + if (is_array($key)) { $this->map->setDeepKey($key, NULL); } @@ -85,11 +85,11 @@ class Config implements ConfigInterface { */ public function set(array|int|string $key, mixed $value): ConfigInterface { - if (\is_array($key)) + if (is_array($key)) { $this->map->setDeepKey($key, $value); } - else if (is_scalar($key) && ! empty($key)) + elseif (is_scalar($key) && ! empty($key)) { $this->map->set($key, $value); } @@ -102,4 +102,4 @@ class Config implements ConfigInterface { } } -// End of config.php \ No newline at end of file +// End of config.php diff --git a/src/Ion/ConfigInterface.php b/src/Ion/ConfigInterface.php index e92fb656..3637b0bb 100644 --- a/src/Ion/ConfigInterface.php +++ b/src/Ion/ConfigInterface.php @@ -16,10 +16,13 @@ namespace Aviat\Ion; +use InvalidArgumentException; + /** * Standard interface for retrieving/setting configuration values */ -interface ConfigInterface { +interface ConfigInterface +{ /** * Does the config item exist? */ @@ -27,15 +30,13 @@ interface ConfigInterface { /** * Get a config value - * - * @param array|string|null $key */ public function get(array|string $key = NULL): mixed; /** * Set a config value * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function set(array|int|string $key, mixed $value): self; @@ -43,4 +44,4 @@ interface ConfigInterface { * Remove a config value */ public function delete(array|string $key): void; -} \ No newline at end of file +} diff --git a/src/Ion/Di/Container.php b/src/Ion/Di/Container.php index 8e91fc70..7d163747 100644 --- a/src/Ion/Di/Container.php +++ b/src/Ion/Di/Container.php @@ -22,8 +22,8 @@ use Psr\Log\LoggerInterface; /** * Dependency container */ -class Container implements ContainerInterface { - +class Container implements ContainerInterface +{ /** * Array of object instances */ @@ -42,8 +42,8 @@ class Container implements ContainerInterface { public function __construct(/** * Array of container Generator functions */ - protected array $container = []) - { + protected array $container = [] + ) { $this->loggers = []; } @@ -52,8 +52,8 @@ class Container implements ContainerInterface { * * @param string $id - Identifier of the entry to look for. * - * @throws NotFoundException - No entry was found for this identifier. * @throws ContainerException - Error while retrieving the entry. + * @throws NotFoundException - No entry was found for this identifier. * * @return mixed Entry. */ @@ -70,6 +70,7 @@ class Container implements ContainerInterface { // If there isn't already an instance, create one $obj = $this->getNew($id); $this->instances[$id] = $obj; + return $obj; } @@ -79,10 +80,10 @@ class Container implements ContainerInterface { /** * Get a new instance of the specified item * - * @param string $id - Identifier of the entry to look for. + * @param string $id - Identifier of the entry to look for. * @param array|null $args - Optional arguments for the factory callable - * @throws NotFoundException - No entry was found for this identifier. * @throws ContainerException - Error while retrieving the entry. + * @throws NotFoundException - No entry was found for this identifier. */ public function getNew(string $id, ?array $args = NULL): mixed { @@ -90,7 +91,7 @@ class Container implements ContainerInterface { { // By default, call a factory with the Container $args = \is_array($args) ? $args : [$this]; - $obj = \call_user_func_array($this->container[$id], $args); + $obj = ($this->container[$id])(...$args); // Check for container interface, and apply the container to the object // if applicable @@ -103,11 +104,12 @@ class Container implements ContainerInterface { /** * Add a factory to the container * - * @param Callable $value - a factory callable for the item + * @param callable $value - a factory callable for the item */ - public function set(string $id, Callable $value): ContainerInterface + public function set(string $id, callable $value): ContainerInterface { $this->container[$id] = $value; + return $this; } @@ -124,6 +126,7 @@ class Container implements ContainerInterface { } $this->instances[$id] = $value; + return $this; } @@ -141,7 +144,7 @@ class Container implements ContainerInterface { /** * Determine whether a logger channel is registered * - * @param string $id The logger channel + * @param string $id The logger channel */ public function hasLogger(string $id = 'default'): bool { @@ -151,18 +154,19 @@ class Container implements ContainerInterface { /** * Add a logger to the Container * - * @param string $id The logger 'channel' + * @param string $id The logger 'channel' */ public function setLogger(LoggerInterface $logger, string $id = 'default'): ContainerInterface { $this->loggers[$id] = $logger; + return $this; } /** * Retrieve a logger for the selected channel * - * @param string $id The logger to retrieve + * @param string $id The logger to retrieve */ public function getLogger(string $id = 'default'): ?LoggerInterface { @@ -198,4 +202,4 @@ class Container implements ContainerInterface { } } -// End of Container.php \ No newline at end of file +// End of Container.php diff --git a/src/Ion/Di/ContainerAware.php b/src/Ion/Di/ContainerAware.php index 7d96a149..78d547e6 100644 --- a/src/Ion/Di/ContainerAware.php +++ b/src/Ion/Di/ContainerAware.php @@ -19,8 +19,8 @@ namespace Aviat\Ion\Di; /** * Trait implementation of ContainerAwareInterface */ -trait ContainerAware { - +trait ContainerAware +{ /** * Di Container */ @@ -32,6 +32,7 @@ trait ContainerAware { public function setContainer(ContainerInterface $container): self { $this->container = $container; + return $this; } @@ -44,4 +45,4 @@ trait ContainerAware { } } -// End of ContainerAware.php \ No newline at end of file +// End of ContainerAware.php diff --git a/src/Ion/Di/ContainerAwareInterface.php b/src/Ion/Di/ContainerAwareInterface.php index 645e2096..e9ab33dc 100644 --- a/src/Ion/Di/ContainerAwareInterface.php +++ b/src/Ion/Di/ContainerAwareInterface.php @@ -19,8 +19,8 @@ namespace Aviat\Ion\Di; /** * Interface for a class that is aware of the Di Container */ -interface ContainerAwareInterface { - +interface ContainerAwareInterface +{ /** * Set the container for the current object * @@ -32,7 +32,6 @@ interface ContainerAwareInterface { * Get the container object */ public function getContainer(): ContainerInterface; - } -// End of ContainerAwareInterface.php \ No newline at end of file +// End of ContainerAwareInterface.php diff --git a/src/Ion/Di/ContainerInterface.php b/src/Ion/Di/ContainerInterface.php index 063e97b4..98385f72 100644 --- a/src/Ion/Di/ContainerInterface.php +++ b/src/Ion/Di/ContainerInterface.php @@ -26,13 +26,13 @@ use Psr\Log\LoggerInterface; * * @see https://github.com/container-interop/container-interop */ -interface ContainerInterface { - +interface ContainerInterface +{ /** * Finds an entry of the container by its identifier and returns it. * * @param string $id Identifier of the entry to look for. - * @throws Exception\NotFoundException No entry was found for this identifier. + * @throws Exception\NotFoundException No entry was found for this identifier. * @throws Exception\ContainerException Error while retrieving the entry. * @return mixed Entry. */ @@ -49,9 +49,9 @@ interface ContainerInterface { /** * Add a factory to the container * - * @param Callable $value - a factory callable for the item + * @param callable $value - a factory callable for the item */ - public function set(string $id, Callable $value): ContainerInterface; + public function set(string $id, callable $value): ContainerInterface; /** * Set a specific instance in the container for an existing factory @@ -66,21 +66,21 @@ interface ContainerInterface { /** * Determine whether a logger channel is registered * - * @param string $id The logger channel + * @param string $id The logger channel */ public function hasLogger(string $id = 'default'): bool; /** * Add a logger to the Container * - * @param string $id The logger 'channel' + * @param string $id The logger 'channel' */ public function setLogger(LoggerInterface $logger, string $id = 'default'): ContainerInterface; /** * Retrieve a logger for the selected channel * - * @param string $id The logger to retrieve + * @param string $id The logger to retrieve */ public function getLogger(string $id = 'default'): ?LoggerInterface; -} \ No newline at end of file +} diff --git a/src/Ion/Di/Exception/ContainerException.php b/src/Ion/Di/Exception/ContainerException.php index d10e5ce8..a563dceb 100644 --- a/src/Ion/Di/Exception/ContainerException.php +++ b/src/Ion/Di/Exception/ContainerException.php @@ -21,8 +21,8 @@ use Exception; /** * Generic exception for Di Container */ -class ContainerException extends Exception { - +class ContainerException extends Exception +{ } -// End of ContainerException.php \ No newline at end of file +// End of ContainerException.php diff --git a/src/Ion/Di/Exception/NotFoundException.php b/src/Ion/Di/Exception/NotFoundException.php index 8a09fe4a..3f46b54f 100644 --- a/src/Ion/Di/Exception/NotFoundException.php +++ b/src/Ion/Di/Exception/NotFoundException.php @@ -20,8 +20,8 @@ namespace Aviat\Ion\Di\Exception; * Exception for Di Container when trying to access a * key that doesn't exist in the container */ -class NotFoundException extends ContainerException { - +class NotFoundException extends ContainerException +{ } -// End of NotFoundException.php \ No newline at end of file +// End of NotFoundException.php diff --git a/src/Ion/Enum.php b/src/Ion/Enum.php index 64915157..f2c405d1 100644 --- a/src/Ion/Enum.php +++ b/src/Ion/Enum.php @@ -22,8 +22,8 @@ use ReflectionException; /** * Class emulating an enumeration type */ -abstract class Enum { - +abstract class Enum +{ /** * Return the list of constant values for the Enum * @@ -36,10 +36,11 @@ abstract class Enum { if ($self === NULL) { $class = static::class; - $self = new $class; + $self = new $class(); } $reflect = new ReflectionClass($self); + return $reflect->getConstants(); } @@ -51,8 +52,9 @@ abstract class Enum { public static function isValid(mixed $key): bool { $values = array_values(static::getConstList()); + return in_array($key, $values, TRUE); } } -// End of Enum.php \ No newline at end of file +// End of Enum.php diff --git a/src/Ion/Event.php b/src/Ion/Event.php index be9d2588..6254a069 100644 --- a/src/Ion/Event.php +++ b/src/Ion/Event.php @@ -19,7 +19,8 @@ namespace Aviat\Ion; /** * A basic event handler */ -class Event { +class Event +{ private static array $eventMap = []; /** @@ -46,4 +47,4 @@ class Event { array_walk(static::$eventMap[$eventName], static fn ($fn) => $fn(...$args)); } } -} \ No newline at end of file +} diff --git a/src/Ion/Exception/ConfigException.php b/src/Ion/Exception/ConfigException.php index ea95aa23..0020e37b 100644 --- a/src/Ion/Exception/ConfigException.php +++ b/src/Ion/Exception/ConfigException.php @@ -21,6 +21,6 @@ use InvalidArgumentException; /** * Exception for bad configuration */ -class ConfigException extends InvalidArgumentException { - -} \ No newline at end of file +class ConfigException extends InvalidArgumentException +{ +} diff --git a/src/Ion/Exception/DoubleRenderException.php b/src/Ion/Exception/DoubleRenderException.php index 77356107..5b03cf25 100644 --- a/src/Ion/Exception/DoubleRenderException.php +++ b/src/Ion/Exception/DoubleRenderException.php @@ -22,15 +22,13 @@ use LogicException; /** * Exception called when a view is attempted to be sent twice */ -class DoubleRenderException extends LogicException { - +class DoubleRenderException extends LogicException +{ /** * DoubleRenderException constructor. - * - * @param Exception|null $previous */ - public function __construct(string $message = 'A view can only be rendered once, because headers can only be sent once.', int $code = 0, Exception $previous = NULL) + public function __construct(string $message = 'A view can only be rendered once, because headers can only be sent once.', int $code = 0, ?Exception $previous = NULL) { parent::__construct($message, $code, $previous); } -} \ No newline at end of file +} diff --git a/src/Ion/Exception/ImageCreationException.php b/src/Ion/Exception/ImageCreationException.php index 490d05bd..af93285c 100644 --- a/src/Ion/Exception/ImageCreationException.php +++ b/src/Ion/Exception/ImageCreationException.php @@ -21,6 +21,6 @@ use RuntimeException; /** * Exception for bad configuration */ -class ImageCreationException extends RuntimeException { - -} \ No newline at end of file +class ImageCreationException extends RuntimeException +{ +} diff --git a/src/Ion/Friend.php b/src/Ion/Friend.php index 5ac8784f..ab6ae287 100644 --- a/src/Ion/Friend.php +++ b/src/Ion/Friend.php @@ -19,14 +19,16 @@ namespace Aviat\Ion; use BadMethodCallException; use InvalidArgumentException; use ReflectionClass; +use ReflectionException; use ReflectionMethod; use ReflectionProperty; +use function is_object; /** * Friend class for testing */ -class Friend { - +class Friend +{ /** * Object to create a friend of */ @@ -41,11 +43,11 @@ class Friend { * Create a friend object * * @throws InvalidArgumentException - * @throws \ReflectionException + * @throws ReflectionException */ public function __construct(mixed $obj) { - if ( ! \is_object($obj)) + if ( ! is_object($obj)) { throw new InvalidArgumentException('Friend must be an object'); } @@ -101,9 +103,9 @@ class Friend { /** * Calls a protected or private method on the friend * - * @return mixed * @throws BadMethodCallException - * @throws \ReflectionException + * @throws ReflectionException + * @return mixed */ public function __call(string $method, array $args) { @@ -114,6 +116,7 @@ class Friend { $friendMethod = new ReflectionMethod($this->_friend_, $method); $friendMethod->setAccessible(TRUE); + return $friendMethod->invokeArgs($this->_friend_, $args); } @@ -126,6 +129,7 @@ class Friend { { $property = $this->_reflect_->getProperty($name); $property->setAccessible(TRUE); + return $property; } // Return NULL on any exception, so no further logic needed @@ -140,4 +144,4 @@ class Friend { } } -// End of Friend.php \ No newline at end of file +// End of Friend.php diff --git a/src/Ion/HttpViewInterface.php b/src/Ion/HttpViewInterface.php index b7c4b2ab..a4198d42 100644 --- a/src/Ion/HttpViewInterface.php +++ b/src/Ion/HttpViewInterface.php @@ -16,15 +16,17 @@ namespace Aviat\Ion; +use InvalidArgumentException; + /** * View Interface abstracting an HTTP Response */ -interface HttpViewInterface extends ViewInterface { - +interface HttpViewInterface extends ViewInterface +{ /** * Set the status code of the request * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function setStatusCode(int $code): self; -} \ No newline at end of file +} diff --git a/src/Ion/ImageBuilder.php b/src/Ion/ImageBuilder.php index 86021d8c..7d2dc847 100644 --- a/src/Ion/ImageBuilder.php +++ b/src/Ion/ImageBuilder.php @@ -16,21 +16,21 @@ namespace Aviat\Ion; -use GdImage; - use Aviat\Ion\Exception\ImageCreationException; +use GdImage; + /** * A wrapper around GD functions to create images * - * @property GdImage|false|null $img + * @property false|GdImage|null $img */ -class ImageBuilder { - private GDImage|false|null $_img; - +class ImageBuilder +{ + private GDImage|FALSE|NULL $_img; private int $fontSize = 10; - private function __construct(private int $width=200, private int $height=200 ) + private function __construct(private int $width = 200, private int $height = 200) { $this->_img = imagecreatetruecolor($this->width, $this->height); } @@ -50,7 +50,7 @@ class ImageBuilder { throw new ImageCreationException('Invalid GD object'); } - public static function new(int $width=200, int $height=200): self + public static function new(int $width = 200, int $height = 200): self { $i = new self($width, $height); if ($i->_img === FALSE) @@ -79,7 +79,7 @@ class ImageBuilder { return $this; } - public function addCenteredText(string $text, int $red, int $green, int $blue, int $alpha=-1): self + public function addCenteredText(string $text, int $red, int $green, int $blue, int $alpha = -1): self { // Create the font color $textColor = ($alpha > -1) @@ -104,7 +104,7 @@ class ImageBuilder { return $this; } - public function addBackgroundColor(int $red, int $green, int $blue, int $alpha=-1): self + public function addBackgroundColor(int $red, int $green, int $blue, int $alpha = -1): self { $fillColor = ($alpha > -1) ? imagecolorallocatealpha($this->getImg(), $red, $green, $blue, $alpha) diff --git a/src/Ion/Json.php b/src/Ion/Json.php index 3c2fcf69..88fde49a 100644 --- a/src/Ion/Json.php +++ b/src/Ion/Json.php @@ -17,12 +17,13 @@ namespace Aviat\Ion; use Aviat\Ion\Type\StringType; +use InvalidArgumentException; /** * Helper class for json convenience methods */ -class Json { - +class Json +{ /** * Encode data in json format * @@ -39,8 +40,8 @@ class Json { /** * Encode data in json format and save to a file * - * @param int $jsonOptions - Options to pass to json_encode - * @param int $fileOptions - Options to pass to file_get_contents + * @param int $jsonOptions - Options to pass to json_encode + * @param int $fileOptions - Options to pass to file_get_contents * @throws JsonException */ public static function encodeFile(string $filename, mixed $data, int $jsonOptions = 0, int $fileOptions = 0): bool @@ -48,6 +49,7 @@ class Json { $json = self::encode($data, $jsonOptions); $res = file_put_contents($filename, $json, $fileOptions); + return $res !== FALSE; } @@ -67,6 +69,7 @@ class Json { $data = json_decode($json, $assoc, $depth, $options); self::check_json_error(); + return $data; } @@ -86,7 +89,7 @@ class Json { /** * Determines whether a string is valid json * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public static function isJson(string $string): bool { @@ -109,7 +112,7 @@ class Json { JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8', JSON_ERROR_RECURSION => 'JSON_ERROR_RECURSION', JSON_ERROR_INF_OR_NAN => 'JSON_ERROR_INF_OR_NAN', - JSON_ERROR_UNSUPPORTED_TYPE => 'JSON_ERROR_UNSUPPORTED_TYPE' + JSON_ERROR_UNSUPPORTED_TYPE => 'JSON_ERROR_UNSUPPORTED_TYPE', ]; $error = json_last_error(); @@ -122,4 +125,4 @@ class Json { } } -// End of JSON.php \ No newline at end of file +// End of JSON.php diff --git a/src/Ion/JsonException.php b/src/Ion/JsonException.php index 4f9df4cd..75f35b57 100644 --- a/src/Ion/JsonException.php +++ b/src/Ion/JsonException.php @@ -21,8 +21,8 @@ use InvalidArgumentException; /** * Exceptions thrown by the Json class */ -class JsonException extends InvalidArgumentException { - +class JsonException extends InvalidArgumentException +{ } -// End of JsonException.php \ No newline at end of file +// End of JsonException.php diff --git a/src/Ion/Model.php b/src/Ion/Model.php index 75e5cef9..54b3308b 100644 --- a/src/Ion/Model.php +++ b/src/Ion/Model.php @@ -19,7 +19,8 @@ namespace Aviat\Ion; /** * Common base for all Models */ -class Model { +class Model +{ } // End of Model.php diff --git a/src/Ion/Transformer/AbstractTransformer.php b/src/Ion/Transformer/AbstractTransformer.php index 48d490a0..c3d224f6 100644 --- a/src/Ion/Transformer/AbstractTransformer.php +++ b/src/Ion/Transformer/AbstractTransformer.php @@ -21,7 +21,8 @@ use BadMethodCallException; /** * Base class for data transformation */ -abstract class AbstractTransformer implements TransformerInterface { +abstract class AbstractTransformer implements TransformerInterface +{ /** * Mutate the data structure */ @@ -32,7 +33,8 @@ abstract class AbstractTransformer implements TransformerInterface { */ public function transformCollection(iterable $collection): array { - $list = (array)$collection; + $list = (array) $collection; + return array_map([$this, 'transform'], $list); } @@ -40,8 +42,6 @@ abstract class AbstractTransformer implements TransformerInterface { * Untransform a set of structures * * Requires an 'untransform' method in the extending class - * - * @param iterable $collection */ public function untransformCollection(iterable $collection): array { @@ -50,9 +50,10 @@ abstract class AbstractTransformer implements TransformerInterface { throw new BadMethodCallException('untransform() method does not exist.'); } - $list = (array)$collection; + $list = (array) $collection; + return array_map([$this, 'untransform'], $list); } } -// End of AbstractTransformer.php \ No newline at end of file +// End of AbstractTransformer.php diff --git a/src/Ion/Transformer/TransformerInterface.php b/src/Ion/Transformer/TransformerInterface.php index 47d022ec..4cfe5ed6 100644 --- a/src/Ion/Transformer/TransformerInterface.php +++ b/src/Ion/Transformer/TransformerInterface.php @@ -19,10 +19,10 @@ namespace Aviat\Ion\Transformer; /** * Interface for data transformation classes */ -interface TransformerInterface { - +interface TransformerInterface +{ /** * Mutate the data structure */ public function transform(array|object $item): mixed; -} \ No newline at end of file +} diff --git a/src/Ion/Type/ArrayType.php b/src/Ion/Type/ArrayType.php index ce36f4d1..8688ddb6 100644 --- a/src/Ion/Type/ArrayType.php +++ b/src/Ion/Type/ArrayType.php @@ -17,16 +17,17 @@ namespace Aviat\Ion\Type; use InvalidArgumentException; +use function in_array; /** * Wrapper class for native array methods for convenience * * @method array chunk(int $size, bool $preserve_keys = FALSE) - * @method array pluck(mixed $column_key, mixed $index_key = NULL) * @method array filter(callable $callback = NULL, int $flag = 0) + * @method array pluck(mixed $column_key, mixed $index_key = NULL) */ -class ArrayType { - +class ArrayType +{ /** * The current array */ @@ -102,6 +103,7 @@ class ArrayType { { $func = $this->nativeInPlaceMethods[$method]; $func($this->arr); + return $this->arr; } @@ -117,7 +119,7 @@ class ArrayType { { $pos =& $this->arr; - foreach($key as $level) + foreach ($key as $level) { if ( ! array_key_exists($level, $pos)) { @@ -156,7 +158,7 @@ class ArrayType { /** * Find an array key by its associated value */ - public function search(mixed $value, bool $strict = TRUE): int|string|false|null + public function search(mixed $value, bool $strict = TRUE): int|string|FALSE|null { return array_search($value, $this->arr, $strict); } @@ -166,13 +168,13 @@ class ArrayType { */ public function has(mixed $value, bool $strict = TRUE): bool { - return \in_array($value, $this->arr, $strict); + return in_array($value, $this->arr, $strict); } /** * Return the array, or a key */ - public function &get(string|int|null $key = NULL): mixed + public function &get(string|int|NULL $key = NULL): mixed { $value = NULL; if ($key === NULL) @@ -196,6 +198,7 @@ class ArrayType { public function set(mixed $key, mixed $value): ArrayType { $this->arr[$key] = $value; + return $this; } @@ -205,7 +208,7 @@ class ArrayType { * @example $arr = ArrayType::from([0 => ['data' => ['foo' => 'bar']]]); * $val = $arr->getDeepKey([0, 'data', 'foo']); * // returns 'bar' - * @param array $key An array of keys of the array + * @param array $key An array of keys of the array */ public function &getDeepKey(array $key): mixed { @@ -220,6 +223,7 @@ class ArrayType { // excess code, just what's required for this // unique situation. $pos = NULL; + return $pos; } @@ -258,4 +262,4 @@ class ArrayType { } } -// End of ArrayType.php \ No newline at end of file +// End of ArrayType.php diff --git a/src/Ion/Type/StringType.php b/src/Ion/Type/StringType.php index a305101b..581bf40c 100644 --- a/src/Ion/Type/StringType.php +++ b/src/Ion/Type/StringType.php @@ -16,13 +16,14 @@ namespace Aviat\Ion\Type; +use InvalidArgumentException; use Stringy\Stringy; /** * Wrapper around Stringy */ -class StringType extends Stringy { - +class StringType extends Stringy +{ /** * Alias for `create` static constructor */ @@ -35,15 +36,15 @@ class StringType extends Stringy { * See if two strings match, despite being delimited differently, * such as camelCase, PascalCase, kebab-case, or snake_case. * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function fuzzyCaseMatch(string $strToMatch): bool { - $firstStr = (string)self::create($this->str)->dasherize(); - $secondStr = (string)self::create($strToMatch)->dasherize(); + $firstStr = (string) self::create($this->str)->dasherize(); + $secondStr = (string) self::create($strToMatch)->dasherize(); return $firstStr === $secondStr; } } -// End of StringType.php \ No newline at end of file +// End of StringType.php diff --git a/src/Ion/View/HtmlView.php b/src/Ion/View/HtmlView.php index 77b42292..ac3d9f1a 100644 --- a/src/Ion/View/HtmlView.php +++ b/src/Ion/View/HtmlView.php @@ -16,15 +16,16 @@ namespace Aviat\Ion\View; -use Aviat\Ion\Di\ContainerAware; -use Aviat\Ion\Di\ContainerInterface; +use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; use Laminas\Diactoros\Response\HtmlResponse; +use Throwable; use const EXTR_OVERWRITE; /** * View class for outputting HTML */ -class HtmlView extends HttpView { +class HtmlView extends HttpView +{ use ContainerAware; /** @@ -46,7 +47,7 @@ class HtmlView extends HttpView { /** * Render a basic html Template * - * @throws \Throwable + * @throws Throwable */ public function renderTemplate(string $path, array $data): string { @@ -62,10 +63,9 @@ class HtmlView extends HttpView { $rawBuffer = ob_get_clean(); $buffer = ($rawBuffer === FALSE) ? '' : $rawBuffer; - // Very basic html minify, that won't affect content between html tags return preg_replace('/>\s+ <', $buffer) ?? $buffer; } } -// End of HtmlView.php \ No newline at end of file +// End of HtmlView.php diff --git a/src/Ion/View/HttpView.php b/src/Ion/View/HttpView.php index a3a16dab..16da2005 100644 --- a/src/Ion/View/HttpView.php +++ b/src/Ion/View/HttpView.php @@ -16,18 +16,20 @@ namespace Aviat\Ion\View; +use Aviat\Ion\Exception\DoubleRenderException; use Aviat\Ion\HttpViewInterface; +use InvalidArgumentException; + use Laminas\Diactoros\Response; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; - -use Aviat\Ion\Exception\DoubleRenderException; use Psr\Http\Message\ResponseInterface; +use Stringable; /** * Base view class for Http output */ -class HttpView implements HttpViewInterface, \Stringable{ - +class HttpView implements HttpViewInterface, Stringable +{ /** * HTTP response Object */ @@ -77,6 +79,7 @@ class HttpView implements HttpViewInterface, \Stringable{ } $this->hasRendered = TRUE; + return $this->getOutput(); } @@ -88,6 +91,7 @@ class HttpView implements HttpViewInterface, \Stringable{ public function addHeader(string $name, array|string $value): self { $this->response = $this->response->withHeader($name, $value); + return $this; } @@ -98,7 +102,6 @@ class HttpView implements HttpViewInterface, \Stringable{ { $this->response->getBody()->write($string); - return $this; } @@ -116,29 +119,31 @@ class HttpView implements HttpViewInterface, \Stringable{ */ public function getOutput(): string { - return (string)$this->response->getBody(); + return (string) $this->response->getBody(); } /** * Do a redirect * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function redirect(string $url, int $code = 302, array $headers = []): self { $this->response = new Response\RedirectResponse($url, $code, $headers); + return $this; } /** * Set the status code of the request * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function setStatusCode(int $code): self { $this->response = $this->response->withStatus($code) ->withProtocolVersion('1.1'); + return $this; } @@ -147,7 +152,7 @@ class HttpView implements HttpViewInterface, \Stringable{ * any attempt to call again will result in a DoubleRenderException. * * @throws DoubleRenderException - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function send(): void { @@ -159,7 +164,7 @@ class HttpView implements HttpViewInterface, \Stringable{ * * @codeCoverageIgnore * @throws DoubleRenderException - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ protected function output(): void { @@ -178,4 +183,4 @@ class HttpView implements HttpViewInterface, \Stringable{ $this->hasRendered = TRUE; } -} \ No newline at end of file +} diff --git a/src/Ion/View/JsonView.php b/src/Ion/View/JsonView.php index a88b3ab5..279ff518 100644 --- a/src/Ion/View/JsonView.php +++ b/src/Ion/View/JsonView.php @@ -16,14 +16,13 @@ namespace Aviat\Ion\View; -use Aviat\Ion\Json; -use Aviat\Ion\HttpViewInterface; +use Aviat\Ion\{HttpViewInterface, Json}; /** * View class to serialize Json */ -class JsonView extends HttpView { - +class JsonView extends HttpView +{ /** * Response mime type */ @@ -43,4 +42,4 @@ class JsonView extends HttpView { } } -// End of JsonView.php \ No newline at end of file +// End of JsonView.php diff --git a/src/Ion/ViewInterface.php b/src/Ion/ViewInterface.php index e584048f..5f3214ba 100644 --- a/src/Ion/ViewInterface.php +++ b/src/Ion/ViewInterface.php @@ -21,7 +21,8 @@ use Aviat\Ion\Exception\DoubleRenderException; /** * View Interface abstracting a Response */ -interface ViewInterface { +interface ViewInterface +{ /** * Return rendered output as string. Renders the view, * and any attempts to call again will result in a DoubleRenderException @@ -60,4 +61,4 @@ interface ViewInterface { * @throws DoubleRenderException */ public function send(): void; -} \ No newline at end of file +} diff --git a/src/Ion/functions.php b/src/Ion/functions.php index e5cbb0fb..4bb85b7c 100644 --- a/src/Ion/functions.php +++ b/src/Ion/functions.php @@ -23,4 +23,4 @@ namespace Aviat\Ion; function _dir(string ...$args): string { return implode(DIRECTORY_SEPARATOR, $args); -} \ No newline at end of file +} diff --git a/tools/rector.php b/tools/rector.php index 09a55ec9..26a91001 100644 --- a/tools/rector.php +++ b/tools/rector.php @@ -28,6 +28,7 @@ use Rector\Doctrine\Set\DoctrineSetList; use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector; use Rector\EarlyReturn\Rector\If_\ChangeIfElseValueAssignToEarlyReturnRector; use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector; +use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector; use Rector\Php81\Rector\Property\ReadOnlyPropertyRector; use Rector\Restoration\Rector\Property\MakeTypedPropertyNullableIfCheckedRector; use Rector\Set\ValueObject\LevelSetList; @@ -56,6 +57,7 @@ return static function (ContainerConfigurator $config): void { $parameters->set(Option::IMPORT_SHORT_CLASSES, false); $parameters->set(Option::SKIP, [ ReadOnlyPropertyRector::class, + RestoreDefaultNullToNullableTypePropertyRector::class, ]); walk_array([$config, 'import'], [ @@ -79,7 +81,7 @@ return static function (ContainerConfigurator $config): void { ForRepeatedCountToOwnVariableRector::class, ForToForeachRector::class, // MakeTypedPropertyNullableIfCheckedRector::class, - NewlineAfterStatementRector::class, + // NewlineAfterStatementRector::class, NewlineBeforeNewAssignSetRector::class, ParamTypeByMethodCallTypeRector::class, ParamTypeByParentCallTypeRector::class,