From 3d34db3827479bfbd7b8ff25f2190f0d02b65ebe Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 17 Oct 2025 15:57:49 +0200 Subject: [PATCH 01/22] Fixed #197 --- .../General/UserManagement/GetUsers/OutOfOffice.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php index 802e4cf8..2a5a356f 100644 --- a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php +++ b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php @@ -12,12 +12,16 @@ public static function fromJson(array $data): self { if ($startDateTime = Arr::get($data, 'StartDateTime')) { $startDateTime = Str::of($startDateTime)->after('(')->before(')'); - $startDateTime = Carbon::createFromTimestamp($startDateTime); + // Extract milliseconds part (ignore optional timezone offset like +0000) + $milliseconds = (int) (string) $startDateTime; + $startDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); } if ($endDateTime = Arr::get($data, 'EndDateTime')) { $endDateTime = Str::of($endDateTime)->after('(')->before(')'); - $endDateTime = Carbon::createFromTimestamp($endDateTime); + // Extract milliseconds part (ignore optional timezone offset like +0000) + $milliseconds = (int) (string) $endDateTime; + $endDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); } return new self( @@ -25,7 +29,7 @@ public static function fromJson(array $data): self startDateTime: $startDateTime, startDateTimeSpecified: Arr::get($data, 'StartDateTimeSpecified'), endDateTime: $endDateTime, - endDateTimeSpecified: Arr::get($data, 'EndDateTimeSpecified'), + endDateTimeSpecified: Arr::get($data, key: 'EndDateTimeSpecified'), ); } From 6087c046c1bf7ea2b798d7ebe97dbe11b8878ffe Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 17 Oct 2025 16:02:52 +0200 Subject: [PATCH 02/22] Resolved #189, updated Docs and Tests for Enums --- .phpunit.cache/test-results | 2 +- README.md | 46 ++++++++++++++ src/Enums/DocuWareFieldTypeEnum.php | 13 ++++ tests/Unit/Enums/ConnectionEnumTest.php | 37 +++++++++++ tests/Unit/Enums/DialogTypeTest.php | 46 ++++++++++++++ .../Unit/Enums/DocuWareFieldTypeEnumTest.php | 61 +++++++++++++++++++ 6 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/Enums/DocuWareFieldTypeEnum.php create mode 100644 tests/Unit/Enums/ConnectionEnumTest.php create mode 100644 tests/Unit/Enums/DialogTypeTest.php create mode 100644 tests/Unit/Enums/DocuWareFieldTypeEnumTest.php diff --git a/.phpunit.cache/test-results b/.phpunit.cache/test-results index 865937dc..7c94d9dd 100644 --- a/.phpunit.cache/test-results +++ b/.phpunit.cache/test-results @@ -1 +1 @@ -{"version":"pest_3.8.2","defects":{"P\\Tests\\Feature\\Requests\\Workflow\\GetDocumentWorkflowHistoryTest::__pest_evaluable_it_can_get_document_workflow_history":1,"P\\Tests\\Feature\\SleepTest::__pest_evaluable_sleep":1,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_uses_CACHE__STORE_in_Laravel_12":8,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_uses_DOCUWARE__CACHE__DRIVER_when_explicitly_set":7,"P\\Tests\\Feature\\Requests\\Workflow\\GetDocumentWorkflowHistoryStepsTest::__pest_evaluable_it_can_get_document_workflow_history":1,"P\\Tests\\Feature\\Requests\\FileCabinets\\Upload\\AppendFilesToADataRecordTest::__pest_evaluable_it_can_attach_files_to_a_data_record":1,"Tests\\Unit\\DTO\\TextshotPageTest::test_it_can_create_textshot_page_with_null_language":7,"Tests\\Unit\\DTO\\TextshotPageTest::test_it_can_create_textshot_page_with_string_language":7,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_uses_default_file_driver_when_no_configuration_is_set":8,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_respects_the_new_CACHE__STORE_fallback_chain":8,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_environment_variable_fallback_chain_works_correctly":7,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_CACHE__STORE_takes_precedence_over_CACHE__DRIVER_when_DOCUWARE__CACHE__DRIVER_is_not_set":7,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_can_be_overridden":8,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_fallback_chain_is_properly_configured":8},"times":{"P\\Tests\\Feature\\Requests\\Documents\\Sections\\GetTextshotTest::__pest_evaluable_it_get_textshot_for_a_specific_section":1.669,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\DeleteDocumentsFromTrashBinTest::__pest_evaluable_it_can_delete_documents_in_trash":1.262,"P\\Tests\\Feature\\Requests\\Documents\\Sections\\GetAllSectionsFromADocumentTest::__pest_evaluable_it_can_get_all_sections_from_a_document":1.1,"P\\Tests\\Feature\\Requests\\Documents\\ClipUnclipStapleUnstaple\\UnstapleTest::__pest_evaluable_it_can_unstaple_a_document":13.455,"P\\Tests\\Feature\\Requests\\Documents\\ApplicationProperties\\ApplicationPropertiesTest::__pest_evaluable_it_can_add_get_update_delete_application_properties_to_a_document":1.042,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetUsers\\GetUsersTest::__pest_evaluable_it_can_list_users":0.746,"P\\Tests\\Feature\\Requests\\Organization\\GetOrganizationsRequestTest::__pest_evaluable_it_can_list_organizations":0.504,"P\\Tests\\Feature\\Requests\\Fields\\GetFieldsRequestTest::__pest_evaluable_it_can_list_fields_for_a_file_cabinet":0.53,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_override_search_documents_dates_filter_by_using_equal_operator":0.766,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_search_documents_dates_filter_in_past":0.661,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_search_documents":0.58,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_search_documents_with_multiple_values":1.078,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_search_documents_with_null_values":0.495,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_override_search_documents_dates_filter_by_using_same_operator":0.617,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_t_search_documents_by_more_than_two_dates":0.371,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_search_documents_dates_filter_in_future":0.645,"P\\Tests\\Feature\\Requests\\Search\\GetSearchRequestTest::__pest_evaluable_it_can_t_search_documents_by_diverged_date_range":0.364,"P\\Tests\\Feature\\DocuWareTest::__pest_evaluable_it_can_create_encrypted_url_for_a_document_in_a_file_cabinet":0.424,"P\\Tests\\Feature\\DocuWareTest::__pest_evaluable_it_can_create_encrypted_url_for_a_document_in_a_basket":0.369,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyGroups\\GetAllGroupsForASpecificUserTest::__pest_evaluable_it_can_list_groups_for_a_specific_user":0.884,"P\\Tests\\Feature\\Requests\\FileCabinets\\Dialogs\\GetASpecificDialogTest::__pest_evaluable_it_can_get_a_dialog":0.555,"P\\Tests\\Feature\\Requests\\FileCabinets\\General\\GetFileCabinetInformationTest::__pest_evaluable_it_can_get_file_cabinet_information":0.63,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_organization_index":0.395,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_document":0.351,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_dialog":0.405,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_file_cabinet":0.352,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_field":0.336,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_document_field":0.34,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_table_row":0.352,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_suggestion_field":0.361,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_document_paginator":0.361,"P\\Tests\\Feature\\DTOTest::__pest_evaluable_it_create_a_fake_organization":0.346,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexDateDTOTest::__pest_evaluable_it_create_index_date_dto":0.002,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyRoles\\GetRolesTest::__pest_evaluable_it_can_list_groups":0.494,"P\\Tests\\Feature\\Requests\\FileCabinets\\Search\\GetASpecificDocumentFromAFileCabinetTest::__pest_evaluable_it_can_show_a_document":0.666,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\RestoreDocumentsFromTrashBinTest::__pest_evaluable_it_can_restore_documents_in_trash":1.184,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_search_documents_dates_filter_in_past_in_trash":0.518,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_t_search_documents_by_more_than_two_dates_in_trash":0.331,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_override_search_documents_dates_filter_by_using_same_operator_in_trash":0.565,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_override_search_documents_dates_filter_by_using_equal_operator_in_trash":0.56,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_search_documents_in_trash":0.532,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_search_documents_with_null_values_in_trash":0.568,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_t_search_documents_by_diverged_date_range":0.364,"P\\Tests\\Feature\\Requests\\Documents\\DocumentsTrashBin\\GetDocumentsFromTrashBinTest::__pest_evaluable_it_can_search_documents_dates_filter_in_future_in_trash":0.51,"P\\Tests\\Feature\\Requests\\FileCabinets\\Upload\\ReplaceAPDFDocumentSectionTest::__pest_evaluable_it_can_replace_a_pdf_document_section":1.084,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexKeywordDTOTest::__pest_evaluable_it_create_prepare_index_keyword_dto":0.001,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetUsers\\GetUsersOfARoleTest::__pest_evaluable_it_can_list_users_of_a_role":0.649,"P\\Tests\\Feature\\DocuWareAuthenticationTest::__pest_evaluable_it_can_get_oath_responsible_identity_service":0.497,"P\\Tests\\Feature\\DocuWareAuthenticationTest::__pest_evaluable_it_throws_an_error_if_credentials_are_wrong":0.839,"P\\Tests\\Feature\\DocuWareAuthenticationTest::__pest_evaluable_it_can_authenticate_with_DocuWare_Credentials":0.48,"P\\Tests\\Feature\\DocuWareAuthenticationTest::__pest_evaluable_it_can_get_oath_identity_service_configuration":0.701,"P\\Tests\\Unit\\DTO\\DocumentIndex\\PrepareDTOTest::__pest_evaluable_it_create_prepare_makeContent_dto":0,"P\\Tests\\Feature\\Requests\\Documents\\Download\\DownloadThumbnailTest::__pest_evaluable_it_can_download_a_thumbnail":0.814,"P\\Tests\\Feature\\Requests\\Documents\\ClipUnclipStapleUnstaple\\StapleTest::__pest_evaluable_it_can_staple_2_documents":12.323,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexDecimalDTOTest::__pest_evaluable_it_create_index_numeric_dto":0.001,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetUsers\\GetUserByIdTest::__pest_evaluable_it_can_get_user_by_id":0.763,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyGroups\\GetGroupsTest::__pest_evaluable_it_can_list_groups":0.548,"P\\Tests\\Feature\\Requests\\Workflow\\GetDocumentWorkflowHistoryTest::__pest_evaluable_it_can_get_document_workflow_history":0.359,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyGroups\\AddRemoveUserToAGroupTest::__pest_evaluable_it_can_add_groups_to_a_user":7.947,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyGroups\\AddRemoveUserToAGroupTest::__pest_evaluable_it_can_remove_groups_to_a_user":5.958,"P\\Tests\\Feature\\Requests\\Documents\\PostDocumentRequestTest::__pest_evaluable_it_can_upload_document_without_file_name_and_file_content_and_delete_it":0.565,"P\\Tests\\Feature\\Requests\\Documents\\PostDocumentRequestTest::__pest_evaluable_it_can_upload_document_with_index_values_and_delete_it":0.633,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexDateTimeDTOTest::__pest_evaluable_it_create_index_date_time_dto":0.001,"P\\Tests\\Core\\ArchTest::__pest_evaluable_it_will_not_use_any_debug_function":0.231,"P\\Tests\\Feature\\Requests\\Documents\\GetDocumentPreviewRequestTest::__pest_evaluable_it_can_preview_a_document_image":0.941,"P\\Tests\\Feature\\Requests\\Documents\\PutDocumentFieldsRequestTest::__pest_evaluable_it_can_update_a_document_value":0.679,"P\\Tests\\Feature\\Requests\\Documents\\PutDocumentFieldsRequestTest::__pest_evaluable_it_can_update_multiple_document_values":0.803,"P\\Tests\\Feature\\SleepTest::__pest_evaluable_sleep":0.339,"P\\Tests\\Feature\\Requests\\Documents\\ClipUnclipStapleUnstaple\\ClipTest::__pest_evaluable_it_can_clip_2_documents":6.624,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_uses_CACHE__STORE_in_Laravel_12":0.003,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_falls_back_to_CACHE__DRIVER_when_CACHE__STORE_is_not_set":0.425,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_uses_DOCUWARE__CACHE__DRIVER_when_explicitly_set":0.876,"P\\Tests\\Feature\\Requests\\Documents\\Download\\DownloadDocumentTest::__pest_evaluable_it_can_download_a_document":0.705,"P\\Tests\\Feature\\Requests\\FileCabinets\\Upload\\AppendASinglePDFToADocumentTest::__pest_evaluable_it_can_replace_a_pdf_document_section":0.87,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\CreateUpdateUsers\\CreateUpdateUserTest::__pest_evaluable_it_can_create_users":1.781,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\CreateUpdateUsers\\CreateUpdateUserTest::__pest_evaluable_it_can_update_users":6.156,"P\\Tests\\Feature\\Requests\\FileCabinets\\Dialogs\\GetDialogsOfASpecificTypeTest::__pest_evaluable_it_can_list_dialogs_for_a_file_cabinet":0.523,"P\\Tests\\Feature\\Requests\\Documents\\ClipUnclipStapleUnstaple\\UnclipTest::__pest_evaluable_it_can_unclip_2_documents":12.165,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetUsers\\GetUsersOfAGroupTest::__pest_evaluable_it_can_list_users_of_a_group":0.729,"P\\Tests\\Feature\\Requests\\Workflow\\GetDocumentWorkflowHistoryStepsTest::__pest_evaluable_it_can_get_document_workflow_history":0.354,"P\\Tests\\Feature\\Requests\\FileCabinets\\Search\\GetDocumentsFromAFileCabinetTest::__pest_evaluable_it_can_get_all_documents":0.876,"P\\Tests\\Feature\\Requests\\Documents\\Sections\\DeleteSectionTest::__pest_evaluable_it_can_delete_a_specific_section":0.825,"P\\Tests\\Feature\\Requests\\FileCabinets\\Upload\\AppendFilesToADataRecordTest::__pest_evaluable_it_can_attach_a_file_to_a_data_record":0.8,"P\\Tests\\Feature\\Requests\\FileCabinets\\Upload\\AppendFilesToADataRecordTest::__pest_evaluable_it_can_attach_files_to_a_data_record":0.353,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyRoles\\GetAllRolesForASpecificUserTest::__pest_evaluable_it_can_list_groups":0.78,"P\\Tests\\Feature\\Requests\\Documents\\Sections\\GetASpecificSectionTest::__pest_evaluable_it_can_get_a_specific_section":0.76,"P\\Tests\\Feature\\Requests\\Documents\\Thumbnail\\GetDocumentDownloadThumbnailRequestTest::__pest_evaluable_it_can_download_a_document_thumbnail":0.847,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexNumericDTOTest::__pest_evaluable_it_create_index_numeric_dto":0,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyRoles\\AddRemoveUserToARoleTest::__pest_evaluable_it_can_add_roles_to_a_user":6.818,"P\\Tests\\Feature\\Requests\\General\\UserManagement\\GetModifyRoles\\AddRemoveUserToARoleTest::__pest_evaluable_it_can_remove_roles_to_a_user":5.917,"P\\Tests\\Feature\\Requests\\Documents\\Download\\DownloadSectionTest::__pest_evaluable_it_can_download_a_section":0.849,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexTableDTOTest::__pest_evaluable_it_create_prepare_index_text_dto_using_dto":0.001,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexTextDTOTest::__pest_evaluable_it_create_prepare_index_text_dto":0,"P\\Tests\\Unit\\DTO\\DocumentIndex\\IndexMemoDTOTest::__pest_evaluable_it_create_prepare_index_memo_dto":0,"P\\Tests\\Feature\\Requests\\Documents\\GetDocumentCountRequestTest::__pest_evaluable_it_can_get_a_total_count_of_documents":0.879,"Tests\\Unit\\DTO\\TextshotPageTest::test_it_can_create_textshot_page_with_null_language":0,"Tests\\Unit\\DTO\\TextshotPageTest::test_it_can_create_textshot_page_with_string_language":0.006,"Tests\\Unit\\DTO\\TextshotPageTest::test_it_can_create_textshot_page_with_empty_content":0,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_uses_default_file_driver_when_no_configuration_is_set":0.361,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_respects_the_new_CACHE__STORE_fallback_chain":0.008,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_environment_variable_fallback_chain_works_correctly":0.384,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_CACHE__STORE_takes_precedence_over_CACHE__DRIVER_when_DOCUWARE__CACHE__DRIVER_is_not_set":0.376,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_can_be_overridden":0.037,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_properly_loads_from_config":0.412,"P\\Tests\\Feature\\Laravel12CacheCompatibilityTest::__pest_evaluable_cache_configuration_fallback_chain_is_properly_configured":0.385}} \ No newline at end of file +{"version":"pest_3.8.4","defects":[],"times":{"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_can_try_to_create_enum_from_string_value":0.02,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_throws_exception_for_invalid_enum_value":0,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_can_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_can_get_string_value_from_enum":0,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_has_all_expected_dialog_type_enum_cases":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_throws_exception_for_invalid_enum_value":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_has_all_expected_connection_enum_cases":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_can_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_can_get_string_value_from_enum":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_can_try_to_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_throws_exception_for_invalid_enum_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_try_to_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_be_used_in_switch_statements":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_get_string_value_from_enum":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_has_all_expected_field_type_enum_cases":0}} \ No newline at end of file diff --git a/README.md b/README.md index 5e866513..a5440133 100644 --- a/README.md +++ b/README.md @@ -315,6 +315,52 @@ $connector = new DocuWareConnector( ); ``` +### Enums + +The package provides several enums to ensure type safety and consistency when working with DocuWare API values. + +#### ConnectionEnum + +Represents different connection types for DocuWare authentication: + +```php +use CodebarAg\DocuWare\Enums\ConnectionEnum; + +ConnectionEnum::WITHOUT_COOKIE; +ConnectionEnum::STATIC_COOKIE; +ConnectionEnum::DYNAMIC_COOKIE; +``` + +#### DialogType + +Represents different types of dialogs in DocuWare: + +```php +use CodebarAg\DocuWare\Enums\DialogType; + +DialogType::SEARCH; +DialogType::STORE; +DialogType::RESULT; +DialogType::INDEX; +DialogType::LIST; +DialogType::FOLDERS; +``` + +#### DocuWareFieldTypeEnum + +Represents different field types used in DocuWare document indexing: + +```php +use CodebarAg\DocuWare\Enums\DocuWareFieldTypeEnum; + +DocuWareFieldTypeEnum::STRING; +DocuWareFieldTypeEnum::INT; +DocuWareFieldTypeEnum::DECIMAL; +DocuWareFieldTypeEnum::DATE; +DocuWareFieldTypeEnum::DATETIME; +DocuWareFieldTypeEnum::TABLE; +``` + ### Available Requests The following sections provide examples for each available request type. All functionality is documented inline below with code examples. diff --git a/src/Enums/DocuWareFieldTypeEnum.php b/src/Enums/DocuWareFieldTypeEnum.php new file mode 100644 index 00000000..e3370d77 --- /dev/null +++ b/src/Enums/DocuWareFieldTypeEnum.php @@ -0,0 +1,13 @@ + $case->value, ConnectionEnum::cases()); + + expect($actualCases)->toBe($expectedCases); +}); + +it('can get string value from enum', function () { + expect(ConnectionEnum::WITHOUT_COOKIE->value)->toBe('WITHOUT_COOKIE'); + expect(ConnectionEnum::STATIC_COOKIE->value)->toBe('STATIC_COOKIE'); + expect(ConnectionEnum::DYNAMIC_COOKIE->value)->toBe('DYNAMIC_COOKIE'); +}); + +it('can create enum from string value', function () { + expect(ConnectionEnum::from('WITHOUT_COOKIE'))->toBe(ConnectionEnum::WITHOUT_COOKIE); + expect(ConnectionEnum::from('STATIC_COOKIE'))->toBe(ConnectionEnum::STATIC_COOKIE); + expect(ConnectionEnum::from('DYNAMIC_COOKIE'))->toBe(ConnectionEnum::DYNAMIC_COOKIE); +}); + +it('throws exception for invalid enum value', function () { + expect(fn () => ConnectionEnum::from('INVALID_VALUE')) + ->toThrow(ValueError::class); +}); + +it('can try to create enum from string value', function () { + expect(ConnectionEnum::tryFrom('WITHOUT_COOKIE'))->toBe(ConnectionEnum::WITHOUT_COOKIE); + expect(ConnectionEnum::tryFrom('INVALID_VALUE'))->toBeNull(); +}); diff --git a/tests/Unit/Enums/DialogTypeTest.php b/tests/Unit/Enums/DialogTypeTest.php new file mode 100644 index 00000000..7f5008b5 --- /dev/null +++ b/tests/Unit/Enums/DialogTypeTest.php @@ -0,0 +1,46 @@ + $case->value, DialogType::cases()); + + expect($actualCases)->toBe($expectedCases); +}); + +it('can get string value from enum', function () { + expect(DialogType::SEARCH->value)->toBe('Search'); + expect(DialogType::STORE->value)->toBe('Store'); + expect(DialogType::RESULT->value)->toBe('Result'); + expect(DialogType::INDEX->value)->toBe('Index'); + expect(DialogType::LIST->value)->toBe('List'); + expect(DialogType::FOLDERS->value)->toBe('Folders'); +}); + +it('can create enum from string value', function () { + expect(DialogType::from('Search'))->toBe(DialogType::SEARCH); + expect(DialogType::from('Store'))->toBe(DialogType::STORE); + expect(DialogType::from('Result'))->toBe(DialogType::RESULT); + expect(DialogType::from('Index'))->toBe(DialogType::INDEX); + expect(DialogType::from('List'))->toBe(DialogType::LIST); + expect(DialogType::from('Folders'))->toBe(DialogType::FOLDERS); +}); + +it('throws exception for invalid enum value', function () { + expect(fn () => DialogType::from('InvalidType')) + ->toThrow(ValueError::class); +}); + +it('can try to create enum from string value', function () { + expect(DialogType::tryFrom('Search'))->toBe(DialogType::SEARCH); + expect(DialogType::tryFrom('InvalidType'))->toBeNull(); +}); diff --git a/tests/Unit/Enums/DocuWareFieldTypeEnumTest.php b/tests/Unit/Enums/DocuWareFieldTypeEnumTest.php new file mode 100644 index 00000000..cadd5f2c --- /dev/null +++ b/tests/Unit/Enums/DocuWareFieldTypeEnumTest.php @@ -0,0 +1,61 @@ + $case->value, DocuWareFieldTypeEnum::cases()); + + expect($actualCases)->toBe($expectedCases); +}); + +it('can get string value from enum', function () { + expect(DocuWareFieldTypeEnum::STRING->value)->toBe('String'); + expect(DocuWareFieldTypeEnum::INT->value)->toBe('Int'); + expect(DocuWareFieldTypeEnum::DECIMAL->value)->toBe('Decimal'); + expect(DocuWareFieldTypeEnum::DATE->value)->toBe('Date'); + expect(DocuWareFieldTypeEnum::DATETIME->value)->toBe('DateTime'); + expect(DocuWareFieldTypeEnum::TABLE->value)->toBe('Table'); +}); + +it('can create enum from string value', function () { + expect(DocuWareFieldTypeEnum::from('String'))->toBe(DocuWareFieldTypeEnum::STRING); + expect(DocuWareFieldTypeEnum::from('Int'))->toBe(DocuWareFieldTypeEnum::INT); + expect(DocuWareFieldTypeEnum::from('Decimal'))->toBe(DocuWareFieldTypeEnum::DECIMAL); + expect(DocuWareFieldTypeEnum::from('Date'))->toBe(DocuWareFieldTypeEnum::DATE); + expect(DocuWareFieldTypeEnum::from('DateTime'))->toBe(DocuWareFieldTypeEnum::DATETIME); + expect(DocuWareFieldTypeEnum::from('Table'))->toBe(DocuWareFieldTypeEnum::TABLE); +}); + +it('throws exception for invalid enum value', function () { + expect(fn () => DocuWareFieldTypeEnum::from('InvalidType')) + ->toThrow(ValueError::class); +}); + +it('can try to create enum from string value', function () { + expect(DocuWareFieldTypeEnum::tryFrom('String'))->toBe(DocuWareFieldTypeEnum::STRING); + expect(DocuWareFieldTypeEnum::tryFrom('InvalidType'))->toBeNull(); +}); + +it('can be used in switch statements', function () { + $fieldType = DocuWareFieldTypeEnum::STRING; + + $result = match ($fieldType) { + DocuWareFieldTypeEnum::STRING => 'text field', + DocuWareFieldTypeEnum::INT => 'numeric field', + DocuWareFieldTypeEnum::DECIMAL => 'decimal field', + DocuWareFieldTypeEnum::DATE => 'date field', + DocuWareFieldTypeEnum::DATETIME => 'datetime field', + DocuWareFieldTypeEnum::TABLE => 'table field', + }; + + expect($result)->toBe('text field'); +}); From b96f386aefa8b73d390f79986f5f3c50439223e1 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 17 Oct 2025 16:03:58 +0200 Subject: [PATCH 03/22] Removed phpunit cache --- .gitignore | 1 + .phpunit.cache/test-results | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 .phpunit.cache/test-results diff --git a/.gitignore b/.gitignore index 2536343a..0d3a8e74 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ vendor node_modules .phpactor.json build +.phpunit.cache ## Annotations src/DTO/Documents/AnnotationsStamps/* diff --git a/.phpunit.cache/test-results b/.phpunit.cache/test-results deleted file mode 100644 index 7c94d9dd..00000000 --- a/.phpunit.cache/test-results +++ /dev/null @@ -1 +0,0 @@ -{"version":"pest_3.8.4","defects":[],"times":{"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_can_try_to_create_enum_from_string_value":0.02,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_throws_exception_for_invalid_enum_value":0,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_can_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_can_get_string_value_from_enum":0,"P\\Tests\\Unit\\Enums\\DialogTypeTest::__pest_evaluable_it_has_all_expected_dialog_type_enum_cases":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_throws_exception_for_invalid_enum_value":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_has_all_expected_connection_enum_cases":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_can_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_can_get_string_value_from_enum":0,"P\\Tests\\Unit\\Enums\\ConnectionEnumTest::__pest_evaluable_it_can_try_to_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_throws_exception_for_invalid_enum_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_try_to_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_be_used_in_switch_statements":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_create_enum_from_string_value":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_can_get_string_value_from_enum":0,"P\\Tests\\Unit\\Enums\\DocuWareFieldTypeEnumTest::__pest_evaluable_it_has_all_expected_field_type_enum_cases":0}} \ No newline at end of file From 30b8d829046fac0d438d8ebd3137dec39a909bfb Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 17 Oct 2025 16:08:23 +0200 Subject: [PATCH 04/22] Resolved #188 --- .../UserManagement/GetUsers/OutOfOffice.php | 2 -- .../ModifyDocuments/TransferDocument.php | 31 ++++++++++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php index 2a5a356f..eab35494 100644 --- a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php +++ b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php @@ -12,14 +12,12 @@ public static function fromJson(array $data): self { if ($startDateTime = Arr::get($data, 'StartDateTime')) { $startDateTime = Str::of($startDateTime)->after('(')->before(')'); - // Extract milliseconds part (ignore optional timezone offset like +0000) $milliseconds = (int) (string) $startDateTime; $startDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); } if ($endDateTime = Arr::get($data, 'EndDateTime')) { $endDateTime = Str::of($endDateTime)->after('(')->before(')'); - // Extract milliseconds part (ignore optional timezone offset like +0000) $milliseconds = (int) (string) $endDateTime; $endDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); } diff --git a/src/Requests/Documents/ModifyDocuments/TransferDocument.php b/src/Requests/Documents/ModifyDocuments/TransferDocument.php index 3431ec5d..2ead5f51 100644 --- a/src/Requests/Documents/ModifyDocuments/TransferDocument.php +++ b/src/Requests/Documents/ModifyDocuments/TransferDocument.php @@ -2,7 +2,9 @@ namespace CodebarAg\DocuWare\Requests\Documents\ModifyDocuments; +use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\PrepareDTO; use CodebarAg\DocuWare\Responses\Documents\ModifyDocuments\TransferDocumentResponse; +use Illuminate\Support\Collection; use Saloon\Contracts\Body\HasBody; use Saloon\Enums\Method; use Saloon\Http\Request; @@ -18,9 +20,12 @@ class TransferDocument extends Request implements HasBody public function __construct( protected readonly string $fileCabinetId, protected readonly string $destinationFileCabinetId, - protected readonly string $storeDialogId, protected readonly string $documentId, - protected readonly array $fields = [], + protected readonly ?string $storeDialogId = null, + protected readonly ?Collection $fields = null, + protected readonly bool $keepSource = false, + protected readonly bool $fillIntellix = false, + protected readonly bool $useDefaultDialog = false, ) {} public function resolveEndpoint(): string @@ -39,18 +44,30 @@ protected function defaultHeaders(): array protected function defaultBody(): array { - return [ + $body = [ 'SourceFileCabinetId' => $this->fileCabinetId, 'Documents' => [ [ 'Id' => $this->documentId, - 'Fields' => $this->fields, ], ], - 'KeepSource' => false, - 'FillIntellix' => false, - 'UseDefaultDialog' => false, + 'KeepSource' => $this->keepSource, + 'FillIntellix' => $this->fillIntellix, + 'UseDefaultDialog' => $this->useDefaultDialog, ]; + + // Add storeDialogId if provided + if ($this->storeDialogId) { + $body['StoreDialogId'] = $this->storeDialogId; + } + + // Add fields if provided + if ($this->fields) { + $fieldData = PrepareDTO::makeField($this->fields); + $body['Documents'][0]['Fields'] = $fieldData['Field']; + } + + return $body; } public function createDtoFromResponse(Response $response): bool From fd4e1cfa35d6e3ef16d5c8e747ff5fc3434601d1 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 17 Oct 2025 16:09:00 +0200 Subject: [PATCH 05/22] wip --- src/Requests/Documents/ModifyDocuments/TransferDocument.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Requests/Documents/ModifyDocuments/TransferDocument.php b/src/Requests/Documents/ModifyDocuments/TransferDocument.php index 2ead5f51..4ac99aec 100644 --- a/src/Requests/Documents/ModifyDocuments/TransferDocument.php +++ b/src/Requests/Documents/ModifyDocuments/TransferDocument.php @@ -56,12 +56,10 @@ protected function defaultBody(): array 'UseDefaultDialog' => $this->useDefaultDialog, ]; - // Add storeDialogId if provided if ($this->storeDialogId) { $body['StoreDialogId'] = $this->storeDialogId; } - // Add fields if provided if ($this->fields) { $fieldData = PrepareDTO::makeField($this->fields); $body['Documents'][0]['Fields'] = $fieldData['Field']; From d8c2a1af7e5b6342a7df169c38e1637fa67255fa Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 17 Oct 2025 16:10:29 +0200 Subject: [PATCH 06/22] Minor code improvements --- src/DTO/General/UserManagement/GetUsers/OutOfOffice.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php index eab35494..282ae282 100644 --- a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php +++ b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php @@ -10,13 +10,17 @@ final class OutOfOffice { public static function fromJson(array $data): self { - if ($startDateTime = Arr::get($data, 'StartDateTime')) { + $startDateTime = Arr::get($data, 'StartDateTime'); + + if (filled($startDateTime)) { $startDateTime = Str::of($startDateTime)->after('(')->before(')'); $milliseconds = (int) (string) $startDateTime; $startDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); } - if ($endDateTime = Arr::get($data, 'EndDateTime')) { + $endDateTime = Arr::get($data, 'EndDateTime'); + + if (filled($endDateTime)) { $endDateTime = Str::of($endDateTime)->after('(')->before(')'); $milliseconds = (int) (string) $endDateTime; $endDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); From 56b872e7bca4849ba3e590384c2c7fcd1e1cc60e Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 17 Oct 2025 16:17:28 +0200 Subject: [PATCH 07/22] Improved TransferDocument Request --- .../UserManagement/GetUsers/OutOfOffice.php | 8 +++++--- .../ModifyDocuments/TransferDocument.php | 19 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php index 282ae282..8aeb77a4 100644 --- a/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php +++ b/src/DTO/General/UserManagement/GetUsers/OutOfOffice.php @@ -12,10 +12,12 @@ public static function fromJson(array $data): self { $startDateTime = Arr::get($data, 'StartDateTime'); + $timeZone = config('app.timezone', 'UTC'); + if (filled($startDateTime)) { $startDateTime = Str::of($startDateTime)->after('(')->before(')'); $milliseconds = (int) (string) $startDateTime; - $startDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); + $startDateTime = Carbon::createFromTimestampMs($milliseconds, $timeZone); } $endDateTime = Arr::get($data, 'EndDateTime'); @@ -23,7 +25,7 @@ public static function fromJson(array $data): self if (filled($endDateTime)) { $endDateTime = Str::of($endDateTime)->after('(')->before(')'); $milliseconds = (int) (string) $endDateTime; - $endDateTime = Carbon::createFromTimestampMs($milliseconds, 'UTC'); + $endDateTime = Carbon::createFromTimestampMs($milliseconds, $timeZone); } return new self( @@ -31,7 +33,7 @@ public static function fromJson(array $data): self startDateTime: $startDateTime, startDateTimeSpecified: Arr::get($data, 'StartDateTimeSpecified'), endDateTime: $endDateTime, - endDateTimeSpecified: Arr::get($data, key: 'EndDateTimeSpecified'), + endDateTimeSpecified: Arr::get($data, 'EndDateTimeSpecified'), ); } diff --git a/src/Requests/Documents/ModifyDocuments/TransferDocument.php b/src/Requests/Documents/ModifyDocuments/TransferDocument.php index 4ac99aec..b80a2a96 100644 --- a/src/Requests/Documents/ModifyDocuments/TransferDocument.php +++ b/src/Requests/Documents/ModifyDocuments/TransferDocument.php @@ -2,6 +2,7 @@ namespace CodebarAg\DocuWare\Requests\Documents\ModifyDocuments; +use Arr; use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\PrepareDTO; use CodebarAg\DocuWare\Responses\Documents\ModifyDocuments\TransferDocumentResponse; use Illuminate\Support\Collection; @@ -30,7 +31,13 @@ public function __construct( public function resolveEndpoint(): string { - return '/FileCabinets/'.$this->destinationFileCabinetId.'/Task/Transfer'; + $endpoint = '/FileCabinets/'.$this->destinationFileCabinetId.'/Task/Transfer'; + + if ($this->storeDialogId) { + $endpoint .= '?StoreDialogId='.$this->storeDialogId; + } + + return $endpoint; } protected function defaultHeaders(): array @@ -49,6 +56,7 @@ protected function defaultBody(): array 'Documents' => [ [ 'Id' => $this->documentId, + 'Fields' => $this->fields ? Arr::get(PrepareDTO::makeField($this->fields), 'Field') : null, ], ], 'KeepSource' => $this->keepSource, @@ -56,15 +64,6 @@ protected function defaultBody(): array 'UseDefaultDialog' => $this->useDefaultDialog, ]; - if ($this->storeDialogId) { - $body['StoreDialogId'] = $this->storeDialogId; - } - - if ($this->fields) { - $fieldData = PrepareDTO::makeField($this->fields); - $body['Documents'][0]['Fields'] = $fieldData['Field']; - } - return $body; } From 9de480befc4c7f45be8c9bf4edfd812033e413a5 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 20 Mar 2026 06:58:06 +0100 Subject: [PATCH 08/22] Security updates --- .github/dependabot.yml | 40 ++++++++++++++++++++++++------ CONTRIBUTING.md | 55 ++++++++++++++++++++++++++++++++++++++++++ SECURITY.md | 3 +++ 3 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 30c8a493..9ac6a658 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,38 @@ -# Please see the documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - version: 2 updates: - - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "weekly" - labels: - - "dependencies" \ No newline at end of file + interval: "daily" + ignore: + - dependency-name: "*" + update-types: [ "version-update:semver-major" ] + groups: + minor-and-patch: + update-types: [ "minor", "patch" ] + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-type: "direct" + ignore: + - dependency-name: "*" + update-types: [ "version-update:semver-major" ] + groups: + minor-and-patch: + update-types: [ "minor", "patch" ] + + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-type: "direct" + ignore: + - dependency-name: "*" + update-types: [ "version-update:semver-major" ] + groups: + minor-and-patch: + update-types: [ "minor", "patch" ] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..b4ae1c4a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,55 @@ +# Contributing + +Contributions are **welcome** and will be fully **credited**. + +Please read and understand the contribution guide before creating an issue or pull request. + +## Etiquette + +This project is open source, and as such, the maintainers give their free time to build and maintain the source code +held within. They make the code freely available in the hope that it will be of use to other developers. It would be +extremely unfair for them to suffer abuse or anger for their hard work. + +Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the +world that developers are civilized and selfless people. + +It's the duty of the maintainer to ensure that all submissions to the project are of sufficient +quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. + +## Viability + +When requesting or submitting new features, first consider whether it might be useful to others. Open +source projects are used by many developers, who may have entirely different needs to your own. Think about +whether or not your feature is likely to be used by other users of the project. + +## Procedure + +Before filing an issue: + +- Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. +- Check to make sure your feature suggestion isn't already present within the project. +- Check the pull requests tab to ensure that the bug doesn't have a fix in progress. +- Check the pull requests tab to ensure that the feature isn't already in progress. + +Before submitting a pull request: + +- Check the codebase to ensure that your feature doesn't already exist. +- Check the pull requests to ensure that another person hasn't already submitted the feature or fix. + +## Requirements + +If the project maintainer has any additional requirements, you will find them listed here. + +- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). + +- **Add tests!** - Your patch won't be accepted if it doesn't have tests. + +- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. + +- **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. + +- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. + +- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. + +**Happy coding**! diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..dd923a21 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,3 @@ +# Security Policy + +If you discover any security related issues, please email info@codebar.ch instead of using the issue tracker. From ddae347c38ccd4dd7dd76ed68fb4ced7669c8657 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 20 Mar 2026 07:39:21 +0100 Subject: [PATCH 09/22] Optimized Repository Skeleton --- .github/workflows/dependabot-auto-merge.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index a3368d2d..5bfa1ad9 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.4.0 + uses: dependabot/fetch-metadata@v2.5.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 046e9c88..3ea91b44 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -15,6 +15,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: 'Dependency Review' uses: actions/dependency-review-action@v4 From 72a9de08f2637f057b1b680fee7a5e5310dba2ab Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 20 Mar 2026 08:23:42 +0100 Subject: [PATCH 10/22] chore: sync Laravel Pint workflow from template --- .github/workflows/fix-php-code-style-issues.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 768197d9..9ed9047d 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -2,20 +2,21 @@ name: Fix PHP code style issues on: [push] +permissions: + contents: write + jobs: php-code-styling: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v5 - with: - ref: ${{ github.head_ref }} + uses: actions/checkout@v6.0.2 - name: Fix PHP code style issues uses: aglipanci/laravel-pint-action@2.6 - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v7 + uses: stefanzweifel/git-auto-commit-action@v6.0.1 with: commit_message: Fix styling From 81ff18048a9549404209964d4f2063a371815acc Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 20 Mar 2026 08:34:56 +0100 Subject: [PATCH 11/22] chore: sync CONTRIBUTING.md from template --- .github/CONTRIBUTING.md | 2 +- CONTRIBUTING.md | 55 ----------------------------------------- 2 files changed, 1 insertion(+), 56 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b4ae1c4a..3f687e93 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -40,7 +40,7 @@ Before submitting a pull request: If the project maintainer has any additional requirements, you will find them listed here. -- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). +- **[Laravel Pint](https://github.com/laravel/pint)** - PHP style is enforced with Pint (PSR-12–oriented, via PHP-CS-Fixer). Run `composer install`, then `./vendor/bin/pint` before pushing (`composer run format` instead if your package defines that script). The **Fix PHP code style issues** GitHub Action also runs on push and may commit formatting fixes. - **Add tests!** - Your patch won't be accepted if it doesn't have tests. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index b4ae1c4a..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,55 +0,0 @@ -# Contributing - -Contributions are **welcome** and will be fully **credited**. - -Please read and understand the contribution guide before creating an issue or pull request. - -## Etiquette - -This project is open source, and as such, the maintainers give their free time to build and maintain the source code -held within. They make the code freely available in the hope that it will be of use to other developers. It would be -extremely unfair for them to suffer abuse or anger for their hard work. - -Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the -world that developers are civilized and selfless people. - -It's the duty of the maintainer to ensure that all submissions to the project are of sufficient -quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. - -## Viability - -When requesting or submitting new features, first consider whether it might be useful to others. Open -source projects are used by many developers, who may have entirely different needs to your own. Think about -whether or not your feature is likely to be used by other users of the project. - -## Procedure - -Before filing an issue: - -- Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. -- Check to make sure your feature suggestion isn't already present within the project. -- Check the pull requests tab to ensure that the bug doesn't have a fix in progress. -- Check the pull requests tab to ensure that the feature isn't already in progress. - -Before submitting a pull request: - -- Check the codebase to ensure that your feature doesn't already exist. -- Check the pull requests to ensure that another person hasn't already submitted the feature or fix. - -## Requirements - -If the project maintainer has any additional requirements, you will find them listed here. - -- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). - -- **Add tests!** - Your patch won't be accepted if it doesn't have tests. - -- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. - -- **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. - -- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. - -- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. - -**Happy coding**! From 928c56ccdb568fe2f47c4e99b90651d44579257c Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Fri, 20 Mar 2026 08:34:57 +0100 Subject: [PATCH 12/22] chore: sync security policy from template --- SECURITY.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index dd923a21..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,3 +0,0 @@ -# Security Policy - -If you discover any security related issues, please email info@codebar.ch instead of using the issue tracker. From 61ccea0207fe090ab89e964675e6c0a9e2e4187c Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 07:58:03 +0100 Subject: [PATCH 13/22] chore: sync PHPStan workflow from template --- .github/workflows/phpstan.yml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 4fcc1697..10e8b37c 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -1,13 +1,33 @@ name: PHPStan -on: [push] +on: + push: + paths: + - '**/*.php' + - 'phpstan.neon.dist' + - 'phpstan-baseline.neon' + - 'composer.json' + - 'composer.lock' + pull_request: + paths: + - '**/*.php' + - 'phpstan.neon.dist' + - 'phpstan-baseline.neon' + - 'composer.json' + - 'composer.lock' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: phpstan: name: phpstan runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6.0.2 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -16,7 +36,7 @@ jobs: coverage: none - name: Install composer dependencies - uses: ramsey/composer-install@v3 + uses: ramsey/composer-install@v4 - name: Run PHPStan run: ./vendor/bin/phpstan --error-format=github From 6661fd2bfb4d3972ada5f8cc473613a43faf445e Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 08:07:15 +0100 Subject: [PATCH 14/22] chore: sync Laravel Pint workflow from template --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 9ed9047d..1c4e562f 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -17,6 +17,6 @@ jobs: uses: aglipanci/laravel-pint-action@2.6 - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v6.0.1 + uses: stefanzweifel/git-auto-commit-action@v7 with: commit_message: Fix styling From 8720eafb1c408f09e8a8b56bd911ebb31bf118ba Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 08:09:44 +0100 Subject: [PATCH 15/22] chore: sync Dependabot config and workflows from template --- .github/workflows/dependency-review.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 3ea91b44..b45940f0 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -15,6 +15,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v6 + uses: actions/checkout@v6.0.2 - name: 'Dependency Review' - uses: actions/dependency-review-action@v4 + uses: actions/dependency-review-action@v4.9.0 From 6ca012bfcdd8bb3f6de665834c826bf2793c8c28 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 08:09:47 +0100 Subject: [PATCH 16/22] chore: sync Laravel Pint workflow from template --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 1c4e562f..41e61934 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -17,6 +17,6 @@ jobs: uses: aglipanci/laravel-pint-action@2.6 - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v7 + uses: stefanzweifel/git-auto-commit-action@v7.1.0 with: commit_message: Fix styling From 8a79d8b0cf4da4dd699363ba2175176f3ec4955e Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 08:09:54 +0100 Subject: [PATCH 17/22] chore: sync PHPStan workflow from template --- .github/workflows/phpstan.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 10e8b37c..18023123 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -30,13 +30,13 @@ jobs: - uses: actions/checkout@v6.0.2 - name: Setup PHP - uses: shivammathur/setup-php@v2 + uses: shivammathur/setup-php@2.37.0 with: php-version: '8.4' coverage: none - name: Install composer dependencies - uses: ramsey/composer-install@v4 + uses: ramsey/composer-install@4.0.0 - name: Run PHPStan run: ./vendor/bin/phpstan --error-format=github From b5271921a9184a74ddf64c8a49f9e7e6bbb919dc Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 08:09:55 +0100 Subject: [PATCH 18/22] chore: sync release workflow from template --- .github/workflows/release.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a4b057b7..c95e4148 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,12 +10,13 @@ jobs: release: name: Release runs-on: ubuntu-latest + timeout-minutes: 10 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6.0.2 with: fetch-depth: '0' - name: Bump version and push tag - uses: anothrNick/github-tag-action@master + uses: anothrNick/github-tag-action@1.75.0 env: GITHUB_TOKEN: ${{ secrets.MY_GITHUB_TOKEN }} WITH_V: true From aff5617532fcc1e036d680c2465f9327fc73e937 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 08:50:33 +0100 Subject: [PATCH 19/22] chore: sync CONTRIBUTING.md from template --- CONTRIBUTING.md | 55 ------------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index b4ae1c4a..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,55 +0,0 @@ -# Contributing - -Contributions are **welcome** and will be fully **credited**. - -Please read and understand the contribution guide before creating an issue or pull request. - -## Etiquette - -This project is open source, and as such, the maintainers give their free time to build and maintain the source code -held within. They make the code freely available in the hope that it will be of use to other developers. It would be -extremely unfair for them to suffer abuse or anger for their hard work. - -Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the -world that developers are civilized and selfless people. - -It's the duty of the maintainer to ensure that all submissions to the project are of sufficient -quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. - -## Viability - -When requesting or submitting new features, first consider whether it might be useful to others. Open -source projects are used by many developers, who may have entirely different needs to your own. Think about -whether or not your feature is likely to be used by other users of the project. - -## Procedure - -Before filing an issue: - -- Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. -- Check to make sure your feature suggestion isn't already present within the project. -- Check the pull requests tab to ensure that the bug doesn't have a fix in progress. -- Check the pull requests tab to ensure that the feature isn't already in progress. - -Before submitting a pull request: - -- Check the codebase to ensure that your feature doesn't already exist. -- Check the pull requests to ensure that another person hasn't already submitted the feature or fix. - -## Requirements - -If the project maintainer has any additional requirements, you will find them listed here. - -- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). - -- **Add tests!** - Your patch won't be accepted if it doesn't have tests. - -- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. - -- **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. - -- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. - -- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. - -**Happy coding**! From 4fe66131d239c78955313dd37b46339571f8a47c Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 21 Mar 2026 08:50:34 +0100 Subject: [PATCH 20/22] chore: sync security policy from template --- SECURITY.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index dd923a21..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,3 +0,0 @@ -# Security Policy - -If you discover any security related issues, please email info@codebar.ch instead of using the issue tracker. From 43984b58f12f571b412d5100186d7c62adbe4ff2 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Thu, 26 Mar 2026 06:59:25 +0100 Subject: [PATCH 21/22] Optimized Repository Skeleton --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 9aa3cd0b..c637e7ce 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "authors": [ { "name": "Sebastian Bürgin-Fix", - "email": "sebastian.buergin@buergin.ch", + "email": "helpdesk@codebar.ch", "homepage": "https://www.codebar.ch", "role": "Software-Engineer" } @@ -25,9 +25,9 @@ "guzzlehttp/guzzle": "^7.8", "illuminate/contracts": "^12.0", "nesbot/carbon": "^3.8", - "saloonphp/cache-plugin": "^3.0", - "saloonphp/laravel-plugin": "^3.5", - "saloonphp/saloon": "^3.10.1", + "saloonphp/cache-plugin": "^3.1", + "saloonphp/laravel-plugin": "^4.0", + "saloonphp/saloon": "^4.0", "spatie/laravel-package-tools": "^1.19" }, "require-dev": { From a9fbe3128f04b19fd2597b22212a660496ea3fe2 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Thu, 26 Mar 2026 07:56:45 +0100 Subject: [PATCH 22/22] Optimized Repository Skeleton --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c637e7ce..409fc869 100644 --- a/composer.json +++ b/composer.json @@ -26,8 +26,8 @@ "illuminate/contracts": "^12.0", "nesbot/carbon": "^3.8", "saloonphp/cache-plugin": "^3.1", - "saloonphp/laravel-plugin": "^4.0", - "saloonphp/saloon": "^4.0", + "saloonphp/laravel-plugin": "^3.0|^4.0", + "saloonphp/saloon": "^3.0|^4.0", "spatie/laravel-package-tools": "^1.19" }, "require-dev": {