Skip to content
Snippets Groups Projects
Commit 44de0c82 authored by Martin Leblanc's avatar Martin Leblanc
Browse files

Merge branch 'feature/ISTWCMS-5204-ebremner-contacts' into '1.0.x'

ISTWCMS-5204: updating node theming to use a free flowing image

See merge request !180
parents aa8f93aa 0dffdfc6
No related branches found
No related tags found
1 merge request!180ISTWCMS-5204: updating node theming to use a free flowing image
......@@ -76,6 +76,36 @@ class UWService implements UWServiceInterface {
$this->requestStack = $requestStack;
}
/**
* {@inheritDoc}
*/
public function getCropImageStyles(string $type, bool $get_all = FALSE): array {
// Image styles for portrait.
$image_styles['portrait'] = [
'uw_is_portrait',
];
// Image styles for responsive.
$image_styles['responsive'] = [
'uw_is_media_x_large',
'uw_is_media_x_small',
'uw_is_media_medium',
'uw_is_media_large',
'uw_is_media_small',
];
// If the flag to get all the image styles is set,
// return all of them. If not return the
// specific image style.
if ($get_all) {
return $image_styles;
}
else {
return $image_styles[$type];
}
}
/**
* {@inheritDoc}
*/
......@@ -101,10 +131,22 @@ class UWService implements UWServiceInterface {
// Step through each of the sources and setup our own sources array.
foreach ($variables['sources'] as $source) {
$srcset = $source->storage()['srcset']->value();
$srcset_parts = explode('/', $srcset);
foreach ($srcset_parts as $srcset_part) {
if (strpos($srcset_part, 'uw_is') !== FALSE) {
$style = $srcset_part;
break;
}
}
$variables['responsive_sources'][] = [
'srcset' => $source->storage()['srcset']->value(),
'srcset' => $srcset,
'media' => $source->storage()['media']->value(),
'type' => $source->storage()['type']->value(),
'style' => $style,
];
}
......@@ -115,6 +157,20 @@ class UWService implements UWServiceInterface {
return [];
}
/**
* {@inheritDoc}
*/
public function uwGetResponsiveImageStyles(): array {
return [
'uw_is_media_x_large',
'uw_is_media_large',
'uw_is_media_medium',
'uw_is_media_small',
'uw_is_media_x_small',
'uw_is_portrait',
];
}
/**
* {@inheritDoc}
*/
......
......@@ -14,6 +14,19 @@ use Drupal\node\Entity\Node;
*/
interface UWServiceInterface {
/**
* Get the image styles used in UW crops.
*
* @param string $type
* The type of styles to get.
* @param bool $get_all
* Flag to get all the image styles.
*
* @return string[]
* Array of image styles that are used.
*/
public function getCropImageStyles(string $type, bool $get_all = FALSE): array;
/**
* Prepares responsive image.
*
......@@ -27,6 +40,14 @@ interface UWServiceInterface {
*/
public function prepareResponsiveImage(EntityInterface $entity, string $image_style): array;
/**
* Get the UW images styles used in UW responsive image.
*
* @return array
* Array of image styles.
*/
public function uwGetResponsiveImageStyles(): array;
/**
* Gets content types that have feature images.
*
......
......@@ -125,7 +125,6 @@ class UwNodeContent {
$node_flags['get_content'] = FALSE;
$node_flags['get_title'] = FALSE;
$node_flags['get_hero'] = FALSE;
$node_flags['get_listing_image'] = FALSE;
$node_flags['get_tags'] = TRUE;
// Setup flags based on teaser content argument.
......@@ -137,17 +136,25 @@ class UwNodeContent {
if ($view_mode == 'full') {
$node_flags['get_title'] = TRUE;
$node_flags['get_hero'] = TRUE;
if ($node->getType() == 'uw_ct_contact') {
$node_flags['get_image'] = TRUE;
}
}
elseif ($view_mode == 'teaser') {
if ($node->getType() !== 'uw_ct_contact') {
$node_flags['get_footer'] = FALSE;
}
$node_flags['get_listing_image'] = TRUE;
$node_flags['get_image'] = TRUE;
$node_flags['get_title'] = TRUE;
}
}
else {
if ($content == 'header') {
if ($node->getType() == 'uw_ct_contact') {
$node_flags['get_image'] = TRUE;
}
$node_flags['get_header'] = TRUE;
$node_flags['get_title'] = TRUE;
$node_flags['get_hero'] = TRUE;
......@@ -238,8 +245,12 @@ class UwNodeContent {
}
// Get the listing image.
if ($node_flags['get_listing_image']) {
$content_data['listing_image'] = $this->addToContentData('sources', 'field_uw_blog_listing_page_image');
if ($node_flags['get_image']) {
$content_data['image'] = $this->addToContentData('image', 'field_uw_blog_listing_page_image');
$content_data['image']['extra_options'] = [
'type' => 'listing_image',
'is_responsive' => TRUE,
];
}
// Setup the actual content.
......@@ -286,8 +297,12 @@ class UwNodeContent {
}
// Get listing image.
if ($node_flags['get_listing_image']) {
$content_data['listing_image'] = $this->addToContentData('sources', 'field_uw_event_listing_page_img');
if ($node_flags['get_image']) {
$content_data['image'] = $this->addToContentData('image', 'field_uw_event_listing_page_img');
$content_data['image']['extra_options'] = [
'type' => 'listing_image',
'is_responsive' => TRUE,
];
}
// Setup the actual content.
......@@ -352,8 +367,12 @@ class UwNodeContent {
}
// Get listing image.
if ($node_flags['get_listing_image']) {
$content_data['listing_image'] = $this->addToContentData('sources', 'field_uw_news_listing_page_image');
if ($node_flags['get_image']) {
$content_data['image'] = $this->addToContentData('image', 'field_uw_news_listing_page_image');
$content_data['image']['extra_options'] = [
'type' => 'listing_image',
'is_responsive' => TRUE,
];
}
// Setup the actual content.
......@@ -453,6 +472,15 @@ class UwNodeContent {
$content_data['header']['position'] = $this->addToContentData('plain_text', 'field_uw_ct_contact_title');
}
if ($node_flags['get_image']) {
$content_data['image'] = $this->addToContentData('image', 'field_uw_ct_contact_image');
$content_data['image']['extra_options'] = [
'type' => 'portrait',
'crop' => 'portrait',
'is_responsive' => TRUE,
];
}
// Setup the actual content.
if ($node_flags['get_content']) {
$content_data['content'] = $this->addToContentData('content', NULL);
......
......@@ -63,7 +63,8 @@ class UwNodeData {
$node,
$view_mode,
$data['type'],
$data['field'] ?? NULL
$data['field'] ?? NULL,
$data['extra_options'] ?? NULL
);
}
}
......@@ -73,12 +74,17 @@ class UwNodeData {
$node,
$view_mode,
$cdata['type'],
$cdata['field'] ?? NULL
$cdata['field'] ?? NULL,
$cdata['extra_options'] ?? NULL
);
}
}
}
// Send down the bundle to get used in modifier classes.
$bundle = str_replace('uw_ct_', '', $node->getType());
$node_data['bundle'] = str_replace('_', '-', $bundle);
return $this->cleanNodeData($node_data);
}
......@@ -108,7 +114,8 @@ class UwNodeData {
$node,
$view_mode,
$data['type'],
$data['field'] ?? NULL
$data['field'] ?? NULL,
$data['extra_options'] ?? NULL
);
}
}
......@@ -118,7 +125,8 @@ class UwNodeData {
$node,
$view_mode,
$cdata['type'],
$cdata['field'] ?? NULL
$cdata['field'] ?? NULL,
$data['extra_options'] ?? NULL
);
}
}
......
......@@ -73,13 +73,15 @@ class UwNodeFieldValue {
* The type of field.
* @param mixed $field_name
* The name of the field.
* @param array|null $extra_options
* Some extra options if requried.
*
* @return array|\Drupal\Core\GeneratedUrl|mixed|string|void|null
* Array of the value of the field.
*
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function getFieldValue(Node $node, string $view_mode, string $type, $field_name = NULL) {
public function getFieldValue(Node $node, string $view_mode, string $type, $field_name = NULL, array $extra_options = NULL) {
// Address field type.
if ($type == 'address') {
......@@ -130,7 +132,7 @@ class UwNodeFieldValue {
// Image field type.
if ($type == 'image') {
return $this->getImage($node, $field_name);
return $this->getImage($node, $field_name, $extra_options);
}
// Link field type.
......@@ -303,6 +305,8 @@ class UwNodeFieldValue {
* Node entity.
* @param string $field_name
* Field name.
* @param string|null $extra_options
* An array of extra options for the image.
*
* @return array
* Array of data such as url, alt.
......@@ -310,32 +314,52 @@ class UwNodeFieldValue {
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getImage(Node $node, string $field_name): array {
public function getImage(Node $node, string $field_name, array $extra_options = NULL): array {
// Empty image array, empty if no image.
$image = [];
// Get the media id.
$mid = $node->$field_name->getValue();
// If this is responsive, get the sources.
if (isset($extra_options['is_responsive'])) {
// If there is an image, process it.
if ($mid) {
// Get the sources for the image.
$image = $this->getSources($node, $field_name, $extra_options);
}
else {
// Get the media id.
$mid = $node->$field_name->getValue();
// Load in the media item.
/** @var \Drupal\media\Entity\Media $media */
$media = $this->entityTypeManager->getStorage('media')->load($mid[0]['target_id']);
// If there is an image, process it.
if ($mid) {
// Get the file id from the media object.
$fid = $media->getSource()->getSourceFieldValue($media);
// Load in the media item.
/** @var \Drupal\media\Entity\Media $media */
$media = $this->entityTypeManager->getStorage('media')->load($mid[0]['target_id']);
// If there is a file id, then get the uri,
// using the thumbnail image style.
if ($fid) {
$file = $this->entityTypeManager->getStorage('file')->load($fid);
$image['uri'] = $this->entityTypeManager->getStorage('image_style')->load('thumbnail')->buildUrl($file->getFileUri());
$image['alt'] = $media->field_media_image->alt;
// Get the file id from the media object.
$fid = $media->getSource()->getSourceFieldValue($media);
// If there is a file id, then get the uri,
// using the thumbnail image style.
if (isset($extra_options['image_style'])) {
$file = $this->entityTypeManager->getStorage('file')->load($fid);
$image['uri'] = $this->entityTypeManager->getStorage('image_style')->load($extra_options['image_style'])->buildUrl($file->getFileUri());
$image['alt'] = $media->field_media_image->alt;
}
else {
$file = $this->entityTypeManager->getStorage('file')->load($fid);
$image['uri'] = $this->entityTypeManager->getStorage('image_style')->load('thumbnail')->buildUrl($file->getFileUri());
$image['alt'] = $media->field_media_image->alt;
}
}
}
// If there is a type for the image, add it to the array.
if (!empty($image) && isset($extra_options['type'])) {
$image['type'] = $extra_options['type'];
}
return $image;
}
......@@ -605,15 +629,18 @@ class UwNodeFieldValue {
* Node entity.
* @param string $field_name
* The field name that has the date(s).
* @param string|null $extra_options
* An array of extra options.
*
* @return array
* Either array with responsive image.
*/
public function getSources(Node $node, string $field_name): array {
public function getSources(Node $node, string $field_name, array $extra_options = NULL): array {
$return_sources = [];
if ($node->$field_name) {
// Get the image entity.
$image = $node->$field_name->entity;
......@@ -622,14 +649,31 @@ class UwNodeFieldValue {
$sources = $this->uwService->prepareResponsiveImage($image, 'uw_ris_media');
}
else {
$sources = NULL;
return [];
}
if (isset($sources['responsive_sources'])) {
$return_sources['sources'] = $sources['sources'];
$return_sources['sources'] = $sources['responsive_sources'];
$return_sources['img_element'] = $sources['img_element']['#uri'];
$return_sources['alt'] = $sources['alt'];
}
// If there is a crop on image, pull out only those sources.
// If no crop is specified use the default which is responsive.
if (isset($extra_options['crop'])) {
$image_styles = $this->uwService->getCropImageStyles($extra_options['crop']);
}
else {
$image_styles = $this->uwService->getCropImageStyles('responsive');
}
// Step through and remove any sources that are
// not going to be in the image.
foreach ($return_sources['sources'] as $index => $source) {
if (!in_array($source['style'], $image_styles)) {
unset($return_sources['sources'][$index]);
}
}
}
return $return_sources;
......
......@@ -99,6 +99,48 @@ function uw_cfg_common_entity_presave(EntityInterface $entity) {
\Drupal::service('plugin.manager.menu.link')->rebuild();
}
}
// On a node entity save, check if the responsive
// image has created the derivatives so that things
// like hero images will load when no image has yet
// been rendered. If we do not do this, most hero
// images will not work.
if ($entity->getEntityTypeId() == 'node') {
// If there is a hero image, continue to process.
if ($image = $entity->field_uw_hero_image) {
// Get the value of the image field.
$image = $entity->field_uw_hero_image->getValue();
// Load the file from the hero image.
$file = \Drupal::entityTypeManager()
->getStorage('file')
->load($image[0]['target_id']);
// Load the image styles that are needed for the hero.
$uw_styles = \Drupal::service('uw_cfg_common.uw_service')->uwGetResponsiveImageStyles();
// Step through each of the image styles and ensure that
// the derivative is created.
foreach ($uw_styles as $uw_style) {
// Load the image style.
$style = \Drupal::entityTypeManager()
->getStorage('image_style')
->load($uw_style);
// Get the styled image derivative.
$destination = $style->buildUri($file->getFileUri());
// If the derivative doesn't exist yet (as the image style may have been
// added post launch), create it.
if (!file_exists($destination)) {
$style->createDerivative($file->getFileUri(), $destination);
}
}
}
}
}
/**
......@@ -680,6 +722,68 @@ function uw_cfg_common_form_menu_link_content_menu_link_content_form_alter(array
unset($form['menu_parent']['#options']['main:uw_base_profile.front_page']);
}
/**
* Implements template_preprocess_responsive_images().
*/
function uw_cfg_common_preprocess_responsive_image(&$variables) {
// Get the current path.
$current_path = \Drupal::service('path.current')->getPath();
// Explode the current path so we can check where we are.
$current_path_parts = explode('/', $current_path);
// If the current path has a node, we need to alter
// the image styles.
if ($current_path_parts[1] == 'node') {
// Get the media library parameters, we will use this
// if we are on a media library page/modal.
$media_lib_parameters = \Drupal::request()->query->get('media_library_opener_parameters');
// If we are on a contact image, remove all styles
// but those for portraits.
if (
$media_lib_parameters['bundle'] == 'uw_ct_contact' ||
end($current_path_parts) == 'uw_ct_contact'
) {
// Get the styles used for portraits.
$uw_styles = \Drupal::service('uw_cfg_common.uw_service')->getCropImageStyles('portrait');
}
else {
// Get the styles used for responsive.
$uw_styles = \Drupal::service('uw_cfg_common.uw_service')->getCropImageStyles('portrait');
}
// Step through each of the sources and see if we are.
// to use it.
foreach ($variables['sources'] as $index => $source) {
// Get the srcset.
$srcset = $source->storage()['srcset']->render();
// Break into parts so that we can check for image styles.
$srcset_parts = explode('/', $srcset);
// Step through each of the srcset parts.
foreach ($srcset_parts as $sp) {
// Ensure that we are on an image style.
if (strpos($sp, 'uw_is') !== FALSE) {
// If not in the list of image styles, remove
// it from the sources.
if (!in_array($sp, $uw_styles)) {
unset($variables['sources'][$index]);
}
}
}
}
}
}
/**
* Implements hook_form_alter().
*
......@@ -714,6 +818,49 @@ function uw_cfg_common_form_alter(array &$form, FormStateInterface $form_state,
$form['field_uw_meta_tags']['widget'][0]['twitter_cards']['twitter_cards_page_url']['#access'] = FALSE;
}
}
// If we are on the media upload form, we want to restrict
// what crops are available.
if ($form_id == 'media_library_add_form_upload') {
// If the crop widget is on the form, unset certain crops.
if (isset($form['media'][0]['fields']['field_media_image']['widget'][0]['#crop_list'])) {
// Get the parameters from the request, this was the only
// way to get out what the bundle was. Since this is a new
// form call from media_library, we could not use get current
// path or uri, since it would only return /media_library.
// The media library parameters has everything listed for the
// node and the node types.
$media_lib_parameters = \Drupal::request()->query->get('media_library_opener_parameters');
// If there are media lib parameters, process them.
if ($media_lib_parameters) {
// If there is a bundle on the parameters, continue
// to process.
if (isset($media_lib_parameters['bundle'])) {
// If this is a contact, remove all the responsive crops.
// If anything else, remove the portrait crop.
if ($media_lib_parameters['bundle'] == 'uw_ct_contact') {
foreach ($form['media'][0]['fields']['field_media_image']['widget'][0]['#crop_list'] as $index => $crop) {
if ($crop !== 'uw_crop_portrait') {
unset($form['media'][0]['fields']['field_media_image']['widget'][0]['#crop_list'][$index]);
}
}
}
else {
foreach ($form['media'][0]['fields']['field_media_image']['widget'][0]['#crop_list'] as $index => $crop) {
if ($crop == 'uw_crop_portrait') {
unset($form['media'][0]['fields']['field_media_image']['widget'][0]['#crop_list'][$index]);
}
}
}
}
}
}
}
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment