Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • wcms/uw_cfg_common
1 result
Show changes
Commits on Source (26)
langcode: en
status: true
dependencies:
module:
- node
- options
id: node.field_uw_type_of_media
field_name: field_uw_type_of_media
entity_type: node
type: list_string
settings:
allowed_values:
-
value: image
label: Image
allowed_values_function: ''
module: options
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
<?php
namespace Drupal\uw_cfg_common\Helpers;
use Drupal\features\FeaturesManagerInterface;
use Drupal\features\ConfigurationItem;
use Drupal\features\Package;
use Drupal\config_update\ConfigRevertInterface;
/**
* Class to perform feature revert.
*/
class UwFeatureRevert {
/**
* Features manager.
*
* @var \Drupal\features\FeaturesManagerInterface
*/
private $featuresManager;
/**
* Config update revert.
*
* @var \Drupal\config_update\ConfigRevertInterface
*/
private $configRevert;
/**
* Default constructor.
*
* @param \Drupal\features\FeaturesManagerInterface $featuresManager
* Features manager.
* @param Drupal\config_update\ConfigRevertInterface $configRevert
* The config update revert.
*/
public function __construct(
FeaturesManagerInterface $featuresManager,
ConfigRevertInterface $configRevert
) {
$this->featuresManager = $featuresManager;
$this->configRevert = $configRevert;
}
/**
* Load the features from the module.
*
* @param string $module
* Array of modules.
* @param bool $any
* Flag for all modules.
*
* @return \Drupal\features\Package
* The list of packages.
*/
private function drushFeaturesLoadFeature(string $module, bool $any = FALSE): Package {
// Get the features manager.
$manager = $this->featuresManager;
// Get teh feature.
$feature = $manager->getPackage($module);
// Check if this get any or not a feature module.
if ($any && !isset($feature)) {
// See if this is a non-features module.
$module_handler = \Drupal::moduleHandler();
$modules = $module_handler->getModuleList();
// If it is not a feature module, set it up as one.
if (!empty($modules[$module])) {
$extension = $modules[$module];
$feature = $manager->initPackageFromExtension($extension);
$config = $manager->listExtensionConfig($extension);
$feature->setConfig($config);
$feature->setStatus(FeaturesManagerInterface::STATUS_INSTALLED);
}
}
return $feature;
}
/**
* Copy from file features.drush.inc.
*/
public function import($args) {
// Determine if revert should be forced.
$force = TRUE;
// Determine if -y was supplied. If so, we can filter out needless output
// from this command.
$skip_confirmation = TRUE;
// Get the feature manager.
$manager = $this->featuresManager;
// Get the config update revert.
$config_revert = $this->configRevert;
// Parse list of arguments.
$modules = [];
foreach ($args as $arg) {
$arg = explode(':', $arg);
$module = array_shift($arg);
$component = array_shift($arg);
if (isset($module)) {
if (empty($component)) {
// If we received just a feature name, this means that we need all of
// its components.
$modules[$module] = TRUE;
}
elseif ($modules[$module] !== TRUE) {
if (!isset($modules[$module])) {
$modules[$module] = [];
}
$modules[$module][] = $component;
}
}
}
// Process modules.
foreach ($modules as $module => $components_needed) {
// Setup the modules array.
$dt_args['@module'] = $module;
// Get the feature information.
$feature = $this->drushFeaturesLoadFeature($module, TRUE);
// If the feature is empty, throw an error and exit.
if (empty($feature)) {
\Drupal::logger('UwFeatureRevert')
->error('No such feature is available: @module', $dt_args);
return;
}
// If the feature status is not set as active, throw error and exit.
if ($feature->getStatus() != FeaturesManagerInterface::STATUS_INSTALLED) {
\Drupal::logger('UwFeatureRevert')
->error('No such feature is installed: @module', $dt_args);
return;
}
// Forcefully revert all components of a feature.
if ($force) {
$components = $feature->getConfigOrig();
}
// Only revert components that are detected to be Overridden.
else {
$components = $manager->detectOverrides($feature);
$missing = $manager->reorderMissing($manager->detectMissing($feature));
// Be sure to import missing components first.
$components = array_merge($missing, $components);
}
if (!empty($components_needed) && is_array($components_needed)) {
$components = array_intersect($components, $components_needed);
}
if (empty($components)) {
\Drupal::logger('UwFeatureRevert')
->notice('Current state already matches active config, aborting.');
}
else {
$config = $manager->getConfigCollection();
foreach ($components as $component) {
$dt_args['@component'] = $component;
if ($skip_confirmation) {
// If there is no config for this present, import it.
if (!isset($config[$component])) {
// Import missing component.
$item = $manager->getConfigType($component);
$type = ConfigurationItem::fromConfigStringToConfigType($item['type']);
$config_revert->import($type, $item['name_short']);
\Drupal::logger('d_application_api')
->notice('Import @module : @component.', $dt_args);
}
else {
// Revert existing component.
$item = $config[$component];
$type = ConfigurationItem::fromConfigStringToConfigType($item->getType());
$config_revert->revert($type, $item->getShortName());
\Drupal::logger('UwFeatureRevert')
->notice('Reverted @module : @component.', $dt_args);
}
}
else {
\Drupal::logger('UwFeatureRevert')
->notice('Skipping @module : @component.', $dt_args);
}
}
}
}
}
}
<?php
namespace Drupal\uw_cfg_common\Plugin\CKEditorPlugin;
use Drupal\ckeditor\CKEditorPluginBase;
use Drupal\Core\Asset\LibrariesDirectoryFileFinder;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\editor\Entity\Editor;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines the "link" plugin.
*
* @CKEditorPlugin(
* id = "link",
* label = @Translation("link")
* )
*/
class LinkPlugin extends CKEditorPluginBase implements ContainerFactoryPluginInterface {
/**
* Library file finder.
*
* @var \Drupal\Core\Asset\LibrariesDirectoryFileFinder
*/
protected $libFileFinder;
/**
* Constructs a BlockComponentRenderArray object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Asset\LibrariesDirectoryFileFinder $libFileFinder
* The library file finder.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, LibrariesDirectoryFileFinder $libFileFinder) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->libFileFinder = $libFileFinder;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('library.libraries_directory_file_finder'));
}
/**
* {@inheritdoc}
*/
public function getDependencies(Editor $editor) {
return [
'fakeobjects',
];
}
/**
* {@inheritdoc}
*/
public function getLibraries(Editor $editor) {
return [];
}
/**
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
return [];
}
/**
* {@inheritdoc}
*/
public function getButtons() {
$libraryUrl = $this->libFileFinder->find('ckeditor.link');
return [
'Link' => [
'label' => $this->t('Link'),
'image' => $libraryUrl . '/icons/link.png',
],
'Unlink' => [
'label' => $this->t('Unlink'),
'image' => $libraryUrl . '/icons/unlink.png',
],
'Anchor' => [
'label' => $this->t('Anchor'),
'image' => $libraryUrl . '/icons/anchor.png',
],
];
}
/**
* {@inheritdoc}
*/
public function getFile() {
return $this->libFileFinder->find('ckeditor.link') . '/plugin.js';
}
/**
* {@inheritdoc}
*/
public function isInternal() {
return FALSE;
}
}
<?php
namespace Drupal\uw_cfg_common\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Checks that the submitted value is a unique integer.
*
* @Constraint(
* id = "UwMedia",
* label = @Translation("Media constraint", context = "Validation"),
* type = "string"
* )
*/
class UwMedia extends Constraint {
/**
* Variable for missing media.
*
* @var string
*/
public $mediaMissing = '%value needs to have a media item.';
}
<?php
namespace Drupal\uw_cfg_common\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the Uw Media constraint.
*/
class UwMediaValidator extends ConstraintValidator {
/**
* {@inheritdoc}
*/
public function validate($items, Constraint $constraint) {
// If the node has a type of media field, then continue
// to check that it has some media.
if ($uw_type_of_media = $items->field_uw_type_of_media) {
// Switch on the type of media select list.
switch ($uw_type_of_media->value) {
// If its a hero image, ensure that an image is selected.
case 'image':
// If there is no hero image, add the violation.
if (!$items->field_uw_hero_image->getValue()) {
$this->context->addViolation($constraint->mediaMissing, ['%value' => 'Hero Image']);
}
break;
}
}
}
}
......@@ -220,11 +220,11 @@ class UWService implements UWServiceInterface {
];
break;
case 'featured_image':
case 'media':
$preprocess = [
'uw_ct_blog' => 'field_uw_hero_image',
'uw_ct_event' => 'field_uw_hero_image',
'uw_ct_news_item' => 'field_uw_hero_image',
'uw_ct_blog',
'uw_ct_event',
'uw_ct_news_item',
];
break;
}
......@@ -235,35 +235,34 @@ class UWService implements UWServiceInterface {
/**
* {@inheritDoc}
*/
public function uwCheckNodeForFeaturedImage(Node $node): string {
public function uwCheckNodeForMedia(Node $node): string {
// Set the node type.
$node_type = $node->getType();
// Get the list of content types that are allowed to have
// feature images from our service.
$featured_image = $this->uwGetNodePreprocessing('featured_image');
// hero from our service.
$media = $this->uwGetNodePreprocessing('media');
// If node is allowed to have a featured image, make sure that
// node actually has an image.
if (in_array($node_type, array_keys($featured_image))) {
// If node is allowed to have a media, make sure that
// node actually has a media.
if (in_array($node_type, $media)) {
// Get the field name.
$field_name = $featured_image[$node_type];
// Ensure that the node has the type of media field.
if ($node->hasField('field_uw_type_of_media')) {
// Get the image object values from the node.
$image = $node->$field_name->getValue();
// Get the type of media value from the node.
$value = $node->field_uw_type_of_media->value;
// If there is an image present, set the variable so that
// the page title will not be displayed.
if ($image) {
return 'yes';
}
else {
return 'no';
// If there is a media present, set the variable so that
// the page title will not be displayed.
if ($value) {
return 'yes';
}
}
}
// Return a no by default.
return 'no';
}
......
......@@ -68,7 +68,7 @@ interface UWServiceInterface {
* @return string
* Yes or no.
*/
public function uwCheckNodeForFeaturedImage(Node $node): string;
public function uwCheckNodeForMedia(Node $node): string;
/**
* A function to get or check the attached sidebar.
......
......@@ -124,7 +124,8 @@ class UwNodeContent {
$node_flags['get_image'] = FALSE;
$node_flags['get_content'] = FALSE;
$node_flags['get_title'] = FALSE;
$node_flags['get_hero'] = FALSE;
$node_flags['get_media'] = FALSE;
$node_flags['get_listing_image'] = FALSE;
$node_flags['get_tags'] = TRUE;
// Setup flags based on teaser content argument.
......@@ -135,7 +136,7 @@ class UwNodeContent {
if ($view_mode == 'full') {
$node_flags['get_title'] = TRUE;
$node_flags['get_hero'] = TRUE;
$node_flags['get_media'] = TRUE;
if ($node->getType() == 'uw_ct_contact') {
$node_flags['get_image'] = TRUE;
......@@ -157,7 +158,7 @@ class UwNodeContent {
$node_flags['get_header'] = TRUE;
$node_flags['get_title'] = TRUE;
$node_flags['get_hero'] = TRUE;
$node_flags['get_media'] = TRUE;
$node_flags['get_tags'] = FALSE;
}
......@@ -239,9 +240,9 @@ class UwNodeContent {
$content_data['header']['author'] = $this->addToContentData('author', 'field_author');
}
// Get the hero image.
if ($node_flags['get_hero']) {
$content_data['hero_image'] = $this->addToContentData('sources', 'field_uw_hero_image');
// Get the media.
if ($node_flags['get_media']) {
$content_data['media'] = $this->addToContentData('media', NULL);
}
// Get the listing image.
......@@ -291,9 +292,9 @@ class UwNodeContent {
$content_data['header']['date'] = $this->addToContentData('date', 'field_uw_event_date');
}
// Get hero image.
if ($node_flags['get_hero']) {
$content_data['hero_image'] = $this->addToContentData('sources', 'field_uw_hero_image');
// Get the media.
if ($node_flags['get_media']) {
$content_data['media'] = $this->addToContentData('media', NULL);
}
// Get listing image.
......@@ -361,9 +362,9 @@ class UwNodeContent {
$content_data['header']['date'] = $this->addToContentData('date', 'field_uw_news_date');
}
// Get hero image.
if ($node_flags['get_hero']) {
$content_data['hero_image'] = $this->addToContentData('sources', 'field_uw_hero_image');
// Get the media.
if ($node_flags['get_media']) {
$content_data['media'] = $this->addToContentData('media', NULL);
}
// Get listing image.
......@@ -413,6 +414,10 @@ class UwNodeContent {
$content_data['content'] = $this->addToContentData('content', 'layout_builder__layout');
}
if ($node_flags['get_media']) {
$content_data['media'] = $this->addToContentData('media', NULL);
}
return $content_data;
}
......
......@@ -115,6 +115,16 @@ class UwNodeFieldValue {
}
}
// The media for the top of the page.
if ($type == 'media') {
if ($node->hasField('field_uw_type_of_media')) {
return [
'type' => $node->field_uw_type_of_media->value,
'media' => $this->getMedia($node),
];
}
}
// Date field type (smart dates).
if ($type == 'date') {
return $this->getDates($node, $field_name, $view_mode);
......@@ -177,6 +187,160 @@ class UwNodeFieldValue {
}
}
/**
* Function to get the media for the top of the page.
*
* @param \Drupal\node\Entity\Node $node
* The node.
*
* @return array
* Render array for formatted text.
*/
public function getMedia(Node $node): array {
// Set to empty array in case we do not return anything.
$media = [];
// Get the specific type of media.
switch ($node->field_uw_type_of_media->value) {
// Get the banner.
case 'banner':
$media = $this->getBanner($node, 'field_uw_banner');
break;
// Get the image.
case 'image':
$media = $this->getSources($node, 'field_uw_hero_image');
break;
// Get the remote video media.
case 'remote_video':
$media = $this->getRemoteVideo($node, 'field_uw_remote_video');
break;
}
// Return the render things for the media.
return $media;
}
/**
* Function to get the banner.
*
* @param \Drupal\node\Entity\Node $node
* The node.
* @param string|null $field_name
* The name of the field to get.
*
* @return array
* Render array for formatted text.
*/
public function getBanner(Node $node, string $field_name = NULL): array {
// Set the banners as empty in case we do not have any.
$banners = [];
// Process banner images.
foreach ($node->$field_name as $banner_item) {
$banner_para = $banner_item->entity;
$type = $banner_para->getType();
$banner = [
'type' => $type,
'big_text' => $banner_para->field_uw_ban_big_text->value,
'small_text' => $banner_para->field_uw_ban_small_text->value,
];
// Link details needs to be created using for loop.
foreach ($banner_para->field_uw_ban_link as $link_item) {
$banner['link'] = $link_item->getUrl()->toString();
}
if ($type === 'uw_para_image_banner') {
$banner['image'] = $this->uwService->prepareResponsiveImage($banner_para->field_uw_ban_image->entity, 'uw_ris_media');
}
elseif ($type === 'uw_para_local_video_banner') {
$banner['image'] = $this->uwService->prepareResponsiveImage($banner_para->field_uw_ban_fallback_image->entity, 'uw_ris_media');
$banner['video'] = $banner_para->field_uw_ban_video->entity->field_media_file->entity->getFileUri();
}
elseif ($type === 'uw_para_vimeo_video_banner') {
$banner['image'] = $this->uwService->prepareResponsiveImage($banner_para->field_uw_ban_fallback_image->entity, 'uw_ris_media');
// Vimeo embed needs to be handled same way as links.
foreach ($banner_para->field_uw_ban_vimeo_video->entity->field_media_oembed_video as $embed_video) {
$banner['video'] = $embed_video->value;
}
}
// If we are using an image, set the sources and the
// img_element and remove the image array element.
// Also add on the alt for the image.
if (isset($banner['image']['sources'])) {
$banner['sources'] = $banner['image']['responsive_sources'];
$banner['img_element'] = $banner['image']['img_element']['#uri'];
$banner['alt'] = $banner['image']['alt'];
unset($banner['image']);
}
$images[] = $banner;
}
$banners = [
'images' => $images,
// 'autoplay' => $block_content->field_uw_autoplay->value,
// 'slide_speed' => $block_content->field_uw_slide_speed->value,
// 'style' => $block_content->field_uw_text_overlay_style->value,
// 'transition_speed' => $block_content->field_uw_transition_speed->value,
];
return $banners;
}
/**
* Function to get the remote video.
*
* @param \Drupal\node\Entity\Node $node
* The node.
* @param string|null $field_name
* The name of the field to get.
*
* @return array
* Render array for formatted text.
*/
public function getRemoteVideo(Node $node, string $field_name = NULL): array {
// Get the media object.
$media = $node->$field_name->entity;
// Set the remote video URL.
$remote_video['view']['url'] = $media->field_media_oembed_video->value;
// Check for YouTube.
if (preg_match('/^https?:\/\/(?:www\.youtube(?:-nocookie)?\.com\/(watch\?(?:\S+&)?v=|embed\/|.+#.+\/)|youtu\.be\/)([\w\-]{11})(?:[#&?]\S*)?$/', $remote_video['view']['url'])) {
// Set the type of video to YouTube.
$remote_video['view']['type'] = 'YouTube';
}
// Check for Vimeo.
elseif (strrpos($remote_video['view']['url'], 'vimeo')) {
// Set the type of video to Vimeo.
$remote_video['view']['type'] = 'Vimeo';
}
// Generic video.
else {
// Set the type of video to Generic.
$remote_video['view']['type'] = 'Generic';
}
// Set the video content to be the rendering of the media object.
$remote_video['video'] = $this->entityTypeManager->getViewBuilder('media')->view($media, 'default');
return $remote_video;
}
/**
* Function to get the formatted text.
*
......
......@@ -4,6 +4,7 @@ type: module
core_version_requirement: '^8.9 || ^9'
dependencies:
- 'composer_deploy:composer_deploy'
- 'drupal:anchor_link'
- 'drupal:better_exposed_filters'
- 'drupal:block_content'
- 'drupal:block_list_override'
......
......@@ -490,6 +490,49 @@ function uw_cfg_common_update_8104() {
return t('Set default access for @counter Webforms.', ['@counter' => $counter]);
}
/**
* Update the fields required for new media section.
*/
function uw_cfg_common_update_9101() {
// The content types to get updated.
$node_types = [
'uw_ct_blog',
'uw_ct_event',
'uw_ct_news_item',
];
// We need to a feature revert first, so tha the fields for
// type of media are created.
// Reverting uw_cfg_common first so that the fields get created.
\Drupal::service('uw_cfg_common.features')->import(['uw_cfg_common']);
// Revert the rest of the content types.
\Drupal::service('uw_cfg_common.features')->import($node_types);
// Step through each of the content types and update the field.
foreach ($node_types as $node_type) {
// Get all the nids of the content type.
$nids = \Drupal::service('entity_type.manager')->getStorage('node')->getQuery()->condition('type', $node_type)->execute();
// Step through each of the nids, get the node and check
// if we have to update the field.
foreach ($nids as $nid) {
// Load the node.
$node = \Drupal::service('entity_type.manager')->getStorage('node')->load($nid);
// If there is a hero image, update the type of media field,
// then save the node.
if ($node->field_uw_hero_image->entity) {
$node->set("field_uw_type_of_media", 'image');
$node->save();
}
}
}
}
/**
* Implements hook_update_dependencies().
*/
......
......@@ -139,6 +139,19 @@ function uw_cfg_common_entity_presave(EntityInterface $entity) {
}
}
}
// If there is a type of media, ensure that we do only have
// values in the fields that are selected.
if ($entity->hasField('field_uw_type_of_media')) {
// Get the type of media.
$type_of_media = $entity->field_uw_type_of_media->value;
// If it is null then set the hero image to null.
if ($type_of_media == NULL) {
$entity->set('field_uw_hero_image', NULL);
}
}
}
}
......@@ -290,7 +303,13 @@ function _uw_cfg_common_form_webform_settings_access_form_validate(array $form,
// Raise error for invalid groups.
foreach ($fields[$field] as $group) {
if (!preg_match('/^[A-Za-z0-9_& -]+$/', $group)) {
$form_state->setError($form['access']['create']['uw_ad_access'][$field], t('Invalid group: %group.', ['%group' => substr($group, 0, 100)]));
$form_state->setError(
$form['access']['create']['uw_ad_access'][$field],
t(
'Invalid group: %group.',
['%group' => substr($group, 0, 100)]
)
);
break;
}
}
......@@ -298,7 +317,10 @@ function _uw_cfg_common_form_webform_settings_access_form_validate(array $form,
// Raise error if no groups are entered.
if (!array_filter($fields)) {
$form_state->setError($form['access']['create']['uw_ad_access'], t('Provide at least one group to use for access control.'));
$form_state->setError(
$form['access']['create']['uw_ad_access'],
t('Provide at least one group to use for access control.')
);
}
// Fall-through.
case 'all':
......@@ -821,6 +843,21 @@ function uw_cfg_common_form_alter(array &$form, FormStateInterface $form_state,
}
}
// If there is a type of media field, it means that we are
// on a node add/edit page, so add the states for the
// actual media types in the hero section.
if (isset($form['field_uw_type_of_media'])) {
$form['field_uw_hero_image']['#states'] = [
'visible' => [
[
'select[name="field_uw_type_of_media"]' => [
['value' => 'image'],
],
],
],
];
}
// If we are on the media upload form, we want to restrict
// what crops are available.
if ($form_id == 'media_library_add_form_upload') {
......@@ -1032,3 +1069,12 @@ function uw_cfg_common_webform_build_access_denied_alter(array &$build, WebformI
];
}
}
/**
* Implements hook_entity_type_alter().
*/
function uw_cfg_common_entity_type_alter(array &$entity_types) {
// Add validation constraint to the node entity.
$entity_types['node']->addConstraint('UwMedia');
}
......@@ -29,3 +29,6 @@ services:
class: '\Drupal\uw_cfg_common\EventSubscriber\UwLayoutBuilderEventSubscriber'
tags:
- { name: 'event_subscriber' }
uw_cfg_common.features:
class: Drupal\uw_cfg_common\Helpers\UwFeatureRevert
arguments: ['@features.manager', '@config_update.config_update']