diff --git a/composer.json b/composer.json index 3fd73e5d3..d0fe1b96b 100644 --- a/composer.json +++ b/composer.json @@ -74,6 +74,7 @@ "league/commonmark": "^2.2", "league/html-to-markdown": "^5.0", "lolli42/finediff": "^1.0", + "opis/json-schema": "^2.2", "orakili/composer-drupal-info-file-patch-helper": "^1", "pelago/emogrifier": "^7.0", "reliefweb/api-indexer": "^v2.8", diff --git a/composer.lock b/composer.lock index 6a9f617bd..631f887a3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b8b3d79cb86b6b8956b17662a2b2dba7", + "content-hash": "a2d31af4c84ea2f63b97c40b8233f09a", "packages": [ { "name": "asm89/stack-cors", @@ -9422,6 +9422,196 @@ ], "time": "2023-11-14T13:39:26+00:00" }, + { + "name": "opis/json-schema", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/opis/json-schema.git", + "reference": "c48df6d7089a45f01e1c82432348f2d5976f9bfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/json-schema/zipball/c48df6d7089a45f01e1c82432348f2d5976f9bfb", + "reference": "c48df6d7089a45f01e1c82432348f2d5976f9bfb", + "shasum": "" + }, + "require": { + "ext-json": "*", + "opis/string": "^2.0", + "opis/uri": "^1.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "ext-bcmath": "*", + "ext-intl": "*", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\JsonSchema\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + }, + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + } + ], + "description": "Json Schema Validator for PHP", + "homepage": "https://opis.io/json-schema", + "keywords": [ + "json", + "json-schema", + "schema", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/opis/json-schema/issues", + "source": "https://github.com/opis/json-schema/tree/2.3.0" + }, + "time": "2022-01-08T20:38:03+00:00" + }, + { + "name": "opis/string", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/opis/string.git", + "reference": "9ebf1a1f873f502f6859d11210b25a4bf5d141e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/string/zipball/9ebf1a1f873f502f6859d11210b25a4bf5d141e7", + "reference": "9ebf1a1f873f502f6859d11210b25a4bf5d141e7", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\String\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Multibyte strings as objects", + "homepage": "https://opis.io/string", + "keywords": [ + "multi-byte", + "opis", + "string", + "string manipulation", + "utf-8" + ], + "support": { + "issues": "https://github.com/opis/string/issues", + "source": "https://github.com/opis/string/tree/2.0.1" + }, + "time": "2022-01-14T15:42:23+00:00" + }, + { + "name": "opis/uri", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/opis/uri.git", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/uri/zipball/0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "shasum": "" + }, + "require": { + "opis/string": "^2.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Uri\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Build, parse and validate URIs and URI-templates", + "homepage": "https://opis.io", + "keywords": [ + "URI Template", + "parse url", + "punycode", + "uri", + "uri components", + "url", + "validate uri" + ], + "support": { + "issues": "https://github.com/opis/uri/issues", + "source": "https://github.com/opis/uri/tree/1.1.0" + }, + "time": "2021-05-22T15:57:08+00:00" + }, { "name": "orakili/composer-drupal-info-file-patch-helper", "version": "1.0.1", @@ -13414,7 +13604,7 @@ "type": "github" } ], - "time": "2024-03-14T16:00:52+00:00" + "time": "2020-09-28T06:45:17+00:00" }, { "name": "sebastian/type", diff --git a/config/core.entity_form_display.node.job.default.yml b/config/core.entity_form_display.node.job.default.yml index 28533403e..6adff3b11 100644 --- a/config/core.entity_form_display.node.job.default.yml +++ b/config/core.entity_form_display.node.job.default.yml @@ -14,6 +14,7 @@ dependencies: - field.field.node.job.field_job_experience - field.field.node.job.field_job_tagger_queue_count - field.field.node.job.field_job_type + - field.field.node.job.field_post_api_provider - field.field.node.job.field_source - field.field.node.job.field_theme - field.field.node.job.reliefweb_job_tagger_info @@ -191,6 +192,7 @@ hidden: field_import_guid: true field_import_hash: true field_job_tagger_queue_count: true + field_post_api_provider: true langcode: true promote: true reliefweb_job_tagger_info: true diff --git a/config/core.entity_form_display.node.report.default.yml b/config/core.entity_form_display.node.report.default.yml index fc071c3bc..8215da9dd 100644 --- a/config/core.entity_form_display.node.report.default.yml +++ b/config/core.entity_form_display.node.report.default.yml @@ -24,6 +24,7 @@ dependencies: - field.field.node.report.field_origin - field.field.node.report.field_origin_notes - field.field.node.report.field_original_publication_date + - field.field.node.report.field_post_api_provider - field.field.node.report.field_primary_country - field.field.node.report.field_source - field.field.node.report.field_theme @@ -36,6 +37,7 @@ dependencies: - path - reliefweb_fields - reliefweb_files + - text id: node.report.default targetEntityType: node bundle: report @@ -375,6 +377,7 @@ content: third_party_settings: { } hidden: created: true + field_post_api_provider: true field_vulnerable_groups: true langcode: true promote: true diff --git a/config/core.entity_form_display.node.training.default.yml b/config/core.entity_form_display.node.training.default.yml index cfd571aea..6bd33eda1 100644 --- a/config/core.entity_form_display.node.training.default.yml +++ b/config/core.entity_form_display.node.training.default.yml @@ -12,6 +12,7 @@ dependencies: - field.field.node.training.field_how_to_register - field.field.node.training.field_language - field.field.node.training.field_link + - field.field.node.training.field_post_api_provider - field.field.node.training.field_registration_deadline - field.field.node.training.field_source - field.field.node.training.field_theme @@ -230,6 +231,7 @@ content: third_party_settings: { } hidden: created: true + field_post_api_provider: true langcode: true promote: true status: true diff --git a/config/core.entity_form_display.reliefweb_post_api_provider.reliefweb_post_api_provider.default.yml b/config/core.entity_form_display.reliefweb_post_api_provider.reliefweb_post_api_provider.default.yml new file mode 100644 index 000000000..563c114fb --- /dev/null +++ b/config/core.entity_form_display.reliefweb_post_api_provider.reliefweb_post_api_provider.default.yml @@ -0,0 +1,176 @@ +uuid: 15416736-1f4f-421a-ac0d-b677b0e5fcf3 +langcode: en +status: true +dependencies: + config: + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_document_url + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_file_url + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_image_url + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_notify + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_quota + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_rate_limit + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_resource_status + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_skip_queue + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_source + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_user + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_webhook_url + module: + - link + - reliefweb_fields + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.default +targetEntityType: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +mode: default +content: + field_document_url: + type: link_default + weight: 6 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + field_file_url: + type: link_default + weight: 8 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + field_image_url: + type: link_default + weight: 7 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + field_notify: + type: email_default + weight: 11 + region: content + settings: + placeholder: '' + size: 60 + third_party_settings: { } + field_quota: + type: number + weight: 9 + region: content + settings: + placeholder: '' + third_party_settings: { } + field_rate_limit: + type: number + weight: 10 + region: content + settings: + placeholder: '' + third_party_settings: { } + field_resource_status: + type: options_select + weight: 2 + region: content + settings: { } + third_party_settings: { } + field_skip_queue: + type: boolean_checkbox + weight: 14 + region: content + settings: + display_label: true + third_party_settings: { } + field_source: + type: reliefweb_entity_reference_select + weight: 3 + region: content + settings: + sort: label + extra_data: + 'source:field_shortname': 'source:field_shortname' + 'source:tid': '0' + 'source:uuid': '0' + 'source:revision_id': '0' + 'source:langcode': '0' + 'source:vid': '0' + 'source:revision_created': '0' + 'source:revision_user': '0' + 'source:revision_log_message': '0' + 'source:status': '0' + 'source:name': '0' + 'source:description': '0' + 'source:weight': '0' + 'source:parent': '0' + 'source:changed': '0' + 'source:default_langcode': '0' + 'source:revision_default': '0' + 'source:revision_translation_affected': '0' + 'source:created': '0' + 'source:moderation_status': '0' + 'source:field_aliases': '0' + 'source:field_allowed_content_types': '0' + 'source:field_attention_job': '0' + 'source:field_attention_report': '0' + 'source:field_attention_training': '0' + 'source:field_country': '0' + 'source:field_disclaimer': '0' + 'source:field_fts_id': '0' + 'source:field_homepage': '0' + 'source:field_job_import_feed': '0' + 'source:field_links': '0' + 'source:field_logo': '0' + 'source:field_longname': '0' + 'source:field_organization_type': '0' + 'source:field_spanish_name': '0' + 'source:field_user_posting_rights': '0' + third_party_settings: { } + field_user: + type: entity_reference_autocomplete + weight: 4 + region: content + settings: + match_operator: CONTAINS + match_limit: 10 + size: 60 + placeholder: '' + third_party_settings: { } + field_webhook_url: + type: link_default + weight: 12 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + key: + type: reliefweb_post_api_key + weight: 5 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + name: + type: string_textfield + weight: 0 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + resource: + type: options_select + weight: 1 + region: content + settings: { } + third_party_settings: { } + status: + type: boolean_checkbox + weight: 13 + region: content + settings: + display_label: true + third_party_settings: { } +hidden: { } diff --git a/config/core.entity_view_display.node.job.default.yml b/config/core.entity_view_display.node.job.default.yml index 4735853c3..3471d77db 100644 --- a/config/core.entity_view_display.node.job.default.yml +++ b/config/core.entity_view_display.node.job.default.yml @@ -14,6 +14,7 @@ dependencies: - field.field.node.job.field_job_experience - field.field.node.job.field_job_tagger_queue_count - field.field.node.job.field_job_type + - field.field.node.job.field_post_api_provider - field.field.node.job.field_source - field.field.node.job.field_theme - field.field.node.job.reliefweb_job_tagger_info @@ -116,6 +117,7 @@ hidden: field_import_guid: true field_import_hash: true field_job_tagger_queue_count: true + field_post_api_provider: true langcode: true links: true reliefweb_job_tagger_info: true diff --git a/config/core.entity_view_display.node.job.teaser.yml b/config/core.entity_view_display.node.job.teaser.yml index 9d88c6d86..1ec033515 100644 --- a/config/core.entity_view_display.node.job.teaser.yml +++ b/config/core.entity_view_display.node.job.teaser.yml @@ -15,6 +15,7 @@ dependencies: - field.field.node.job.field_job_experience - field.field.node.job.field_job_tagger_queue_count - field.field.node.job.field_job_type + - field.field.node.job.field_post_api_provider - field.field.node.job.field_source - field.field.node.job.field_theme - field.field.node.job.reliefweb_job_tagger_info @@ -61,6 +62,7 @@ hidden: field_job_experience: true field_job_tagger_queue_count: true field_job_type: true + field_post_api_provider: true field_theme: true langcode: true links: true diff --git a/config/core.entity_view_display.node.report.default.yml b/config/core.entity_view_display.node.report.default.yml index bfb00fdb4..d5937ba6f 100644 --- a/config/core.entity_view_display.node.report.default.yml +++ b/config/core.entity_view_display.node.report.default.yml @@ -23,6 +23,7 @@ dependencies: - field.field.node.report.field_origin - field.field.node.report.field_origin_notes - field.field.node.report.field_original_publication_date + - field.field.node.report.field_post_api_provider - field.field.node.report.field_primary_country - field.field.node.report.field_source - field.field.node.report.field_theme @@ -72,7 +73,7 @@ content: settings: link: true third_party_settings: { } - weight: 10 + weight: 9 region: content field_disaster_type: type: entity_reference_label @@ -80,14 +81,14 @@ content: settings: link: true third_party_settings: { } - weight: 11 + weight: 10 region: content field_file: type: reliefweb_file label: above settings: { } third_party_settings: { } - weight: 13 + weight: 12 region: content field_image: type: entity_reference_entity_view @@ -104,7 +105,7 @@ content: settings: link: true third_party_settings: { } - weight: 12 + weight: 11 region: content field_origin_notes: type: string @@ -145,7 +146,7 @@ content: settings: link: true third_party_settings: { } - weight: 9 + weight: 8 region: content hidden: field_bury: true @@ -158,6 +159,7 @@ hidden: field_notify: true field_ocha_product: true field_origin: true + field_post_api_provider: true field_vulnerable_groups: true langcode: true links: true diff --git a/config/core.entity_view_display.node.report.headline.yml b/config/core.entity_view_display.node.report.headline.yml index 2bba2bd4b..af7ee3829 100644 --- a/config/core.entity_view_display.node.report.headline.yml +++ b/config/core.entity_view_display.node.report.headline.yml @@ -24,6 +24,7 @@ dependencies: - field.field.node.report.field_origin - field.field.node.report.field_origin_notes - field.field.node.report.field_original_publication_date + - field.field.node.report.field_post_api_provider - field.field.node.report.field_primary_country - field.field.node.report.field_source - field.field.node.report.field_theme @@ -106,6 +107,7 @@ hidden: field_origin: true field_origin_notes: true field_original_publication_date: true + field_post_api_provider: true field_theme: true field_vulnerable_groups: true langcode: true diff --git a/config/core.entity_view_display.node.report.teaser.yml b/config/core.entity_view_display.node.report.teaser.yml index b3f289937..ee2d1bab4 100644 --- a/config/core.entity_view_display.node.report.teaser.yml +++ b/config/core.entity_view_display.node.report.teaser.yml @@ -24,6 +24,7 @@ dependencies: - field.field.node.report.field_origin - field.field.node.report.field_origin_notes - field.field.node.report.field_original_publication_date + - field.field.node.report.field_post_api_provider - field.field.node.report.field_primary_country - field.field.node.report.field_source - field.field.node.report.field_theme @@ -109,6 +110,7 @@ hidden: field_ocha_product: true field_origin: true field_origin_notes: true + field_post_api_provider: true field_theme: true field_vulnerable_groups: true langcode: true diff --git a/config/core.entity_view_display.node.training.default.yml b/config/core.entity_view_display.node.training.default.yml index 124a6b903..b30b204c1 100644 --- a/config/core.entity_view_display.node.training.default.yml +++ b/config/core.entity_view_display.node.training.default.yml @@ -12,6 +12,7 @@ dependencies: - field.field.node.training.field_how_to_register - field.field.node.training.field_language - field.field.node.training.field_link + - field.field.node.training.field_post_api_provider - field.field.node.training.field_registration_deadline - field.field.node.training.field_source - field.field.node.training.field_theme @@ -158,5 +159,6 @@ content: region: content hidden: field_language: true + field_post_api_provider: true langcode: true links: true diff --git a/config/core.entity_view_display.node.training.teaser.yml b/config/core.entity_view_display.node.training.teaser.yml index d5ba1eb70..148260abc 100644 --- a/config/core.entity_view_display.node.training.teaser.yml +++ b/config/core.entity_view_display.node.training.teaser.yml @@ -13,6 +13,7 @@ dependencies: - field.field.node.training.field_how_to_register - field.field.node.training.field_language - field.field.node.training.field_link + - field.field.node.training.field_post_api_provider - field.field.node.training.field_registration_deadline - field.field.node.training.field_source - field.field.node.training.field_theme @@ -75,6 +76,7 @@ hidden: field_how_to_register: true field_language: true field_link: true + field_post_api_provider: true field_theme: true field_training_format: true field_training_language: true diff --git a/config/core.entity_view_display.reliefweb_post_api_provider.reliefweb_post_api_provider.default.yml b/config/core.entity_view_display.reliefweb_post_api_provider.reliefweb_post_api_provider.default.yml new file mode 100644 index 000000000..17270fba9 --- /dev/null +++ b/config/core.entity_view_display.reliefweb_post_api_provider.reliefweb_post_api_provider.default.yml @@ -0,0 +1,158 @@ +uuid: 52e1783a-701e-44a9-aa5a-1cbdbee86d09 +langcode: en +status: true +dependencies: + config: + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_document_url + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_file_url + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_image_url + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_notify + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_quota + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_rate_limit + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_resource_status + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_skip_queue + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_source + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_user + - field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_webhook_url + module: + - link + - options + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.default +targetEntityType: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +mode: default +content: + field_document_url: + type: link + label: above + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + weight: 5 + region: content + field_file_url: + type: link + label: above + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + weight: 7 + region: content + field_image_url: + type: link + label: above + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + weight: 6 + region: content + field_notify: + type: basic_string + label: above + settings: { } + third_party_settings: { } + weight: 10 + region: content + field_quota: + type: number_integer + label: above + settings: + thousand_separator: '' + prefix_suffix: true + third_party_settings: { } + weight: 8 + region: content + field_rate_limit: + type: number_integer + label: above + settings: + thousand_separator: '' + prefix_suffix: true + third_party_settings: { } + weight: 9 + region: content + field_resource_status: + type: list_default + label: above + settings: { } + third_party_settings: { } + weight: 2 + region: content + field_skip_queue: + type: boolean + label: above + settings: + format: default + format_custom_false: '' + format_custom_true: '' + third_party_settings: { } + weight: 13 + region: content + field_source: + type: entity_reference_label + label: above + settings: + link: true + third_party_settings: { } + weight: 3 + region: content + field_user: + type: entity_reference_label + label: above + settings: + link: true + third_party_settings: { } + weight: 4 + region: content + field_webhook_url: + type: link + label: above + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + weight: 11 + region: content + name: + type: string + label: hidden + settings: + link_to_entity: false + third_party_settings: { } + weight: 0 + region: content + resource: + type: list_default + label: above + settings: { } + third_party_settings: { } + weight: 1 + region: content + status: + type: boolean + label: above + settings: + format: default + format_custom_false: '' + format_custom_true: '' + third_party_settings: { } + weight: 12 + region: content +hidden: + key: true diff --git a/config/core.extension.yml b/config/core.extension.yml index d7db6a7ba..1d74d942c 100644 --- a/config/core.extension.yml +++ b/config/core.extension.yml @@ -87,6 +87,7 @@ module: reliefweb_job_tagger: 0 reliefweb_meta: 0 reliefweb_moderation: 0 + reliefweb_post_api: 0 reliefweb_reporting: 0 reliefweb_revisions: 0 reliefweb_rivers: 0 diff --git a/config/field.field.node.job.field_post_api_provider.yml b/config/field.field.node.job.field_post_api_provider.yml new file mode 100644 index 000000000..e307d6e77 --- /dev/null +++ b/config/field.field.node.job.field_post_api_provider.yml @@ -0,0 +1,26 @@ +uuid: c5a31abb-9f8c-4756-9aa5-852e38b51186 +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_post_api_provider + - node.type.job +id: node.job.field_post_api_provider +field_name: field_post_api_provider +entity_type: node +bundle: job +label: 'POST API provider' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:reliefweb_post_api_provider' + handler_settings: + target_bundles: null + sort: + field: _none + direction: ASC + auto_create: false +field_type: entity_reference diff --git a/config/field.field.node.report.field_post_api_provider.yml b/config/field.field.node.report.field_post_api_provider.yml new file mode 100644 index 000000000..b17da7a4b --- /dev/null +++ b/config/field.field.node.report.field_post_api_provider.yml @@ -0,0 +1,26 @@ +uuid: 1ea994b5-9a7a-4263-aaf6-5d4fdf3bc7cc +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_post_api_provider + - node.type.report +id: node.report.field_post_api_provider +field_name: field_post_api_provider +entity_type: node +bundle: report +label: 'POST API provider' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:reliefweb_post_api_provider' + handler_settings: + target_bundles: null + sort: + field: _none + direction: ASC + auto_create: false +field_type: entity_reference diff --git a/config/field.field.node.training.field_post_api_provider.yml b/config/field.field.node.training.field_post_api_provider.yml new file mode 100644 index 000000000..9c065918e --- /dev/null +++ b/config/field.field.node.training.field_post_api_provider.yml @@ -0,0 +1,26 @@ +uuid: 7927f837-fa9e-453a-a6c1-e551991bd6b1 +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_post_api_provider + - node.type.training +id: node.training.field_post_api_provider +field_name: field_post_api_provider +entity_type: node +bundle: training +label: 'POST API provider' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:reliefweb_post_api_provider' + handler_settings: + target_bundles: null + sort: + field: _none + direction: ASC + auto_create: false +field_type: entity_reference diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_document_url.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_document_url.yml new file mode 100644 index 000000000..9ad1dbc6c --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_document_url.yml @@ -0,0 +1,23 @@ +uuid: ae98e3ee-5084-412b-bf82-29612d0dcd68 +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_document_url + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_document_url +field_name: field_document_url +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Base document URL' +description: 'Allowed base document URLs.' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + title: 0 + link_type: 16 +field_type: link diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_file_url.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_file_url.yml new file mode 100644 index 000000000..e637a2f0a --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_file_url.yml @@ -0,0 +1,23 @@ +uuid: 39e3ea73-a025-4de8-b009-956e0be2938d +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_file_url + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_file_url +field_name: field_file_url +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Base file URL' +description: 'Allowed base file URLs.' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + title: 0 + link_type: 16 +field_type: link diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_image_url.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_image_url.yml new file mode 100644 index 000000000..3ca8b847f --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_image_url.yml @@ -0,0 +1,23 @@ +uuid: 275b6221-05ba-446a-abfc-758a0a765fb9 +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_image_url + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_image_url +field_name: field_image_url +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Base image URL' +description: 'Allowed base image URLs.' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + title: 0 + link_type: 16 +field_type: link diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_notify.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_notify.yml new file mode 100644 index 000000000..9e5a59c4d --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_notify.yml @@ -0,0 +1,20 @@ +uuid: 000755d1-44d5-4f08-a094-90d8e2f7f301 +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_notify + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_notify +field_name: field_notify +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Notification emails' +description: 'Email addresses to notify when a document is published.' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: { } +field_type: email diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_quota.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_quota.yml new file mode 100644 index 000000000..c19dab612 --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_quota.yml @@ -0,0 +1,26 @@ +uuid: c3c92661-6018-4152-86a2-c1d2fa1da84e +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_quota + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_quota +field_name: field_quota +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Request quota' +description: 'Number of allowed requests per day.' +required: true +translatable: false +default_value: + - + value: 50 +default_value_callback: '' +settings: + min: 1 + max: null + prefix: '' + suffix: '' +field_type: integer diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_rate_limit.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_rate_limit.yml new file mode 100644 index 000000000..67dc6b987 --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_rate_limit.yml @@ -0,0 +1,26 @@ +uuid: 2631a8bc-7cee-45dc-a8c9-6d8739cfab41 +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_rate_limit + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_rate_limit +field_name: field_rate_limit +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Request rate limit' +description: 'Minimum duration in seconds between 2 requests.' +required: true +translatable: false +default_value: + - + value: 60 +default_value_callback: '' +settings: + min: 1 + max: null + prefix: '' + suffix: '' +field_type: integer diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_resource_status.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_resource_status.yml new file mode 100644 index 000000000..36ed62063 --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_resource_status.yml @@ -0,0 +1,23 @@ +uuid: 08651c89-5d06-4e9a-8554-20cb40cc64f6 +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_resource_status + module: + - options + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_resource_status +field_name: field_resource_status +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Submission status' +description: 'Default status of the created content after processing.' +required: true +translatable: false +default_value: + - + value: pending +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_skip_queue.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_skip_queue.yml new file mode 100644 index 000000000..2c29fb2c8 --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_skip_queue.yml @@ -0,0 +1,22 @@ +uuid: e61ae584-476f-4b69-a560-421db571f92b +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_skip_queue + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_skip_queue +field_name: field_skip_queue +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Skip queue' +description: 'Skip the queue and process the submissions directly.' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + on_label: 'On' + off_label: 'Off' +field_type: boolean diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_source.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_source.yml new file mode 100644 index 000000000..ab78fdf4d --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_source.yml @@ -0,0 +1,30 @@ +uuid: 7ea93d46-1289-4858-8d74-3b0c8409bee5 +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_source + - taxonomy.vocabulary.source + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_source +field_name: field_source +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Allowed source(s)' +description: 'Sources that the provider is allowed to post for.' +required: true +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:taxonomy_term' + handler_settings: + target_bundles: + source: source + sort: + field: name + direction: asc + auto_create: false + auto_create_bundle: '' +field_type: entity_reference diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_user.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_user.yml new file mode 100644 index 000000000..b85a753c2 --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_user.yml @@ -0,0 +1,34 @@ +uuid: 5ed037f7-ffc0-42f4-895a-8671d85c2f1e +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_user + content: + - 'user:user:c2c23306-3da1-4ec0-90c7-c96bf89f3b98' + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_user +field_name: field_user +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: User +description: 'Owner of the created documents for the provider.' +required: true +translatable: false +default_value: + - + target_uuid: c2c23306-3da1-4ec0-90c7-c96bf89f3b98 +default_value_callback: '' +settings: + handler: 'default:user' + handler_settings: + target_bundles: null + sort: + field: name + direction: ASC + auto_create: false + filter: + type: _none + include_anonymous: false +field_type: entity_reference diff --git a/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_webhook_url.yml b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_webhook_url.yml new file mode 100644 index 000000000..4076ae38d --- /dev/null +++ b/config/field.field.reliefweb_post_api_provider.reliefweb_post_api_provider.field_webhook_url.yml @@ -0,0 +1,23 @@ +uuid: 9271fcf7-3f86-4b9e-88fa-76150089099f +langcode: en +status: true +dependencies: + config: + - field.storage.reliefweb_post_api_provider.field_webhook_url + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.reliefweb_post_api_provider.field_webhook_url +field_name: field_webhook_url +entity_type: reliefweb_post_api_provider +bundle: reliefweb_post_api_provider +label: 'Webhook URL' +description: 'URL(s) to call with simple information (ex: URL) of a created/updated document.' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + title: 0 + link_type: 16 +field_type: link diff --git a/config/field.storage.node.field_origin.yml b/config/field.storage.node.field_origin.yml index 5fbbbd0d1..c8b0510ab 100644 --- a/config/field.storage.node.field_origin.yml +++ b/config/field.storage.node.field_origin.yml @@ -20,6 +20,9 @@ settings: - value: 2 label: 'Reliefweb product' + - + value: 3 + label: 'API' allowed_values_function: '' module: options locked: false diff --git a/config/field.storage.node.field_post_api_provider.yml b/config/field.storage.node.field_post_api_provider.yml new file mode 100644 index 000000000..4476f8d51 --- /dev/null +++ b/config/field.storage.node.field_post_api_provider.yml @@ -0,0 +1,20 @@ +uuid: 7993dd10-8926-4c2c-ae65-0d4527502749 +langcode: en +status: true +dependencies: + module: + - node + - reliefweb_post_api +id: node.field_post_api_provider +field_name: field_post_api_provider +entity_type: node +type: entity_reference +settings: + target_type: reliefweb_post_api_provider +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_document_url.yml b/config/field.storage.reliefweb_post_api_provider.field_document_url.yml new file mode 100644 index 000000000..13a434172 --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_document_url.yml @@ -0,0 +1,19 @@ +uuid: 229245d7-af72-410a-828e-0a8d22bcd90a +langcode: en +status: true +dependencies: + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.field_document_url +field_name: field_document_url +entity_type: reliefweb_post_api_provider +type: link +settings: { } +module: link +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_file_url.yml b/config/field.storage.reliefweb_post_api_provider.field_file_url.yml new file mode 100644 index 000000000..826a68c4b --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_file_url.yml @@ -0,0 +1,19 @@ +uuid: 11e0f965-d260-4918-b81f-5d9f61d33a97 +langcode: en +status: true +dependencies: + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.field_file_url +field_name: field_file_url +entity_type: reliefweb_post_api_provider +type: link +settings: { } +module: link +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_image_url.yml b/config/field.storage.reliefweb_post_api_provider.field_image_url.yml new file mode 100644 index 000000000..598742f18 --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_image_url.yml @@ -0,0 +1,19 @@ +uuid: 06f080b2-9d92-499e-8aed-615ca77a61c8 +langcode: en +status: true +dependencies: + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.field_image_url +field_name: field_image_url +entity_type: reliefweb_post_api_provider +type: link +settings: { } +module: link +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_notify.yml b/config/field.storage.reliefweb_post_api_provider.field_notify.yml new file mode 100644 index 000000000..d9c455ebd --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_notify.yml @@ -0,0 +1,18 @@ +uuid: 9e96163f-f82f-467f-8711-41e94740252a +langcode: en +status: true +dependencies: + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.field_notify +field_name: field_notify +entity_type: reliefweb_post_api_provider +type: email +settings: { } +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_quota.yml b/config/field.storage.reliefweb_post_api_provider.field_quota.yml new file mode 100644 index 000000000..6b1724228 --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_quota.yml @@ -0,0 +1,20 @@ +uuid: c8b15b59-ea13-41d9-9d5c-4386a94f345f +langcode: en +status: true +dependencies: + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.field_quota +field_name: field_quota +entity_type: reliefweb_post_api_provider +type: integer +settings: + unsigned: false + size: normal +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_rate_limit.yml b/config/field.storage.reliefweb_post_api_provider.field_rate_limit.yml new file mode 100644 index 000000000..1dff1d190 --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_rate_limit.yml @@ -0,0 +1,20 @@ +uuid: 20aba504-c4b4-496e-b138-5d60cf68e14b +langcode: en +status: true +dependencies: + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.field_rate_limit +field_name: field_rate_limit +entity_type: reliefweb_post_api_provider +type: integer +settings: + unsigned: false + size: normal +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_resource_status.yml b/config/field.storage.reliefweb_post_api_provider.field_resource_status.yml new file mode 100644 index 000000000..9a9f72569 --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_resource_status.yml @@ -0,0 +1,48 @@ +uuid: 0e49a2d5-e72b-455f-8b68-a7eb4b78eb83 +langcode: en +status: true +dependencies: + module: + - options + - reliefweb_post_api +id: reliefweb_post_api_provider.field_resource_status +field_name: field_resource_status +entity_type: reliefweb_post_api_provider +type: list_string +settings: + allowed_values: + - + value: draft + label: Draft + - + value: pending + label: Pending + - + value: on-hold + label: On-hold + - + value: to-review + label: 'To review' + - + value: published + label: Published + - + value: archive + label: Archive + - + value: reference + label: Reference + - + value: embargoed + label: Embargoed + - + value: refused + label: Refused + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_skip_queue.yml b/config/field.storage.reliefweb_post_api_provider.field_skip_queue.yml new file mode 100644 index 000000000..7c904cacb --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_skip_queue.yml @@ -0,0 +1,18 @@ +uuid: f0c717e9-6ca8-488f-935b-b61c4647394a +langcode: en +status: true +dependencies: + module: + - reliefweb_post_api +id: reliefweb_post_api_provider.field_skip_queue +field_name: field_skip_queue +entity_type: reliefweb_post_api_provider +type: boolean +settings: { } +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_source.yml b/config/field.storage.reliefweb_post_api_provider.field_source.yml new file mode 100644 index 000000000..21cb34932 --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_source.yml @@ -0,0 +1,20 @@ +uuid: c30134fe-0960-4547-8da8-91f99a2fd066 +langcode: en +status: true +dependencies: + module: + - reliefweb_post_api + - taxonomy +id: reliefweb_post_api_provider.field_source +field_name: field_source +entity_type: reliefweb_post_api_provider +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_user.yml b/config/field.storage.reliefweb_post_api_provider.field_user.yml new file mode 100644 index 000000000..37122af9f --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_user.yml @@ -0,0 +1,20 @@ +uuid: 5ecb0f1f-42e2-49c2-b45b-aceb98765cb2 +langcode: en +status: true +dependencies: + module: + - reliefweb_post_api + - user +id: reliefweb_post_api_provider.field_user +field_name: field_user +entity_type: reliefweb_post_api_provider +type: entity_reference +settings: + target_type: user +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/field.storage.reliefweb_post_api_provider.field_webhook_url.yml b/config/field.storage.reliefweb_post_api_provider.field_webhook_url.yml new file mode 100644 index 000000000..41745c623 --- /dev/null +++ b/config/field.storage.reliefweb_post_api_provider.field_webhook_url.yml @@ -0,0 +1,19 @@ +uuid: e739ac53-b6e5-4e05-aba8-570455069f3b +langcode: en +status: true +dependencies: + module: + - link + - reliefweb_post_api +id: reliefweb_post_api_provider.field_webhook_url +field_name: field_webhook_url +entity_type: reliefweb_post_api_provider +type: link +settings: { } +module: link +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/docker/Dockerfile b/docker/Dockerfile index c43673f5d..770d7c0ca 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -62,6 +62,7 @@ COPY --from=builder /srv/www/composer.patches.json /srv/www/composer.patches.jso COPY --from=builder /srv/www/composer.lock /srv/www/composer.lock COPY --from=builder /srv/www/PATCHES /srv/www/PATCHES COPY --from=builder /srv/www/scripts /srv/www/scripts +COPY --from=builder /srv/www/docker/etc/nginx/map_block_http_methods.conf /etc/nginx/map_block_http_methods.conf COPY --from=builder /srv/www/docker/etc/nginx/apps/drupal/drupal.conf /etc/nginx/apps/drupal/drupal.conf COPY --from=builder /srv/www/docker/etc/nginx/custom /etc/nginx/custom/ COPY --from=builder /srv/www/docker/etc/nginx/sites-enabled/01_uuid.conf /etc/nginx/sites-enabled/01_uuid.conf diff --git a/docker/etc/nginx/custom/04_api_schemas.conf b/docker/etc/nginx/custom/04_api_schemas.conf new file mode 100644 index 000000000..ebce3a04a --- /dev/null +++ b/docker/etc/nginx/custom/04_api_schemas.conf @@ -0,0 +1,13 @@ +## RW post API schemas. +location /post-api-schemas/v2/ { + + location ~ "^/post-api-schemas/v2/(?[a-z][a-z_-]+[a-z]\.json)$" { + ## Allow CORS so that the RW API swagger UI can load the schema. + add_header Access-Control-Allow-Origin '*' always; + add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS' always; + + try_files "/modules/custom/reliefweb_post_api/schemas/v2/$file_name" =404; + } + + return 404; +} diff --git a/docker/etc/nginx/map_block_http_methods.conf b/docker/etc/nginx/map_block_http_methods.conf new file mode 100644 index 000000000..8b8ff1f23 --- /dev/null +++ b/docker/etc/nginx/map_block_http_methods.conf @@ -0,0 +1,18 @@ +## Override the built-in list of permitted HTTP methods since Reliefweb +## needs to permit PUT as well for the new reports posting API. +## +## The original perusio nginx used weird reverse logic, so add a 0 for methods +## that should not be blocked and default 1 "blocked" for the rest. +## +## See https://humanitarian.atlassian.net/browse/RW-892 + +map $request_method $not_allowed_method { + default 1; + GET 0; + HEAD 0; + POST 0; + OPTIONS 0; + PATCH 0; + PUT 0; + DELETE 0; +} diff --git a/html/modules/custom/reliefweb_entities/src/Entity/Report.php b/html/modules/custom/reliefweb_entities/src/Entity/Report.php index fdea3da90..5441ed288 100644 --- a/html/modules/custom/reliefweb_entities/src/Entity/Report.php +++ b/html/modules/custom/reliefweb_entities/src/Entity/Report.php @@ -242,14 +242,15 @@ public function preSave(EntityStorageInterface $storage) { } // Change the status to `embargoed` if there is an embargo date. - if (!empty($this->field_embargo_date->value) && $this->getModerationStatus() !== 'draft') { + $embargo_statuses = ['embargoed', 'to-review', 'published']; + if (!empty($this->field_embargo_date->value) && in_array($this->getModerationStatus(), $embargo_statuses)) { $this->setModerationStatus('embargoed'); $message = strtr('Embargoed (to be automatically published on @date).', [ '@date' => DateHelper::format($this->field_embargo_date->value, 'custom', 'd M Y H:i e'), ]); - $log = trim($this->getRevisionLogMessage()); + $log = trim($this->getRevisionLogMessage() ?? ''); $log = $message . (!empty($log) ? "\n" . $log : ''); $this->setRevisionLogMessage($log); } diff --git a/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php b/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php index ee73f401e..5e5159117 100644 --- a/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php +++ b/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php @@ -102,6 +102,16 @@ protected function addBundleFormAlterations(array &$form, FormStateInterface $fo ); } + $entity = $form_state->getFormObject()?->getEntity(); + // Only keep the "API" origin if the document was submitted via the API. + if (isset($entity) && $entity->hasField('field_post_api_provider') && !empty($entity->field_post_api_provider?->target_id)) { + FormHelper::removeOptions($form, 'field_origin', [0, 1, 2]); + } + // Otherwise hide it. + else { + FormHelper::removeOptions($form, 'field_origin', [3]); + } + // Validate the attachments. $form['#validate'][] = [$this, 'validateAttachment']; diff --git a/html/modules/custom/reliefweb_moderation/src/ModerationServiceBase.php b/html/modules/custom/reliefweb_moderation/src/ModerationServiceBase.php index f056f74b4..30c304123 100644 --- a/html/modules/custom/reliefweb_moderation/src/ModerationServiceBase.php +++ b/html/modules/custom/reliefweb_moderation/src/ModerationServiceBase.php @@ -1022,6 +1022,22 @@ protected function initFilterDefinitions(array $filters = []) { 'form' => 'omnibox', 'widget' => 'search', ], + 'origin' => [ + 'type' => 'field', + 'label' => $this->t('Origin'), + 'field' => 'field_origin', + 'column' => 'value', + 'shortcut' => 'ori', + 'form' => 'omnibox', + 'widget' => 'autocomplete', + 'operator' => 'OR', + 'values' => [ + 0 => 'URL', + 1 => 'Submit mailbox', + 2 => 'ReliefWeb product', + 3 => 'API', + ], + ], 'headline' => [ 'type' => 'field', 'label' => $this->t('Headline'), @@ -2549,6 +2565,34 @@ protected function getEntityAuthorData(EntityModeratedInterface $entity) { return $this->getFilterLink($author_title, $author_parameter, $author_value); } + /** + * Get the entity reviewer. + * + * @param \Drupal\reliefweb_moderation\EntityModeratedInterface $entity + * Entity. + * + * @return \Drupal\Core\GeneratedLink|null + * Link to the page filtered by the user or NULL if the reviewer couldn't be + * determined. + */ + protected function getEntityReviewerData(EntityModeratedInterface $entity) { + $reviewer = $entity->getRevisionUser(); + if (!isset($reviewer)) { + return NULL; + } + + $reviewer_label = $reviewer->label(); + if (empty($reviewer_label)) { + return NULL; + } + + $reviewer_email = $reviewer->getEmail() ?? $this->t('email missing'); + + $parameter = 'selection[reviewer][]'; + $value = $reviewer->id() . ':' . $reviewer_label . ' (' . $reviewer_email . ')'; + return $this->getFilterLink($reviewer_label, $parameter, $value); + } + /** * Get the revision information for the entity. * diff --git a/html/modules/custom/reliefweb_moderation/src/Services/ReportModeration.php b/html/modules/custom/reliefweb_moderation/src/Services/ReportModeration.php index 50d214e32..a7a46e9b4 100644 --- a/html/modules/custom/reliefweb_moderation/src/Services/ReportModeration.php +++ b/html/modules/custom/reliefweb_moderation/src/Services/ReportModeration.php @@ -47,6 +47,9 @@ public function getHeaders() { 'data' => [ 'label' => $this->t('Report'), ], + 'origin' => [ + 'label' => $this->t('Origin'), + ], 'date' => [ 'label' => $this->t('Posted'), 'type' => 'property', @@ -171,8 +174,15 @@ public function getRows(array $results) { '@name' => Link::fromTextAndUrl($key_content_data['name'], Url::fromUri('entity:taxonomy_term/' . $key_content_data['tid']))->toString(), ]); } - // Author. - $details['author'] = $this->getEntityAuthorData($entity); + + // Author and reviewer. + $details['author'] = $this->t('author: @author', [ + '@author' => $this->getEntityAuthorData($entity), + ]); + $details['reviewer'] = $this->t('reviewer: @reviewer', [ + '@reviewer' => $this->getEntityReviewerData($entity), + ]); + $data['details'] = array_filter($details); // Revision information. @@ -181,6 +191,10 @@ public function getRows(array $results) { // Filter out empty data. $cells['data'] = array_filter($data); + // Retrieve the origin of the document. + $options = $entity->field_origin->first()->getPossibleOptions(); + $cells['origin'] = $options[$entity->field_origin->value] ?? $this->t('N/A'); + // Date cell. $cells['date'] = [ 'date' => $this->getEntityCreationDate($entity), @@ -203,8 +217,10 @@ public function getStatuses() { 'to-review' => $this->t('To review'), 'published' => $this->t('Published'), 'embargoed' => $this->t('Embargoed'), - 'archive' => $this->t('Archived'), 'reference' => $this->t('Reference'), + 'pending' => $this->t('Pending'), + 'refused' => $this->t('Refused'), + 'archive' => $this->t('Archived'), ]; } @@ -214,6 +230,7 @@ public function getStatuses() { public function getFilterDefaultStatuses() { $statuses = $this->getFilterStatuses(); unset($statuses['archive']); + unset($statuses['refused']); return array_keys($statuses); } @@ -239,6 +256,16 @@ public function getEntityFormSubmitButtons($status, EntityModeratedInterface $en ], ]; + // Add the extra buttons to manage content submitted via the API. + if ($entity->hasField('field_post_api_provider') && !empty($entity->field_post_api_provider?->target_id)) { + $buttons['pending'] = [ + '#value' => $this->t('Pending'), + ]; + $buttons['refused'] = [ + '#value' => $this->t('Refused'), + ]; + } + // @todo replace with permission. if (UserHelper::userHasRoles(['administrator', 'webmaster'])) { $buttons['archive'] = [ @@ -326,6 +353,7 @@ protected function initFilterDefinitions(array $filters = []) { 'headline', 'bury', 'key_content', + 'origin', ]); // Values are hardcoded to avoid the use of a query. diff --git a/html/modules/custom/reliefweb_moderation/templates/reliefweb-moderation-table.html.twig b/html/modules/custom/reliefweb_moderation/templates/reliefweb-moderation-table.html.twig index 0226c4388..80b4eb5f7 100644 --- a/html/modules/custom/reliefweb_moderation/templates/reliefweb-moderation-table.html.twig +++ b/html/modules/custom/reliefweb_moderation/templates/reliefweb-moderation-table.html.twig @@ -40,6 +40,8 @@ {% for id, cell in row %} {% if id == 'edit' %} diff --git a/html/modules/custom/reliefweb_post_api/README.md b/html/modules/custom/reliefweb_post_api/README.md new file mode 100644 index 000000000..662ade960 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/README.md @@ -0,0 +1,20 @@ +ReliefWeb POST API +================== + + +This module provides a simple POST API to allow partners to submit content. + +TODO +---- + +- [ ] Better authentication +- [ ] Associated user with API key? +- [ ] Use different users to create content instead of system user? +- [ ] Notify poster when content is created? +- [ ] How to give feedback? + --> Generate UUID, return it when submitting? + --> Add other endpoint to query status (404, refused, pending, published?) +- [ ] Limit the content types the provider can post +- [ ] Limit the fields the provider can populate +- [ ] Validate report original publication date so it cannot be in the future? +- [ ] Use a custom fiedable entity for the providers? diff --git a/html/modules/custom/reliefweb_post_api/drush.services.yml b/html/modules/custom/reliefweb_post_api/drush.services.yml new file mode 100644 index 000000000..2969a96e4 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/drush.services.yml @@ -0,0 +1,6 @@ +services: + reliefweb_post_api.commands: + class: \Drupal\reliefweb_post_api\Commands\ReliefWebPostApiCommands + arguments: ['@reliefweb_post_api.queue.database', '@plugin.manager.reliefweb_post_api.content_processor'] + tags: + - { name: drush.command } diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.info.yml b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.info.yml new file mode 100644 index 000000000..5e853b6e6 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.info.yml @@ -0,0 +1,7 @@ +type: module +name: ReliefWeb POST API +description: 'Provides as simple POST API.' +package: reliefweb +core_version_requirement: ^10 +dependencies: + - drupal:reliefweb_utility diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.install b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.install new file mode 100644 index 000000000..a5032207f --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.install @@ -0,0 +1,55 @@ + [ + 'provider_id' => [ + 'description' => 'Provider ID.', + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + 'default' => 0, + ], + 'request_count' => [ + 'description' => 'Number of requests since last reset (daily).', + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => FALSE, + 'default' => 0, + ], + 'last_request_time' => [ + 'description' => 'Timestamp of the last request.', + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => FALSE, + 'default' => 0, + ], + ], + 'primary key' => ['provider_id'], + ]; + + return $schema; +} + +/** + * Implements hook_update_N(). + * + * Add the rate limits table. + */ +function reliefweb_post_api_update_10001(array &$sandbox) { + $schema = \Drupal::database()->schema(); + if (!$schema->tableExists('reliefweb_post_api_rate_limit')) { + $schema->createTable('reliefweb_post_api_rate_limit', reliefweb_post_api_schema()['reliefweb_post_api_rate_limit']); + } +} diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.action.yml b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.action.yml new file mode 100644 index 000000000..ec132e3e0 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.action.yml @@ -0,0 +1,5 @@ +reliefweb_post_api_provider.add: + route_name: entity.reliefweb_post_api_provider.add_form + title: 'Add provider' + appears_on: + - entity.reliefweb_post_api_provider.collection diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.menu.yml b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.menu.yml new file mode 100644 index 000000000..1bef430a5 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.menu.yml @@ -0,0 +1,6 @@ +entity.reliefweb_post_api_provider.collection: + title: 'ReliefWeb POST API providers' + route_name: entity.reliefweb_post_api_provider.collection + description: 'List of ReliefWeb POST API provider entities.' + parent: system.admin_structure + weight: 110 diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.task.yml b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.task.yml new file mode 100644 index 000000000..2b7d8a7a0 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.links.task.yml @@ -0,0 +1,17 @@ +entity.reliefweb_post_api_provider.collection: + title: List + route_name: entity.reliefweb_post_api_provider.collection + base_route: entity.reliefweb_post_api_provider.collection + +entity.reliefweb_post_api_provider.canonical: + title: View + route_name: entity.reliefweb_post_api_provider.canonical + base_route: entity.reliefweb_post_api_provider.canonical +entity.reliefweb_post_api_provider.edit_form: + title: Edit + route_name: entity.reliefweb_post_api_provider.edit_form + base_route: entity.reliefweb_post_api_provider.canonical +entity.reliefweb_post_api_provider.delete_form: + title: Delete + route_name: entity.reliefweb_post_api_provider.delete_form + base_route: entity.reliefweb_post_api_provider.canonical diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.module b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.module new file mode 100644 index 000000000..bb3f33d3d --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.module @@ -0,0 +1,25 @@ +getStorage($entity_type_id)->load($entity_id); + if (!empty($entity)) { + Provider::notifyProvider($entity); + } + } +} diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.permissions.yml b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.permissions.yml new file mode 100644 index 000000000..66332b836 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.permissions.yml @@ -0,0 +1,4 @@ +administer reliefweb post api providers: + title: 'Administer ReliefWeb POST API providers' + description: 'Administer ReliefWeb POST API providers.' + restrict access: true diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.routing.yml b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.routing.yml new file mode 100644 index 000000000..3aa5385a0 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.routing.yml @@ -0,0 +1,27 @@ +reliefweb_post_api.post: + path: '/api/v2/{resource}/{uuid}' + defaults: + _controller: '\Drupal\reliefweb_post_api\Controller\ReliefWebPostApi::postContent' + # The controller validates the supported methods. + methods: + - HEAD + - OPTIONS + - GET + - POST + - PATCH + - PUT + - DELETE + requirements: + _access: 'TRUE' + resource: '^[a-z][a-z_-]+[a-z]$' + uuid: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$' + +reliefweb_post_api.schema: + path: '/post-api-schemas/v2/{schema}' + defaults: + _controller: '\Drupal\reliefweb_post_api\Controller\ReliefWebPostApi::getJsonSchema' + methods: + - GET + requirements: + _access: 'TRUE' + schema: '^[a-z][a-z_-]+[a-z]\.json$' diff --git a/html/modules/custom/reliefweb_post_api/reliefweb_post_api.services.yml b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.services.yml new file mode 100644 index 000000000..061c9981e --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/reliefweb_post_api.services.yml @@ -0,0 +1,12 @@ +services: + plugin.manager.reliefweb_post_api.content_processor: + class: Drupal\reliefweb_post_api\Plugin\ContentProcessorPluginManager + parent: default_plugin_manager + theme.negotiator.reliefweb_post_api: + class: Drupal\reliefweb_post_api\Theme\ThemeNegotiator + tags: + - { name: theme_negotiator, priority: 0 } + reliefweb_post_api.queue.database: + class: Drupal\reliefweb_post_api\Queue\ReliefWebPostApiDatabaseQueueFactory + parent: queue.database + arguments: ['@datetime.time'] diff --git a/html/modules/custom/reliefweb_post_api/schemas/v2/job.json b/html/modules/custom/reliefweb_post_api/schemas/v2/job.json new file mode 100644 index 000000000..3e302e9f8 --- /dev/null +++ b/html/modules/custom/reliefweb_post_api/schemas/v2/job.json @@ -0,0 +1,169 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://reliefweb.int/post-api-schemas/v2/job.json", + "title": "ReliefWeb POST API schema - job resource", + "type": "object", + "properties": { + "url": { + "description": "Unique URL to identify the job posting. Use the original canonical url if available.", + "type": "string", + "format": "iri", + "maxLength": 2048 + }, + "uuid": { + "description": "The universally unique identifier (UUID) version 5 generated from the URL property above, with the namespace: '8e27a998-c362-5d1f-b152-d474e1d36af2'.", + "type": "string", + "format": "uuid" + }, + "title": { + "description": "Job title. The best job titles are brief and specific. Please refrain from indicating location, salary and other details in the title, if possible.", + "type": "string", + "minLength": 10, + "maxLength": 255, + "allOf": [ + { + "description": "Must contain letters (any language).", + "pattern": "\\p{L}+" + }, + { + "description": "No control characters or separators except for spaces.", + "pattern": "^([^\\p{Z}\\p{C}]|[ \u3000])+$" + } + ], + "not": { + "description": "No leading, trailing or consecutive spaces.", + "pattern": "(?:^[ \u3000]|[ \u3000]$|[ \u3000]{2,})" + } + }, + "source": { + "description": "Job source as a single ID from https://api.reliefweb.int/v1/sources.", + "type": "array", + "items": { + "type": "integer" + }, + "minItems": 1, + "maxItems": 1 + }, + "closing_date": { + "description": "Closing date (ISO 8601) of the job. Please make sure it matches the closing date on your ad and/or job application portal, if applicable.", + "type": "string", + "format": "date-time" + }, + "body": { + "description": "Job description in markdown or html (supported tags: