Commit 3c0c0056 authored by Chris Shantz's avatar Chris Shantz
Browse files

Merge branch '1.0.x' into prod/1.0.x

parents 791a2784 9101ae8f
langcode: en
status: true
dependencies: { }
id: inline_blockuw_cbl_image
block_id: 'inline_block:uw_cbl_image'
id: uw_lbb_image
block_id: uw_cbl_image
category: uw_bc_content
label: 'Full width image'
label: Image
weight: 0
image_path: images/layout_builder_browser/fullwidthimage.svg
image_path_base: 'theme:uw_fdsu_theme_resp'
image_alt: ''
image_alt: Image
......@@ -30,12 +30,24 @@ entity_type_groups:
open_graph: open_graph
twitter_cards: twitter_cards
schema_article: schema_article
uw_ct_opportunity:
basic: basic
advanced: advanced
open_graph: open_graph
twitter_cards: twitter_cards
schema_job_posting: schema_job_posting
uw_ct_profile:
basic: basic
advanced: advanced
open_graph: open_graph
twitter_cards: twitter_cards
schema_web_page: schema_person
uw_ct_service:
basic: basic
advanced: advanced
open_graph: open_graph
twitter_cards: twitter_cards
schema_web_page: schema_web_page
uw_ct_web_page:
basic: basic
advanced: advanced
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: service_categories_path_pattern
label: 'Service categories path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_audience
label: 'Audience path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_blog_tags
label: 'Blog tags path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_catalog_categories
label: 'Catalog categories path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_catalogs
label: 'Catalogs path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_event_tags
label: 'Event tags path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_event_types
label: 'Event types path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_faculties_and_schools
label: 'Faculties and schools path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_news_tags
label: 'News tags path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_opportunity_employment_type
label: 'Opportunity: employment type path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_opportunity_pay_type
label: 'Opportunity: rate of pay type path pattern'
......
......@@ -2,7 +2,6 @@ langcode: en
status: true
dependencies:
module:
- ctools
- taxonomy
id: uw_path_opportunity_type
label: 'Opportunity: type path pattern'
......
......@@ -214,6 +214,7 @@ display:
exposed: false
expose:
label: ''
field_identifier: label
entity_type: menu
plugin_id: standard
title: Menus
......
......@@ -164,6 +164,7 @@ display:
exposed: false
expose:
label: ''
field_identifier: name
entity_type: taxonomy_vocabulary
plugin_id: standard
title: Taxonomy
......
services:
uw_cfg_common.commands:
class: Drupal\uw_cfg_common\Commands\UwDrushCommands
arguments: ['@entity_type.manager']
arguments: ['@entity_type.manager', '@uw_cfg_common.missing_blocks']
tags:
- { name: drush.command }
......@@ -3,8 +3,10 @@
namespace Drupal\uw_cfg_common\Commands;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\uw_cfg_common\Service\UWMissingBlocks;
use Drupal\uw_cfg_common\UwRoles\UwRoles;
use Drush\Commands\DrushCommands;
use Drush\Utils\StringUtils;
/**
* Drush commands for uw_cfg_common module.
......@@ -20,11 +22,19 @@ class UwDrushCommands extends DrushCommands {
*/
protected $entityTypeManager;
/**
* Service to deal with missing blocks.
*
* @var \Drupal\uw_cfg_common\Service\UWMissingBlocks
*/
protected $missingBlocks;
/**
* {@inheritDoc}
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager) {
public function __construct(EntityTypeManagerInterface $entityTypeManager, UWMissingBlocks $missingBlocks) {
$this->entityTypeManager = $entityTypeManager;
$this->missingBlocks = $missingBlocks;
}
/**
......@@ -61,4 +71,100 @@ class UwDrushCommands extends DrushCommands {
$this->logger()->success('All permissions set.');
}
/**
* Removes missing blocks from unsaved layout.
*
* If not existing block is in temp storage for layout build (unsaved)
* changes and layout tab is opened this can result in server error. This
* function will check each block existence (loading block revision) and
* if block is loaded successfully it will leave it in temp storage.
* Otherwise, block will be removed from unsaved changes.
*
* @param string|null $nids
* List (CSV) of nodes to check, if empty command will check all nodes.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*
* @command uw:missing-blocks-unsaved
* @aliases uwblocksunsaved
* @usage drush uwblocksunsaved "102,201,304"
* - Checks nodes with id 102,201,304 and remove not existing blocks.
*/
public function removeBlocksFromUnsavedLayout(string $nids = NULL): void {
$nodes = NULL;
if ($nids) {
$nodes = StringUtils::csvToArray($nids);
}
$this->missingBlocks->removeMissingBlocksFromUnsaved($nodes);
$this->logger()->success('Missing blocks checks complete on unsaved.');
}
/**
* Removes missing blocks from saved layouts.
*
* Scans all nodes, checks each for missing blocks in layout builder.
* Removes missing blocks if found, and saves node. Checks revisions also.
*
* @param string|null $nids
* List (CVS) of nodes to check, if empty command will check all nodes.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*
* @command uw:missing-blocks-saved
* @aliases uwblockssaved
* @usage drush uwblockssaved 102
* - Checks node (nid: 102) for any missing blocks.
* @usage drush uwblockssaved "103,104,105,106"
* - Checks nodes 103, 104, 105, 106 for missing blocks.
*/
public function removeBlockFromLayout(string $nids = NULL): void {
$nodes = NULL;
if ($nids) {
$nodes = StringUtils::csvToArray($nids);
}
$this->missingBlocks->removeMissingBlocksFromSaved($nodes);
$this->logger()->success('Missing blocks checks complete on saved.');
}
/**
* Command to combine saved and unsaved removal of missing blocks.
*
* @param string|null $nids
* List of node ids to process only.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*
* @command uw:missing-blocks
* @aliases uwblocks
* @usage drush uwblocks
* - Run checkup on all nodes. This may take some time to complete.
* @usage drush uwblocks 102
* - Checks node (nid: 12) for any missing blocks(covers saved and unsaved).
* @usage drush uwblocks "103,104,105,106"
* - Checks nodes 103, 104, 105, 106 for missing blocks (saved and unsaved).
*/
public function removeMissingBlocks(string $nids = NULL): void {
$nodes = NULL;
if ($nids) {
$nodes = StringUtils::csvToArray($nids);
}
$this->logger()->notice('Running clean up for saved nodes.');
$this->missingBlocks->removeMissingBlocksFromSaved($nodes);
$this->logger()->notice('Running clean up for unsaved nodes.');
$this->missingBlocks->removeMissingBlocksFromUnsaved($nodes);
$this->logger()->success('Missing blocks removed from saved and unsaved layouts.');
}
}
......@@ -76,9 +76,27 @@ class UwContentModerationForm extends ConfirmFormBase {
* A AccessResult object.
*/
public function access(int $nid, AccountInterface $account): AccessResult {
// Ensure that anonymous users can not
// access this form.
if ($account->isAnonymous()) {
return AccessResult::forbidden();
}
// Ensure that home page access is respected.
if (UWService::nodeIsHomePage($nid) && !$account->hasPermission('bypass home page protection')) {
return AccessResult::forbidden();
}
// Get the node.
$node = $this->entityTypeManager->getStorage('node')->load($nid);
// If the user does not have permission to edit the node
// forbid them from the link.
if (!$account->hasPermission('edit any ' . $node->bundle() . ' content')) {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
......
<?php
namespace Drupal\uw_cfg_common\Service;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
/**
* Service to fix missing blocks in saved and unsaved nodes.
*/
class UWMissingBlocks {
/**
* Entity type manager from core.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Key value expirable service from core.
*
* @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactory
*/
protected $keyValue;
/**
* Layout builder temporary repository service from core.
*
* @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface
*/
protected $temporaryRepository;
/**
* Default class constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Entity type manager service from core.
* @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactory $keyValue
* Key value expirable service from core.
* @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $temporaryRepository
* Layout builder temporary repository service from core.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, KeyValueExpirableFactory $keyValue, LayoutTempstoreRepositoryInterface $temporaryRepository) {
$this->entityTypeManager = $entityTypeManager;
$this->keyValue = $keyValue;
$this->temporaryRepository = $temporaryRepository;
}
/**
* Checks nodes for missing blocks in unsaved changes.
*
* It will load only nodes that have unsaved changes, based on result from
* temporary repository table (key_value_expire) with name
* (tempstore.shared.layout_builder.section_storage.overrides).
*
* @param array|null $nodes
* List of nodes to check, defaults to every node.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function removeMissingBlocksFromUnsaved(array $nodes = NULL): void {
$temp_nodes = $this->keyValue->get('tempstore.shared.layout_builder.section_storage.overrides')->getAll();
foreach ($temp_nodes as $override_id => $storage) {
$ids = explode('.', $override_id);
if ((!empty($nodes) && in_array($ids[1], $nodes)) || empty($nodes)) {
$layout = $storage->data['section_storage'] ?? NULL;
if ($this->removeMissingBlocksProcessLayout($layout)) {
$storage->data['section_storage'] = $layout;
$this->keyValue->get('tempstore.shared.layout_builder.section_storage.overrides')->set($override_id, $storage);
}
}
}
}
/**
* Checks saved nodes for missing blocks (includes revisions).
*
* @param array|null $only_nodes
* List of nodes to check. If omitted it will load all blocks and perform
* checks on them. This may be timely process.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function removeMissingBlocksFromSaved(array $only_nodes = NULL): void {
// Loading either all nodes if only_nodes is empty, or just nodes that
// are passed as arguments. Non-existing node ids will not be loaded.
$nodes = $this->entityTypeManager->getStorage('node')->loadMultiple($only_nodes);
foreach ($nodes as $node) {
$layout = $node->get('layout_builder__layout');
if ($this->removeMissingBlocksProcessLayout($layout)) {
$node->save();
}
// Revisions.
$vids = $this->entityTypeManager->getStorage('node')->revisionIds($node);
foreach ($vids as $vid) {
$revision_node = $this->entityTypeManager->getStorage('node')->loadRevision($vid);
$layout = $revision_node->get('layout_builder__layout');
if ($this->removeMissingBlocksProcessLayout($layout)) {
$revision_node->save();
}
}
}
}
/**
* Checks layout for missing blocks.
*
* @param \Drupal\layout_builder\Field\LayoutSectionItemList|\Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage $layout
* Layout to check.
*
* @return bool
* Were there any changes that would require save on entity.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
private function removeMissingBlocksProcessLayout($layout): bool {
$save_required = FALSE;
$sections = $layout->getSections();
foreach ($sections as $section) {
$components = $section->getComponents();
foreach ($components as $component) {
$config = $component->get('configuration');
if (!empty($config['block_revision_id'])) {
$block_revision = $this->entityTypeManager->getStorage('block_content')
->loadRevision($config['block_revision_id']);
if (!$block_revision) {
$section->removeComponent($component->getUuid());
$save_required = TRUE;
}
}
}
}
return $save_required;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment