Skip to content

Feature/adaptive pixel ratio enhancements #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 28, 2018
90 changes: 90 additions & 0 deletions Block/System/Config/Form/Field/Checkbox.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace Fastly\Cdn\Block\System\Config\Form\Field;

use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Backend\Block\Template\Context;
use Fastly\Cdn\Model\Config;
use Fastly\Cdn\Model\Config\Backend\PixelRatios;

/**
* Class Checkbox
*
* @package Fastly\Cdn\Block\System\Config\Form\Field
*/
class Checkbox extends Field
{
public $values = null;
public $pixelRatios;
public $config;

public function __construct(
Context $context,
PixelRatios $pixelRatios,
Config $config
) {
$this->pixelRatios = $pixelRatios;
$this->config = $config;
parent::__construct($context);
}

public function _construct()
{
$this->_template = 'Fastly_Cdn::system/config/form/field/checkbox.phtml';

parent::_construct();
}

/**
* Retrieve element HTML markup.
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
*
* @return string
*/
public function _getElementHtml(AbstractElement $element)
{
$this->setNamePrefix($element->getName())
->setHtmlId($element->getHtmlId());

return $this->_toHtml();
}

/**
* @return array
*/
public function getValues()
{
$values = [];
$ratios = $this->pixelRatios->toOptionArray();
foreach ($ratios as $value) {
$values[$value['value']] = $value['label'];
}
return $values;
}
/**
*
* @param $name
* @return boolean
*/
public function getIsChecked($name)
{
return in_array($name, $this->getCheckedValues());
}

/**
* @return array|null
*/
public function getCheckedValues()
{
if ($this->values === null) {
$data = $this->config->getImageOptimizationRatios();
if (!isset($data)) {
$data = '';
}
$this->values = explode(',', $data);
}
return $this->values;
}
}
16 changes: 16 additions & 0 deletions Model/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ class Config extends \Magento\PageCache\Model\Config
const XML_FASTLY_IMAGE_OPTIMIZATIONS_PIXEL_RATIO
= 'system/full_page_cache/fastly/fastly_image_optimization_configuration/image_optimizations_pixel_ratio';

/**
* XML path to image optimizations pixel ratios
*/
const XML_FASTLY_IMAGE_OPTIMIZATIONS_RATIOS
= 'system/full_page_cache/fastly/fastly_image_optimization_configuration/image_optimizations_ratios';

/**
* XML path to Google analytics CID
*/
Expand Down Expand Up @@ -482,6 +488,16 @@ public function isImageOptimizationPixelRatioEnabled()
return $this->_scopeConfig->isSetFlag(self::XML_FASTLY_IMAGE_OPTIMIZATIONS_PIXEL_RATIO);
}

/**
* Return image optimization pixel ratios
*
* @return mixed
*/
public function getImageOptimizationRatios()
{
return $this->_scopeConfig->getvalue(self::XML_FASTLY_IMAGE_OPTIMIZATIONS_RATIOS);
}

/**
* Return blocked countries
*
Expand Down
47 changes: 47 additions & 0 deletions Model/Config/Backend/PixelRatios.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Fastly\Cdn\Model\Config\Backend;

use Magento\Framework\App\Config\Value;
use Magento\Framework\Exception\LocalizedException;

/**
* Class PixelRatios
*
* @package Fastly\Cdn\Model\Config\Backend
*/
class PixelRatios extends Value
{
/**
* Options getter
*
* @return array
*/
public function toOptionArray()
{
return [
['value' => '1.5', 'label'=>__('1.5x')],
['value' => '2', 'label'=>__('2x')],
['value' => '3', 'label'=>__('3x')],
['value' => '3.5', 'label'=>__('3.5x')],
['value' => '4', 'label'=>__('4x')]
];
}

/**
* @return $this|string
* @throws LocalizedException
*/
public function beforeSave()
{
$value = $this->getValue();

if ($value === null || empty($value)) {
throw new LocalizedException(
__('At least one device pixel ratio must be selected.', $this->getFieldConfig('label'))
);
}

return $value;
}
}
13 changes: 8 additions & 5 deletions Plugin/AdaptivePixelRationPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@ public function beforeToHtml(\Magento\Catalog\Block\Product\Image $subject)
return;
}

$srcSet = [];
$imageUrl = $subject->getData('image_url');
$pixelRatios = $this->config->getImageOptimizationRatios();
$pixelRatiosArray = explode(',', $pixelRatios);
$glue = (strpos($imageUrl, '?') !== false) ? '&' : '?';

# Pixel ratios defaults are based on the table from https://mydevice.io/devices/
# Bulk of devices are 2x however many new devices like Samsung S8, iPhone X etc are 3x and 4x
$srcSet = [
$imageUrl . $glue . 'dpr=2 2x',
$imageUrl . $glue . 'dpr=3 3x',
$imageUrl . $glue . 'dpr=4 4x'
];
foreach ($pixelRatiosArray as $pr) {
$ratio = 'dpr=' . $pr . ' ' . $pr . 'x';
$srcSet[] = $imageUrl . $glue . $ratio;
}

$subject->setData('custom_attributes', 'srcset="' . implode(',', $srcSet) . '"');
}
Expand Down
12 changes: 11 additions & 1 deletion etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,22 @@
</field>
<field id="image_optimizations_pixel_ratio" translate="label comment" type="select" sortOrder="95" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable adaptive device pixel ratios</label>
<comment><![CDATA[Magento will use <a href="https://docs.fastly.com/guides/imageopto-setup-use/serving-responsive-images#adaptive-device-pixel-ratios" target="_blank">Adaptive device pixel rations</a> through Fastly service.]]></comment>
<comment><![CDATA[Magento will use <a href="https://docs.fastly.com/guides/imageopto-setup-use/serving-responsive-images#adaptive-device-pixel-ratios" target="_blank">Adaptive device pixel ratios</a> through Fastly service.]]></comment>
<depends>
<field id="image_optimizations">1</field>
</depends>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="image_optimizations_ratios" translate="label" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Device Pixel Ratios</label>
<comment><![CDATA[Using a higher <a href="https://www.html5rocks.com/en/mobile/high-dpi/" target="_blank">Device Pixel Ratio</a> means serving larger images.]]></comment>
<depends>
<field id="image_optimizations">1</field>
<field id="image_optimizations_pixel_ratio">1</field>
</depends>
<frontend_model>Fastly\Cdn\Block\System\Config\Form\Field\Checkbox</frontend_model>
<backend_model>Fastly\Cdn\Model\Config\Backend\PixelRatios</backend_model>
</field>
</group>
<group id="fastly_blocking" sortOrder="245" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Blocking</label>
Expand Down
5 changes: 4 additions & 1 deletion etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@
<purge_catalog_product>1</purge_catalog_product>
<purge_cms_page>0</purge_cms_page>
<enable_geoip>0</enable_geoip>
<image_optimizations>0</image_optimizations>
</fastly_advanced_configuration>
<fastly_image_optimization_configuration>
<image_optimizations>0</image_optimizations>
<image_optimizations_ratios>2,3</image_optimizations_ratios>
</fastly_image_optimization_configuration>
<fastly_web_hooks>
<enable_webhooks>0</enable_webhooks>
<publish_key_url_purge_events>1</publish_key_url_purge_events>
Expand Down
15 changes: 15 additions & 0 deletions view/adminhtml/templates/system/config/form/field/checkbox.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<input type="hidden" name="<?php /* @noEscape */ echo $block->getNamePrefix() ?>" value="" />
<ul class="checkboxes">
<?php foreach ($block->getValues() as $name => $label) : ?>
<li>
<input type="checkbox" value="<?php /* @noEscape */ echo $name?>"
data-validate="{required:true}"
name="<?php /* @noEscape */ echo $block->getNamePrefix() ?>[]"
id="<?php /* @noEscape */ echo $block->getHtmlId() . '_' . $name ?>"
<?php /* @noEscape */ echo ($block->getIsChecked($name) ? ' checked="checked"' : '') ?>/>
<label for="<?php /* @noEscape */ echo $block->getHtmlId() . '_' . $name ?>">
<?php /* @noEscape */ echo $label ?>
</label>
</li>
<?php endforeach;?>
</ul>