Current File : /home/pacjaorg/www/kmm/components/com_sppagebuilder/parser/css-helper.php |
<?php
/**
* @package SP Page Builder
* @author JoomShaper http://www.joomshaper.com
* @copyright Copyright (c) 2010 - 2023 JoomShaper
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later
*/
use Joomla\CMS\Factory;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Uri\Uri;
/** No direct access. */
defined('_JEXEC') or die('Restricted access');
/**
* Migrate the CSS method used in the site.php file.
*
* @since 4.0.0
*/
class CSSHelper extends HelperBase
{
/**
* The default device
*
* @var string
* @since 4.0.0
*/
private static $device;
/**
* The font registry array. Registering all the fonts here.
*
* @var array
* @since 4.0.0
*/
private $fontRegistry = [];
/**
* The constructor function of the CSS Migrator.
*
* @param string $id The addon ID selector.
* @param bool $force Flag to set the ID as whatever it is provided, no sanitization is required.
*
* @since 4.0.0
*/
public function __construct(string $id, bool $force = false)
{
parent::__construct($id, $force);
self::$device = SpPgaeBuilderBase::$defaultDevice;
}
private function getFallbackValue($settings, $prop)
{
$keys = explode('.', $prop, 2);
if (empty($keys)) return null;
if (count($keys) > 1)
{
list($key1, $key2) = $keys;
$originalKey1 = $key1 . '_original';
$originalKey2 = $key2 . '_original';
if (isset($settings->$originalKey1))
{
$key1 = $originalKey1;
}
if (isset($settings->$originalKey2))
{
$key2 = $originalKey2;
}
return isset($settings->$key1->$key2) ? $settings->$key1->$key2 : null;
}
$key1 = $keys[0];
$originalKey = $key1 . '_original';
if (isset($settings->$originalKey))
{
$key1 = $originalKey;
}
return isset($settings->$key1) ? $settings->$key1 : null;
}
/**
* Register a font name to the font registry.
*
* @param string $fontName The font name which will be stored to the registry.
*
* @return void
* @since 4.0.0
*/
private function registerFont(string $fontName)
{
if (!\in_array($fontName, $this->fontRegistry))
{
$this->fontRegistry[] = $fontName;
}
}
/**
* Get the font registry array.
*
* @return array
* @since 4.0.0
*/
private function getFontRegistry(): array
{
return $this->fontRegistry;
}
/**
* Load the google font for the typography fields.
*
* @return void
* @since 4.0.0
*/
public function loadGoogleFont(string $fontName)
{
$systemFonts = array(
'Arial',
'Tahoma',
'Verdana',
'Helvetica',
'Times New Roman',
'Trebuchet MS',
'Georgia'
);
if (!empty($fontName))
{
if (!\in_array($fontName, $systemFonts))
{
$fontPath = '/media/com_sppagebuilder/assets/google-fonts/' . $fontName . '/stylesheet.css';
$params = ComponentHelper::getParams('com_sppagebuilder');
$disableGoogleFonts = (bool) $params->get('disable_google_fonts', 0);
if ($disableGoogleFonts)
{
return;
}
if (file_exists(JPATH_ROOT . $fontPath))
{
Factory::getDocument()->addStylesheet(Uri::root(true) . $fontPath);
}
else
{
$linkTagUrl = "https://fonts.googleapis.com/css?family=" . $fontName . ":100,100italic,200,200italic,300,300italic,400,400italic,500,500italic,600,600italic,700,700italic,800,800italic,900,900italic&display=swap";
Factory::getDocument()->addStylesheet($linkTagUrl);
}
}
}
}
public function loadLocalFont(string $fontName)
{
$fontPath = '/media/com_sppagebuilder/assets/custom-fonts/' . $fontName . '/stylesheet.css';
if (file_exists(JPATH_ROOT . $fontPath))
{
Factory::getDocument()->addStylesheet(Uri::root(true) . $fontPath);
}
}
private function purifyTypographyObject($obj)
{
$device = SpPgaeBuilderBase::$defaultDevice;
$obj = $obj ?? '';
if (!\is_object($obj))
{
if (preg_match("@[^-|\d+]@", $obj))
{
$obj = \preg_replace("@\D+$@", '', $obj);
}
$newObject = AddonHelper::initDeviceObject();
foreach ($newObject as $k => &$v)
{
// Todo: need to replace unit value "px" with dynamic $obj unit value.
$v = (object) ['value' => $k === $device ? $obj : '', 'unit' => 'px'];
}
unset($v);
return $newObject;
}
else
{
foreach ($obj as $k => &$v)
{
if (!\is_object($v))
{
$v = (object) ['value' => $v, 'unit' => 'px'];
}
}
unset($v);
}
return $obj;
}
/**
* Typography style generation by using the settings and fallback array.
*
* @param string $selector The CSS selector.
* @param object $settings The settings object.
* @param string $prop The settings prop or the typography field name.
* @param array $fallback The fallback array.
*
* @return string
* @since 4.0.0
*/
public function typography($selector, $settings, $prop, $fallback = [])
{
$hasFallback = !empty($fallback) && !isset($settings->$prop);
if ($hasFallback)
{
$font = array_key_exists('font', $fallback) ? $fallback['font'] : "";
$size = array_key_exists('size', $fallback) ? $fallback['size'] : "";
$lineHeight = array_key_exists('line_height', $fallback) ? $fallback['line_height'] : "";
$letterSpacing = array_key_exists('letter_spacing', $fallback) ? $fallback['letter_spacing'] : "";
$uppercase = array_key_exists('uppercase', $fallback) ? $fallback['uppercase'] : "";
$italic = array_key_exists('italic', $fallback) ? $fallback['italic'] : "";
$underline = array_key_exists('underline', $fallback) ? $fallback['underline'] : "";
$weight = array_key_exists('weight', $fallback) ? $fallback['weight'] : "";
$settings->$prop = new \stdClass;
$settings->$prop->font = $this->getFallbackValue($settings, $font);
$settings->$prop->weight = $this->getFallbackValue($settings, $weight);
$settings->$prop->uppercase = $this->getFallbackValue($settings, $uppercase);
$settings->$prop->italic = $this->getFallbackValue($settings, $italic);
$settings->$prop->underline = $this->getFallbackValue($settings, $underline);
$settings->$prop->size = $this->getFallbackValue($settings, $size);
$settings->$prop->line_height = $this->getFallbackValue($settings, $lineHeight);
$settings->$prop->letter_spacing = $this->getFallbackValue($settings, $letterSpacing);
}
if (!isset($settings->$prop)) return '';
$typography = $settings->$prop;
$objectKeys = ["letter_spacing", "line_height", "size"];
foreach ($objectKeys as $key)
{
if (isset($typography->$key))
{
$typography->$key = $this->purifyTypographyObject($typography->$key);
}
}
if (!empty($typography->weight) && \preg_match("@[^\d]+@", $typography->weight))
{
$typography->weight = (int) $typography->weight;
}
/** If font exists to the typography field then register the font and load it. */
if (!empty($typography->font))
{
$this->registerFont($typography->font);
if (isset($typography->type) && $typography->type === 'local')
{
$this->loadLocalFont($typography->font);
}
else
{
$this->loadGoogleFont($typography->font);
}
}
$props = [
'font' => isset($typography->font) && !empty($typography->font) ? 'font-family' : null,
'weight' => isset($typography->weight) && !empty($typography->weight) ? 'font-weight' : null,
'uppercase' => isset($typography->uppercase) && !empty($typography->uppercase) ? 'text-transform' : null,
'italic' => isset($typography->italic) && !empty($typography->italic) ? 'font-style' : null,
'underline' => isset($typography->underline) && !empty($typography->underline) ? 'text-decoration' : null,
'size' => isset($typography->size) && !empty($typography->size) ? 'font-size' : null,
'line_height' => isset($typography->line_height) && !empty($typography->line_height) ? 'line-height' : null,
'letter_spacing' => isset($typography->letter_spacing) && !empty($typography->letter_spacing) ? 'letter-spacing' : null
];
$units = ['font' => false, 'weight' => false, 'size' => false, 'uppercase' => false, 'italic' => false, 'underline' => false];
$modifiers = [];
$defaults = ['uppercase' => 'uppercase', 'italic' => 'italic', 'underline' => 'underline'];
$typographyStyle = $this->generateStyle($selector, $typography, $props, $units, $modifiers, $defaults);
return $typographyStyle;
}
/**
* Parse the color and generate a valid color property value.
*
* @param mixed $color Object or string value of the color.
*
* @return string Returns the color value string.
* @since 4.0.0
*/
public static function parseColor($settings, $prop): string
{
$originalProp = $prop . '_original';
if (isset($settings->$originalProp))
{
$prop = $originalProp;
}
$color = isset($settings->$prop) ? $settings->$prop : '';
if (\is_string($color))
{
return $color;
}
if (\is_object($color))
{
if (isset($color->type))
{
$color1 = "#398AF1";
$color2 = "#5EDCED";
if (!empty($color->color))
{
$color1 = !empty(preg_replace("@\s+@", "", $color->color)) ? $color->color : '#398AF1';
}
if (!empty($color->color2))
{
$color2 = !empty(preg_replace("@\s+@", "", $color->color2)) ? $color->color2 : '#5EDCED';
}
switch ($color->type)
{
case 'solid':
return preg_replace("@\s+@", "", $color->color);
case 'linear':
$start = $color->pos ?? 0;
$end = $color->pos2 ?? 100;
return 'linear-gradient(' . ($color->deg ?? 0) . 'deg, ' . $color1 . ' ' . $start . '%, ' . $color2 . ' ' . $end . '%)';
case 'radial':
$start = $color->pos ?? 0;
$end = $color->pos2 ?? 100;
$position = $color->radialPos ?? 'center center';
return 'radial-gradient(at ' . $position . ', ' . $color1 . ' ' . $start . '%, ' . $color2 . ' ' . $end . '%)';
default:
return $color->color ?? '';
}
}
}
return '';
}
/**
* Parse the alignment prop and generate the alignment value.
*
* @param object $settings The settings object.
* @param string $prop The alignment prop name.
* @param bool $flex If the alignment for the flex or not.
*
* @return string The alignment value.
* @since 4.0.0
*/
public static function parseAlignment($settings, $prop, $flex = false)
{
$primitiveProp = $prop;
$originalProp = $prop . '_original';
$prop = isset($settings->$originalProp) ? $originalProp : $prop;
if (!isset($settings->$prop))
{
return '';
}
$alignmentMap = [
'sppb-text-center' => 'center',
'sppb-text-left' => 'left',
'sppb-text-right' => 'right',
];
$flexMap = [
'center' => 'center',
'left' => 'flex-start',
'right' => 'flex-end'
];
$alignment = $settings->$prop;
if (self::hasMultiDeviceSettings($alignment))
{
if ($flex)
{
foreach ($alignment as &$value)
{
$value = isset($flexMap[$value]) ? $flexMap[$value] : $value;
}
unset($value);
}
else
{
foreach ($alignment as &$value)
{
$value = isset($alignmentMap[$value]) ? $alignmentMap[$value] : $value;
}
unset($value);
}
return $alignment;
}
$align = isset($alignmentMap[$alignment]) ? $alignmentMap[$alignment] : $alignment;
return $flex && isset($flexMap[$align]) ? $flexMap[$align] : $align;
}
private static function isEnabledBoxShadow($shadow)
{
if (empty($shadow))
{
return false;
}
if (\is_string($shadow))
{
$shadow = preg_replace("@\s+@", ' ', $shadow);
$shadow = explode(' ', $shadow);
$shadow = (object) $shadow;
}
$numberKeys = ['ho', 'vo', 'blur', 'spread'];
if (\is_object($shadow))
{
if (isset($shadow->enabled))
{
return $shadow->enabled;
}
foreach ($shadow as $key => &$value)
{
if (\in_array($key, $numberKeys))
{
$value = (float) $value;
if (!empty($value))
{
return true;
}
}
if ($key === 'color')
{
$value = strtolower($value);
return !($value === '#fff' || $value === '#ffffff');
}
}
unset($value);
}
return false;
}
/**
* Parse the box shadow values and generate the box-shadow CSS property.
*
* @param object $settings The addon settings.
* @param string $prop The box-shadow settings key inside the $settings object.
* @param boolean $isTextShadow Data comes from text-shadow or box shadow.
*
* @return string The generated box-shadow.
* @since 4.0.0
*/
public static function parseBoxShadow($settings, string $prop, $isTextShadow = false): string
{
if (!isset($settings->$prop))
{
return '';
}
$box = $settings->$prop;
if (\is_object($box))
{
$horizontalOffset = !empty($box->ho) ? $box->ho . 'px' : '0px';
$verticalOffset = !empty($box->vo) ? $box->vo . 'px' : '0px';
$blur = !empty($box->blur) ? $box->blur . 'px' : '0px';
$spread = (!$isTextShadow) ? (!empty($box->spread) ? $box->spread . 'px' : '0px') : ' ';
$color = !empty($box->color) ? $box->color : '';
return self::isEnabledBoxShadow($box) ? $horizontalOffset . " " . $verticalOffset . " " . $blur . " " . $spread . " " . $color : '';
}
if ($box === '0 0 0 0 #fff' || $box === '0 0 0 #ffffff' || $box === '0 0 0 transparent' || $box === '0 0 0 0 transparent')
{
return '';
}
return $box;
}
/**
* Check if the value has a multi-device settings.
*
* @param mixed $value The settings value.
*
* @return boolean
* @since 4.0.0
*/
private static function hasMultiDeviceSettings($value): bool
{
return isset($value->xl)
|| isset($value->lg)
|| isset($value->md)
|| isset($value->sm)
|| isset($value->xs);
}
/**
* Extract the value field, if the field has a unit property then add the unit with it.
*
* @param object $value The value object.
*
* @return string The extracted string value.
* @since 4.0.0
*/
private function extractValue($value): string
{
if (\is_object($value))
{
$_value = '';
if (isset($value->value))
{
$_value = is_object($value->value) ? $value->value->value : $value->value;
}
if (!empty($_value) && isset($value->unit))
{
$_value .= is_object($value->unit) ? $value->unit->unit : $value->unit;
}
return $_value;
}
if (\is_array($value) && empty($value))
{
return $value = '';
}
return (string) $value;
}
/**
* Generate style for a specific selector with help of settings object, prop map, units etc.
*
* @param string $selector The selector string where to apply the styles.
* @param \stdClass $settings The settings object.
* @param array $propMap The property map. The structure of the array is [prop => cssProp | [cssProps]]
* @param mixed $unit The unit array. The structure of the array is [prop => unitValue | false]
* @param array $modifier The modifier array. This array says if any modifier is needed to apply
* to this property. Currently we are covering the spacing property.
* if [prop => 'spacing'] is provided then handle the value as spacing value.
* @param mixed $default The default values. This would be useful if we don't want to
* use the $settings->$prop value as a result but want
* user specific value as a value.
* @param boolean $important The important specifier says if the property need
* to append !important; at the end or not.
* @param string $static Provided any static style value. If provided that would be contacted.
*
* @return string The CSS style with media query.
* @since 4.0.0
*/
public function generateStyle(string $selector, $settings, $propMap, $unit = 'px', $modifier = [], $default = null, $important = false, $static = ''): string
{
$device = self::$device;
$selector = $this->generateSelector($selector);
$css = [];
$media = [];
$_unit = 'px';
$css[] = $selector . "{";
if (!empty($static))
{
$css[] = $static;
}
foreach ($propMap as $prop => $cssProp)
{
if (\is_null($cssProp))
{
continue;
}
$primitiveProp = $prop;
$originalProp = $prop . '_original';
if (isset($settings->$originalProp))
{
$prop = $originalProp;
}
$_unit = \is_array($unit) ? ($unit[$primitiveProp] ?? 'px') : $unit;
$_important = \is_array($important) ? ($important[$primitiveProp] ?? false) : $important;
$_default = \is_array($default) ? ($default[$primitiveProp] ?? null) : $default;
if (!isset($settings->$prop) && \is_null($_default))
{
continue;
}
if (isset($settings->$prop) && \is_string($settings->$prop) && preg_replace("@\s+@", '', $settings->$prop) === '' && \is_null($_default))
{
continue;
}
if (\is_string($cssProp))
{
$cssProp = [$cssProp];
}
if (!\is_null($_default))
{
$str = '';
foreach ($cssProp as $attr)
{
$str .= $attr . ': ' . $_default . ';';
}
$css[] = $str;
continue;
}
if (self::hasMultiDeviceSettings($settings->$prop))
{
$multiDeviceData = null;
if (isset($modifier[$primitiveProp]) && $modifier[$primitiveProp] === 'spacing')
{
$multiDeviceData = AddonHelper::generateSpacingObject($settings, $prop, $cssProp, $device);
}
else
{
$multiDeviceData = AddonHelper::generateMultiDeviceObject($settings, $prop, $cssProp, $device, $_important, $_unit);
}
$media[] = $multiDeviceData;
$css[] = $multiDeviceData->$device;
unset($multiDeviceData);
}
else
{
if (isset($settings->$prop))
{
if (isset($modifier[$primitiveProp]) && $modifier[$primitiveProp] === 'spacing')
{
$_object = AddonHelper::generateSpacingObject($settings, $prop, $cssProp, $device);
$media[] = $_object;
}
$val = $this->extractValue($settings->$prop);
if (isset($val) && $val !== '')
{
foreach ($cssProp as $attr)
{
$str = "";
if (!empty($_object) && !empty($_object->$device))
{
$str .= $_object->$device;
unset($_object);
}
else
{
$str .= (strpos($attr, '%1$s') || strpos($attr, '%s')) !== false
? \sprintf($attr, $this->extractValue($settings->$prop) ?? '')
: $attr . ': ' . $this->extractValue($settings->$prop) ?? '';
}
if (!empty($_unit))
{
$str .= $_unit;
}
$str .= $_important ? ' !important' : '';
if (substr($str, -1) !== ';')
{
$str .= ';';
}
$css[] = $str;
}
}
}
}
}
$css[] = "}";
if (!empty($media))
{
$mediaStyle = array_map(function ($key) use ($selector, $media)
{
$str = AddonHelper::mediaQuery($key);
$str .= $selector . "{";
foreach ($media as $object)
{
$str .= $object->$key;
}
$str .= "}";
$str .= "}";
return $str;
}, $this->getDeviceListExcludeDefault());
$css[] = implode("\r\n", $mediaStyle);
}
$css = array_filter($css, function ($style)
{
return !empty($style);
});
return implode("\r\n", $css);
}
function getFormattedValue($transformFunctionCssValue, $value)
{
if (empty($value)) {
return '';
}
$axises = ['x', 'y', 'z', 'top', 'left'];
$values = [];
$valueOfAxis = null;
foreach($axises as $axis) {
if(empty($value->$axis)) {
continue;
}
if(is_object($value->$axis)) {
$valueOfAxis = isset($value->$axis->value) ? $value->$axis->value : null;
$unitOfAxis = isset($value->$axis->unit) ? $value->$axis->unit : null;
} else if (is_string($value->$axis)) {
$valueOfAxis = isset($value->$axis) ? $value->$axis : null;
$unitOfAxis = '';
}
if(empty($valueOfAxis) && $valueOfAxis !== 0 && $valueOfAxis !== '0') {
continue;
}
if($transformFunctionCssValue === 'transform_origin') {
$values[] = $valueOfAxis . $unitOfAxis;
} else {
$values[] = $transformFunctionCssValue . strtoupper($axis) . '(' . $valueOfAxis . $unitOfAxis . ')';
}
}
return implode(' ', $values);
}
/**
* Parse style for transform property
* @since 5.2.10
*
* @param string $selector The selector string where to apply the styles.
* @param \stdClass $settings The settings object
* @param string $prop The filter settings key inside the $settings object
*
* @return string
*/
public function generateTransformStyle(string $selector, $settings, $prop): string
{
$selector = $this->generateSelector($selector);
$transform = isset($settings->$prop) ? $settings->$prop : null;
if (!isset($transform)) {
return '';
}
// Define an array to store transform functions
$transformFunctions = [];
$transformFunctionMap = [
'move' => 'translate',
'rotate' => 'rotate',
'scale' => 'scale',
'skew' => 'skew',
];
foreach ($transformFunctionMap as $transformFunction => $transformFunctionCssValue) {
if (!empty($transform->$transformFunction)) {
$unitWithValue = $this->getFormattedValue($transformFunctionCssValue, $transform->$transformFunction);
if(!empty($unitWithValue)) {
$transformFunctions[] = $unitWithValue;
}
}
}
$transformOriginValue = '';
if(!empty($transform->transform_origin)) {
$value = $this->getFormattedValue('transform_origin', $transform->transform_origin);
if(!empty($value)) {
$transformOriginValue = 'transform-origin: ' . $value . ';';
}
}
$finalCssStyle = '';
if (!empty($transformFunctions) || !empty($transformOriginValue)) {
$finalCssStyle .= $selector . '{ ';
if(!empty($transformFunctions)) {
$finalCssStyle .= 'transform: ' . implode(' ', $transformFunctions) . '; ';
}
if(!empty($transformOriginValue)) {
$finalCssStyle .= $transformOriginValue;
}
$finalCssStyle .= ' }';
}
return $finalCssStyle;
}
/**
* Parse style for css filter property
* @since 5.2.8
*
* @param \stdClass $settings The settings object
* @param string $prop The filter settings key inside the $settings object
*
* @return string
*/
public static function parseCssEffects($settings, $prop): string {
$effects = $settings->$prop;
if (!isset($effects))
{
return '';
}
// Define an array to store filter functions
$filterFunctions = [];
// CSS unit definitions
$effectsKeyUnit = [
'opacity' => '%',
'blur' => 'px',
'brightness' => '%',
'contrast' => '%',
'saturate' => '%',
'grayscale' => '%',
'invert' => '%',
'sepia' => '%',
'hue_rotate' => 'deg',
];
foreach ($effectsKeyUnit as $filterFunction => $unit) {
// Ensure property is valid and exists in $effectsKeyUnit
if (!empty($effects->$filterFunction)) {
$updatedFunction = $filterFunction === 'hue_rotate' ? 'hue-rotate' : $filterFunction;
$filterFunctions[] = $updatedFunction . '(' . $effects->$filterFunction . $unit . ')';
}
}
$parsedFilterCssValue = '';
// If there are filter functions, construct the CSS rule
if (!empty($filterFunctions)) {
$parsedFilterCssValue = implode(' ', $filterFunctions);
}
return $parsedFilterCssValue;
}
/**
* Parse the backdrop filter values and generate the backdrop filter CSS property.
*
* @param object $settings The Add-On settings.
* @param string $property The backdrop-filter settings key inside the $settings object.
* @param string $propertyValue The backdrop settings value.
* @since 4.0.8
* @return string
*/
public static function parseBackDropFilter($settings, string $property, string $propertyValue)
{
if (!isset($settings->$property))
{
return '';
}
$unit = ($settings->$property == 'blur') ? 'px' : '%';
$parsedValue = $settings->$property . '(' . $settings->$propertyValue . $unit . ')';
return $parsedValue;
}
/**
* Generate missing break points of field width for old layouts.
*
* @param object $fieldWidth given breakpoints of field width
*
* @return object
*
* @since 4.0.9
*/
public static function generateMissingBreakPoints($fieldWidth)
{
$missing_breakpoints = ['xl', 'lg'];
foreach ($missing_breakpoints as $key)
{
if (!property_exists($fieldWidth, $key))
{
$fieldWidth->$key = isset($fieldWidth->md) && $fieldWidth->md ? $fieldWidth->md : "";
}
}
return $fieldWidth;
}
public static function generateBorderWidth(array $width, $style, $color)
{
$positions = ['top', 'right', 'bottom', 'left'];
$widthStyles = [];
$slicedWidth = array_slice($width, 0, 4);
foreach ($slicedWidth as $index => $value) {
if (trim($value) !== '') {
$widthStyles[] = 'border-' . $positions[$index] . ': ' . $value . ' ' . $style . ' ' . $color . ';';
}
}
return implode("\n\r", $widthStyles);
}
public function border($selector, $settings, $prop)
{
$value = $settings->{$prop . '_original'} ?? $settings->$prop ?? null;
$output = '';
if (is_null($value))
{
return '';
}
$deviceKeys = ['xl', 'lg', 'md', 'sm', 'xs'];
$isResponsive = false;
foreach ($value as $key => $_) {
if (array_key_exists($key, array_flip($deviceKeys))) {
$isResponsive = true;
break;
}
}
if ($isResponsive)
{
$defaultDevice = SpPgaeBuilderBase::$defaultDevice;
foreach ($deviceKeys as $key) {
if (isset($value->$key))
{
$option = $value->$key;
$width = isset($option->border_width) ? $option->border_width : '';
$style = isset($option->border_style) ? $option->border_style : '';
$color = isset($option->border_color) ? $option->border_color : '';
$widthParts = explode(' ', $width);
if (empty($widthParts))
{
continue;
}
$borderStyle = '';
if (count($widthParts) === 1)
{
$borderStyle = 'border: ' . $width . ' ' . $style . ' ' . $color . ';';
}
else
{
$borderStyle = static::generateBorderWidth($widthParts, $style, $color);
}
$generatedSelector = $this->generateSelector($selector);
$str = '';
if ($defaultDevice === $key)
{
$str .= $generatedSelector . '{';
$str .= $borderStyle;
$str .= '}';
}
else
{
$str .= AddonHelper::mediaQuery($key);
$str .= $generatedSelector . '{';
$str .= $borderStyle;
$str .= '}';
$str .= '}';
}
$output .= $str;
}
}
}
else
{
$width = isset($value->border_width) ? $value->border_width : '';
$style = isset($value->border_style) ? $value->border_style : '';
$color = isset($value->border_color) ? $value->border_color : '';
$widthParts = explode(' ', $width);
if (empty($widthParts))
{
return '';
}
$css = '';
if (count($widthParts) === 1)
{
$css = 'border: ' . $width . ' ' . $style . ' ' . $color . ';';
}
else
{
$css = static::generateBorderWidth($widthParts, $style, $color);
}
$generatedSelector = $this->generateSelector($selector);
$output = $generatedSelector . ' {';
$output .= $css;
$output .= '}';
}
return $output;
}
}