Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
… into feat/SLB-288
  • Loading branch information
HagerDakroury committed May 17, 2024
2 parents 954d6dc + 3dfe283 commit fb306dd
Show file tree
Hide file tree
Showing 37 changed files with 920 additions and 63 deletions.
1 change: 1 addition & 0 deletions .idea/prettier.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions apps/cms/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
},
"amazeelabs/silverback_gatsby": {
"Autosave preview": "./patches/fetch-entity.patch"
},
"drupal/gutenberg": {
"Gutenberg enabled hook": "https://www.drupal.org/files/issues/2024-05-07/gutenberg_enabled_hook_3445677-2.patch"
}
},
"patchLevel": {
Expand Down
103 changes: 103 additions & 0 deletions apps/cms/config/sync/core.entity_form_display.node.page.split.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
uuid: a39d0011-2ebf-4b18-a9f0-8b5aeff5b9aa
langcode: en
status: true
dependencies:
config:
- core.entity_form_mode.node.split
- field.field.node.page.body
- field.field.node.page.field_metatags
- node.type.page
- workflows.workflow.basic
module:
- content_moderation
- metatag
- path
id: node.page.split
targetEntityType: node
bundle: page
mode: split
content:
created:
type: datetime_timestamp
weight: 3
region: content
settings: { }
third_party_settings: { }
field_metatags:
type: metatag_firehose
weight: 11
region: content
settings:
sidebar: true
use_details: true
third_party_settings: { }
langcode:
type: language_select
weight: 1
region: content
settings:
include_locked: true
third_party_settings: { }
moderation_state:
type: moderation_state_default
weight: 9
region: content
settings: { }
third_party_settings: { }
path:
type: path
weight: 7
region: content
settings: { }
third_party_settings: { }
promote:
type: boolean_checkbox
weight: 5
region: content
settings:
display_label: true
third_party_settings: { }
status:
type: boolean_checkbox
weight: 10
region: content
settings:
display_label: true
third_party_settings: { }
sticky:
type: boolean_checkbox
weight: 6
region: content
settings:
display_label: true
third_party_settings: { }
title:
type: string_textfield
weight: 0
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
translation:
weight: 4
region: content
settings: { }
third_party_settings: { }
uid:
type: entity_reference_autocomplete
weight: 2
region: content
settings:
match_operator: CONTAINS
match_limit: 10
size: 60
placeholder: ''
third_party_settings: { }
url_redirects:
weight: 8
region: content
settings: { }
third_party_settings: { }
hidden:
body: true
11 changes: 11 additions & 0 deletions apps/cms/config/sync/core.entity_form_mode.node.split.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
uuid: 5f26940d-fd06-41e0-8e59-9dfcdc9c86df
langcode: en
status: true
dependencies:
module:
- node
id: node.split
label: Split
description: ''
targetEntityType: node
cache: true
1 change: 1 addition & 0 deletions apps/cms/config/sync/core.extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module:
dropzonejs: 0
dynamic_page_cache: 0
editor: 0
entity_create_split: 0
entity_usage: 0
environment_indicator: 0
field: 0
Expand Down
6 changes: 4 additions & 2 deletions apps/cms/config/sync/entity_usage.settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ local_task_enabled_entity_types:
- node
track_enabled_source_entity_types:
- node
- content_moderation_state
- block_content
- content_moderation_state
- menu_link_content
- media
- redirect
- shortcut
- path_alias
track_enabled_target_entity_types:
- node
- content_moderation_state
- block_content
- content_moderation_state
- menu_link_content
- media
- redirect
Expand All @@ -32,6 +32,8 @@ track_enabled_plugins:
- html_link
- ckeditor_image
- block_field
- gutenberg_linked_content
- gutenberg_referenced_content
- gutenberg_media_embed
track_enabled_base_fields: false
site_domains: { }
Expand Down
2 changes: 1 addition & 1 deletion apps/cms/config/sync/linkit.linkit_profile.gutenberg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ matchers:
bundles:
document: document
group_by_bundle: 0
substitution_type: null
substitution_type: canonical
limit: '100'
weight: -9
2 changes: 0 additions & 2 deletions apps/cms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
"content:import": "pnpm drush php-script web/modules/custom/test_content/import.php",
"config:export": "pnpm drush cex -y",
"config:import": "pnpm drush -y cim",
"schema:test": "pnpm jest --testMatch '<rootDir>/generated/__tests__/test-queries.js' --passWithNoTests",
"schema:test:update": "pnpm schema:test -u",
"import-translations": "pnpm drush scr scripts/translations-import.php"
},
"peerDependencies": {
Expand Down
Empty file removed apps/cms/patches/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions apps/preview/.lagoon.env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
PROJECT_NAME="example"
DRUPAL_URL="https://nginx.${LAGOON_ENVIRONMENT}.${LAGOON_PROJECT}.ch4.amazee.io"
71 changes: 71 additions & 0 deletions packages/drupal/custom/custom.module
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\StreamWrapper\LocalStream;
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Drupal\Core\Utility\Error as ErrorUtil;
use Drupal\file\Entity\File;
use Drupal\media\Entity\Media;
Expand Down Expand Up @@ -90,6 +92,75 @@ function custom_silverback_gutenberg_link_processor_outbound_url_alter(
}
}

/**
* Implements hook_silverback_gutenberg_link_processor_inbound_link_alter().
* @param \DOMElement $link
* @param \Drupal\silverback_gutenberg\LinkProcessor $linkProcessor
*
* @return void
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
function custom_silverback_gutenberg_link_processor_inbound_link_alter(
\DOMElement $link,
LinkProcessor $linkProcessor
) {
// For inbound links (when data gets saved), if the link points to a public
// file, then we want to replace the href value with "media/uuid/edit" and
// also make sure the data-id and data-entity-type attributes have the proper
// values (the uuid and the 'media' value). This is a special case for media,
// because the url of the media item is replaced by
// custom_silverback_gutenberg_link_processor_outbound_url_alter() with the
// file path, so now on inbound we need to basically do the opposite. This is
// needed so that the entity usage integration works properly (where the
// data-id and data-entity-type attributes are checked).
$href = $link->getAttribute('href');
/* @var \Drupal\Core\StreamWrapper\StreamWrapperManager $wrapperManager */
$wrapperManager = \Drupal::service('stream_wrapper_manager');
/* @var \Drupal\Core\StreamWrapper\StreamWrapperInterface[] $visibleWrappers */
$visibleWrappers = $wrapperManager->getWrappers(StreamWrapperInterface::VISIBLE);
foreach ($visibleWrappers as $scheme => $wrapperInfo) {
$wrapper = $wrapperManager->getViaScheme($scheme);
// We are only handle local streams for now.
if (!$wrapper instanceof LocalStream) {
continue;
}
if (!str_starts_with($href, '/' . $wrapper->getDirectoryPath() . '/')) {
continue;
}
// When searching for a file inside the database, the wrapper uri is used
// instead of the directory path. That is why we need the wrapper in the
// first place.
$fileuri = str_replace('/' . $wrapper->getDirectoryPath() . '/', $wrapper->getUri(), urldecode($href));
$files = \Drupal::entityTypeManager()
->getStorage('file')
->loadByProperties(['uri' => $fileuri]);
// No files found, just continue to the next wrapper.
if (empty($files)) {
continue;
}
$file = array_shift($files);
$usageList = \Drupal::service('file.usage')->listUsage($file);
// If the media file usage list is empty, then this is probably some kind of
// orphan file, or tracked by some other entity type.
if (empty($usageList['file']['media'])) {
continue;
}
$mids = array_keys($usageList['file']['media']);
$mid = reset($mids);
$media = Media::load($mid);
if (empty($media)) {
continue;
}
// If we got here, we found a matching media item, so we can populate the
// link metadata with its values and just break out of the wrappers loop.
$link->setAttribute('href', '/media/' . $media->uuid() . '/edit');
$link->setAttribute('data-id', $media->uuid());
$link->setAttribute('data-entity-type', 'media');
break;
}
}

/**
* Implements hook_form_alter().
*
Expand Down
13 changes: 13 additions & 0 deletions packages/drupal/entity_create_split/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Entity Create Split

A Drupal module which exposes routes to split an entity create form into two parts:
- on the first step, only the required fields are presented. After submitting the form, a entity is already created
- the second step is actually just the entity edit form, containing all the other optional form fields.

To enable this feature, you must create a form mode with the machine name "split" and enable it on the bundle for which you want to have this feature.

## Special case for the Gutenberg editor

The Gutenberg editor does a lot of alterations on the create form. For this reason, it is better that the form alter hook of the gutenberg module to not run at all. This is not easy possible, so right now the easiest approach is to just patch the module with the patch from https://www.drupal.org/project/gutenberg/issues/3445677/

The functionality should also work without the patch, but the initial form will not look that nice.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: Entity Create Split
type: module
description: 'Provides a route for splitting the entity creation in two steps: first for the mandatory fields and a second one, which is actually the edit form, for the rest of the fields.'
package: Custom
core_version_requirement: ^9 || ^10
67 changes: 67 additions & 0 deletions packages/drupal/entity_create_split/entity_create_split.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

/**
* @file
* Provides a route for splitting the entity creation in two steps: first for
* the mandatory fields and a second one, which is actually the edit form, for
* the rest of the fields.
*/

use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\ContentEntityType;
use Drupal\Core\Entity\EntityInterface;

/**
* Implements hook_entity_type_build().
*/
function entity_create_split_entity_type_build(array &$entity_types) {
foreach ($entity_types as $entity_type) {
if ($entity_type instanceof ContentEntityType) {
$entity_type->setFormClass('split', $entity_type->getFormClass('default'));
}
}
}

/**
* Implements hook_gutenberg_enabled().
*/
function entity_create_split_gutenberg_enabled(EntityInterface $entity) {
if (isset($entity->disableGutenberg) && $entity->disableGutenberg === TRUE) {
return FALSE;
}
}

/**
* Implements hook_form_alter().
*/
function entity_create_split_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
$formObject = $form_state->getFormObject();
if ($formObject instanceof ContentEntityForm && $formObject->getFormDisplay($form_state)->getMode() === 'split') {
if (empty($form['#submit'])) {
$form['#submit'] = [];
}
$form['#submit'][] = 'entity_create_split_submit_redirect';
if (!empty($form['actions']['submit']['#submit'])) {
$form['actions']['submit']['#submit'][] = 'entity_create_split_submit_redirect';
}
}
}

/**
* Submit handler for the entity create from, to redirect the user to the entity
* edit form.
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return void
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
function entity_create_split_submit_redirect(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {
/* @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $form_state->getFormObject()->getEntity();
if (!empty($entity) && $entity->id()) {
$url = $entity->toUrl('edit-form');
$form_state->setRedirectUrl($url);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
entity_create_split.create:
path: '/entity/create/{entity_type}/{bundle}'
defaults:
_controller: '\Drupal\entity_create_split\Controller\EntityCreateSplitController::createForm'
_title_callback: '\Drupal\entity_create_split\Controller\EntityCreateSplitController::getTitle'
requirements:
_custom_access: '\Drupal\entity_create_split\Controller\EntityCreateSplitController::access'
options:
_admin_route: TRUE
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
entity_create_split.route_subscriber:
class: Drupal\entity_create_split\EventSubscriber\EntityCreateSplitRequestSubscriber
arguments:
- "@current_route_match"
- "@entity_type.manager"
- "@entity_display.repository"
tags:
- { name: event_subscriber }
Loading

0 comments on commit fb306dd

Please sign in to comment.