View source
<?php
namespace Drupal\blazy;
use Drupal\blazy\Utility\NestedArray;
class BlazyManager extends BlazyManagerBase {
public function config($key = '', $default = NULL, $id = 'blazy.settings', array $defaults = []) {
return parent::config($key, $default, $id, $id == 'blazy.settings' ? BlazyDefault::formSettings() : $defaults);
}
public function typecast(array &$config, $id = 'blazy.settings') {
if ($id == 'blazy.settings') {
$defaults = BlazyDefault::formSettings();
foreach ($defaults as $key => $value) {
if (isset($config[$key])) {
if ($key == 'blazy' || $key == 'io') {
foreach ($defaults[$key] as $k => $v) {
settype($config[$key][$k], gettype($v));
}
}
elseif ($key == 'filters') {
foreach ($defaults[$key] as $k => $v) {
foreach ($config[$key] as $sk => $format) {
foreach ($format as $ssk => $ignore) {
settype($config[$key][$sk][$ssk], gettype($v));
}
}
}
}
else {
settype($config[$key], gettype($value));
}
}
}
}
}
public function getBlazy(array $build = []) {
foreach (BlazyDefault::themeProperties() as $key) {
$build[$key] = isset($build[$key]) ? $build[$key] : [];
}
$settings =& $build['settings'];
$settings += BlazyDefault::itemSettings();
$item = $build['item'];
$settings['uri'] = $settings['uri'] ?: ($item && isset($item->uri) ? $item->uri : '');
$content = [
'#theme' => 'blazy',
'#image_style' => $settings['image_style'],
'#item' => $item,
'#build' => $build,
'#pre_render' => [
'blazy_pre_render',
],
];
drupal_alter('blazy', $content, $settings);
return empty($settings['uri']) ? [] : $content;
}
public function preRender(array $element) {
$build = $element['#build'];
unset($element['#build']);
$this
->prepareImage($element, $build);
$settings =& $element['#settings'];
if ($settings['use_media'] && empty($settings['_noiframe'])) {
BlazyMedia::build($element);
}
if ($settings['background']) {
$settings['use_image'] = FALSE;
}
if (!empty($settings['media_switch'])) {
if ($settings['media_switch'] == 'content' && !empty($settings['content_url'])) {
$element['#url'] = $settings['content_url'];
}
elseif (!empty($settings['lightbox'])) {
BlazyLightbox::build($element);
}
}
return $element;
}
protected function prepareImage(array &$element, array $build) {
$item = $build['item'];
$settings =& $build['settings'];
$settings['_api'] = TRUE;
$settings['ratio'] = $settings['ratio'] ? str_replace(':', '', $settings['ratio']) : FALSE;
$settings['ratio'] = $settings['background'] && empty($settings['ratio']) ? 'fluid' : $settings['ratio'];
$settings['use_media'] = $settings['embed_url'] && in_array($settings['type'], [
'audio',
'video',
]) && empty($settings['lightbox']);
foreach (BlazyDefault::themeAttributes() as $key) {
$key = $key . '_attributes';
$build[$key] = isset($build[$key]) ? $build[$key] : [];
}
$attributes =& $build['attributes'];
$this
->thumbnailAndPlaceholder($attributes, $settings);
Blazy::urlAndDimensions($settings, $item);
$this
->buildMedia($element, $build);
foreach ([
'caption',
'media',
'wrapper',
] as $key) {
$element["#{$key}" . '_attributes'] = empty($build[$key . '_attributes']) ? [] : Blazy::sanitize($build[$key . '_attributes']);
}
$captions = empty($build['captions']) ? [] : $this
->buildCaption($build['captions'], $settings);
$element['#caption_attributes']['class'][] = $settings['item_id'] . '__caption';
$element['#captions'] = $captions;
$element['#attributes'] = $attributes;
$element['#postscript'] = $build['postscript'];
$element['#url_attributes'] = $build['url_attributes'];
$element['#settings'] = $settings;
}
private function buildMedia(array &$element, array &$build) {
$item = $build['item'];
$settings =& $build['settings'];
$attributes =& $build['attributes'];
$item_attributes = empty($build['item_attributes']) ? [] : Blazy::sanitize($build['item_attributes']);
Blazy::imageAttributes($item_attributes, $settings, $item);
if (!empty($settings['resimage'])) {
$this
->buildResponsiveImage($attributes, $settings);
}
if (empty($settings['picture'])) {
$this
->buildImage($attributes, $item_attributes, $settings, $item);
}
$attributes['class'][] = 'media--' . $settings['type'];
if ($settings['media_switch']) {
$attributes['class'][] = 'media--switch media--switch--' . str_replace('_', '-', $settings['media_switch']);
}
$element['#item_attributes'] = $item_attributes;
}
private function buildResponsiveImage(array &$attributes, array &$settings) {
if ($mappings = picture_mapping_load($settings['responsive_image_style'])) {
$settings['picture'] = picture_get_mapping_breakpoints($mappings, $settings['image_style']);
$attributes['class'][] = 'media--picture';
}
}
private function buildImage(array &$attributes, array &$item_attributes, array &$settings, $item = NULL) {
$settings['ratio'] = empty($settings['width']) ? '' : $settings['ratio'];
if ($settings['ratio']) {
Blazy::aspectRatioAttributes($attributes, $settings);
}
$item_attributes['class'][] = 'media__element';
if (!empty($settings['blazy'])) {
$settings['lazy'] = 'blazy';
}
if ($settings['lazy']) {
$item_attributes['src'] = empty($settings['placeholder']) ? Blazy::PLACEHOLDER : $settings['placeholder'];
if ($settings['use_loading']) {
$attributes['class'][] = 'media--loading';
}
if ($settings['background']) {
Blazy::lazyAttributes($attributes, $settings);
Blazy::buildBreakpointAttributes($attributes, $settings, $item);
$attributes['class'][] = 'b-bg media--background';
if (!empty($settings['urls'])) {
$attributes['data-backgrounds'] = drupal_json_encode($settings['urls']);
}
}
else {
Blazy::lazyAttributes($item_attributes, $settings);
Blazy::buildBreakpointAttributes($item_attributes, $settings, $item);
}
if (!empty($settings['blazy_data']['dimensions'])) {
$attributes['data-dimensions'] = drupal_json_encode($settings['blazy_data']['dimensions']);
}
}
}
protected function thumbnailAndPlaceholder(array &$attributes, array &$settings) {
$path = $style = '';
if (!empty($settings['thumbnail_style'])) {
$path = image_style_path($settings['thumbnail_style'], $settings['uri']);
$style = image_style_load($settings['thumbnail_style']);
$attributes['data-thumb'] = image_style_url($settings['thumbnail_style'], $settings['uri']);
}
if (!empty($settings['thumbnail_uri'])) {
$path = $settings['thumbnail_uri'];
$attributes['data-thumb'] = file_create_url($path);
}
if (isset($style) && ($path && !is_file($path) && file_valid_uri($path))) {
image_style_create_derivative($style, $settings['uri'], $path);
}
if (!empty($settings['fx'])) {
$this
->createPlaceholder($settings, $style, $path);
$attributes['class'][] = 'media--fx--' . str_replace('_', '-', $settings['fx']);
}
}
protected function createPlaceholder(array &$settings, $style = NULL, $path = '') {
if (empty($path) && ($style = image_style_load('thumbnail')) && file_valid_uri($settings['uri'])) {
$path = image_style_path('thumbnail', $settings['uri']);
}
if ($path && file_valid_uri($path)) {
if (!is_file($path) && isset($style)) {
image_style_create_derivative($style, $settings['uri'], $path);
}
if (is_file($path)) {
$settings['placeholder'] = 'data:image/' . pathinfo($path, PATHINFO_EXTENSION) . ';base64,' . base64_encode(file_get_contents($path));
}
}
}
public function buildCaption(array $captions, array $settings) {
$content = [];
foreach ($captions as $key => $caption_content) {
if ($caption_content) {
$content[$key]['content'] = $caption_content;
$content[$key]['tag'] = strpos($key, 'title') !== FALSE ? 'h2' : 'div';
$class = $key == 'alt' ? 'description' : str_replace('field_', '', $key);
$content[$key]['attributes'] = [];
$content[$key]['attributes']['class'][] = $settings['item_id'] . '__caption--' . str_replace('_', '-', $class);
}
}
return $content ? [
'inline' => $content,
] : [];
}
public function build(array $build = []) {
$settings =& $build['settings'];
$settings['_grid'] = isset($settings['_grid']) ? $settings['_grid'] : !empty($settings['style']) && !empty($settings['grid']);
if (empty($settings['_grid'])) {
$settings = $this
->prepareBuild($build);
$build['#blazy'] = $settings;
$this
->setAttachments($build, $settings);
}
else {
$content = [
'#build' => $build,
'#pre_render' => [
'blazy_pre_render_build',
],
];
$build = empty($settings['use_field']) ? $content : [
$content,
];
}
drupal_alter('blazy_build', $build, $settings);
return $build;
}
public function preRenderBuild(array $element) {
$build = $element['#build'];
unset($element['#build']);
$commerce = isset($element['#ajax_replace_class']);
$attributes = isset($element['#attributes']) ? $element['#attributes'] : [];
$attributes = isset($element['#theme_wrappers'], $element['#theme_wrappers']['container']['#attributes']) ? $element['#theme_wrappers']['container']['#attributes'] : $attributes;
$settings = $this
->prepareBuild($build);
$element = BlazyGrid::build($build, $settings);
$this
->setAttachments($element, $settings);
if ($attributes) {
if ($commerce) {
$element['#container_attributes'] = $attributes;
}
else {
$element['#attributes'] = NestedArray::mergeDeep($element['#attributes'], $attributes);
}
}
return $element;
}
private function setAttachments(array &$element, array $settings) {
$attachments = $this
->attach($settings);
$element['#attached'] = empty($element['#attached']) ? $attachments : NestedArray::mergeDeep($element['#attached'], $attachments);
}
protected function prepareBuild(array &$build) {
$settings = isset($build['settings']) ? $build['settings'] : [];
$settings += $this
->getCommonSettings() + BlazyDefault::htmlSettings();
$build = isset($build['items']) ? $build['items'] : $build;
if (!empty($settings['first_image']) && !empty($settings['check_blazy'])) {
if (is_array($settings['first_image'])) {
$this
->isBlazy($settings, $settings['first_image']);
}
}
unset($build['items'], $build['settings']);
return $settings;
}
}