/
home
/
assocoweys
/
leucate
/
components
/
com_sppagebuilder
/
addons
/
dynamic_content_text
/
Upload File
HOME
<?php /** * @package SP Page Builder * @author JoomShaper http://www.joomshaper.com * @copyright Copyright (c) 2010 - 2025 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later */ //no direct access defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; use JoomShaper\SPPageBuilder\DynamicContent\Constants\FieldTypes; use JoomShaper\SPPageBuilder\DynamicContent\Site\CollectionHelper; use JoomShaper\SPPageBuilder\DynamicContent\Constants\CollectionIds; class SppagebuilderAddonDynamic_content_text extends SppagebuilderAddons { function autocorrect_html(string $html): string { if (empty($html)) { return ''; } libxml_use_internal_errors(true); $dom = new DOMDocument(); $dom->loadHTML('<?xml encoding="UTF-8">' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); libxml_clear_errors(); return $dom->saveHTML(); } function renderRatingStars($rating, $attribute, $settings) { if (empty($rating) || !is_numeric($rating)) { return ''; } $rating = floatval($rating); $maxRating = !empty($settings->rating_max_length) ? intval($settings->rating_max_length) : null; $maxRating = $maxRating ?? ceil($rating); $isInteger = isset($attribute->number_format) && $attribute->number_format === 'integer'; // Check if custom icon is selected $customIcon = isset($settings->rating_icon) && !empty($settings->rating_icon) ? $settings->rating_icon : null; $output = '<div class="sppb-rating-stars">'; for ($i = 1; $i <= $maxRating; $i++) { $isFilled = $rating >= $i; $isHalfFilled = !$isInteger && $rating >= ($i - 0.5) && $rating < $i; $starClass = 'sppb-rating-star'; if ($isFilled) { $starClass .= ' sppb-rating-star-filled'; } elseif ($isHalfFilled) { $starClass .= ' sppb-rating-star-half'; } if ($customIcon) { if ($isHalfFilled) { $starClass = 'sppb-rating-star sppb-rating-custom-half'; $output .= '<span class="' . $starClass . '"><i class="' . $customIcon . '"></i><i class="' . $customIcon . ' half-overlay"></i></span>'; } else { $output .= '<span class="' . $starClass . '"><i class="' . $customIcon . '"></i></span>'; } } else { $output .= '<span class="' . $starClass . '">★</span>'; } } $output .= '</div>'; return $output; } public function render() { $settings = $this->addon->settings; $selector = isset($settings->selector) ? $settings->selector : 'p'; $isDownloadable = isset($settings->is_downloadable) ? $settings->is_downloadable : 0; $fileValueOverride = !empty($settings->file_value_override) ? $settings->file_value_override : null; $defaultContent = $settings->default_text ?? ''; $class = $settings->class ?? ''; $collectionId = isset($settings->dynamic_item['collection_id']) ? $settings->dynamic_item['collection_id'] : null; $input = Factory::getApplication()->input; $collectionType = $input->get('collection_type') ?? 'normal-source'; // If the dynamic content value is not come from the parent collection addon, // that means this addon placed into a detail page, so we need to get the data from the detail page. if (empty($settings->dynamic_item) && $collectionType === 'articles') { $settings->dynamic_item = CollectionHelper::getDetailPageDataFromArticles(); } else if (empty($settings->dynamic_item) && $collectionType === 'tags') { $settings->dynamic_item = CollectionHelper::getDetailPageDataFromTags(); } else if (empty($settings->dynamic_item)) { $settings->dynamic_item = CollectionHelper::getDetailPageData(); } if (is_object($settings->dynamic_item)) { $settings->dynamic_item = json_decode(json_encode($settings->dynamic_item), true); } if (empty($settings->dynamic_item) || empty($settings->attribute)) { $content = $defaultContent ? $defaultContent : Text::_('COM_SPPAGEBUILDER_DYNAMIC_CONTENT_TEXT_NO_DATA'); return '<' . $selector . ' class="sppb-dynamic-content-text"' . '>' . $content . '</' . $selector . '>'; } $linkAttributes = [ 'href' => '', 'target' => '', 'rel' => '', 'has_link' => false, ]; $link = $settings->link ?? null; $hasLink = false; if (!empty($link)) { $linkOptions = [ 'url' => CollectionHelper::createDynamicContentLink( $link, CollectionHelper::prepareItemForLink($settings->dynamic_item, $settings->attribute) ), 'target' => $link->new_tab ? '_blank' : null, 'nofollow' => $link->nofollow ?? null, 'noreferrer' => $link->noreferrer ?? null, 'noopener' => $link->noopener ?? null, ]; $linkAttributes = CollectionHelper::generateLinkAttributes($linkOptions); } $content = CollectionHelper::getDynamicContentData($settings->attribute, $settings->dynamic_item) ?? ''; if (isset($settings->dynamic_item['collection_id']) && ($settings->dynamic_item['collection_id'] === CollectionIds::ARTICLES_COLLECTION_ID || $settings->dynamic_item['collection_id'] === CollectionIds::TAGS_COLLECTION_ID)) { $content = $settings->dynamic_item[$settings->attribute->path]; } $attributeType = $settings->attribute->type ?? 'text'; if ($attributeType === FieldTypes::DATETIME) { $content = CollectionHelper::formatDate($content, $settings->attribute); } elseif ($attributeType === FieldTypes::RATING) { $content = $this->renderRatingStars($content, $settings->attribute, $settings); } elseif ($attributeType === FieldTypes::LINK) { $linkOptions = [ 'url' => $content ?? null, 'target' => isset($settings->attribute->link) ? ($settings->attribute->link->target ?? null) : null, 'nofollow' => isset($settings->attribute->link) ? ($settings->attribute->link->nofollow ?? null) : null, 'noreferrer' => isset($settings->attribute->link) ? ($settings->attribute->link->noreferrer ?? null) : null, 'noopener' => isset($settings->attribute->link) ? ($settings->attribute->link->noopener ?? null) : null, ]; $linkAttributes = CollectionHelper::generateLinkAttributes($linkOptions); $content = (isset($settings->attribute->link) && $settings->attribute->link->text) ? $settings->attribute->link->text : $linkAttributes['href']; } if (empty(strip_tags($content)) && $attributeType !== FieldTypes::RATING) { return ''; } $output = ''; $hasLink = $linkAttributes['has_link'] ?? false; $downloadAction = $isDownloadable ? ' download="' . $content . '"' : ''; if ($hasLink) { $linkUrl = $linkAttributes['href'] ?? '/'; $attributes = $linkAttributes['target'] ? ' target="' . $linkAttributes['target'] . '"' : ''; $attributes .= $linkAttributes['rel'] ? ' rel="' . $linkAttributes['rel'] . '"' : ''; $app = Factory::getApplication(); $option = $app->input->get('option', '', 'string'); $view = $app->input->get('view', '', 'string'); if ($option === 'com_content' && ($view === 'category' || $view === 'archive' || $view === 'featured' || $view === 'article') && !empty($settings->dynamic_item['link'])) { $linkUrl = $settings->dynamic_item['link']; } $output .= '<a href="' . $linkUrl . '" class="sppb-dynamic-content-text__link" data-preload-collection ' . $attributes . ' >'; } if ($isDownloadable && $attributeType === FieldTypes::FILE) { $linkUrl = '/' . $content; $attributes = ''; $attributes .= $linkAttributes['rel'] ? ' rel="' . $linkAttributes['rel'] . '"' : ''; $output .= '<a href="' . $linkUrl . '" class="sppb-dynamic-content-file__link" data-preload-collection ' . $attributes . $downloadAction . '" >'; } $icon = $settings->icon ?? null; if (!empty($fileValueOverride) && $attributeType === FieldTypes::FILE) { $content = $fileValueOverride; } $classNames = 'sppb-dynamic-content-text'; if ($attributeType === FieldTypes::RICH_TEXT) { $selector = 'div'; $content = '<div class="sppb-dynamic-content__is-rich-text">' . $this->autocorrect_html($content) . '</div>'; } if ($attributeType === FieldTypes::RATING) { $selector = 'div'; } if (!empty($icon) && !empty(strip_tags($content))) { $iconPosition = $settings->icon_position ?? 'left'; $iconContent = '<i class="sppb-dynamic-content-text__icon ' . $icon . '"></i>'; if ($iconPosition === 'left') { $content = $iconContent . $content; } else { $content = $content . $iconContent; } } if (!empty($class)) { $classNames .= ' ' . $class; } $output .= '<' . $selector . ' class="' . $classNames . '"' . '>' . $content . '</' . $selector . '>'; if ($isDownloadable && $attributeType === FieldTypes::FILE) { $output .= '</a>'; } if ($hasLink) { $output .= '</a>'; } return $output; } public function css() { $css = ''; $addon_id = '#sppb-addon-' . $this->addon->id; $settings = $this->addon->settings; $cssHelper = new CSSHelper($addon_id); $settings->title_text_shadow = CSSHelper::parseBoxShadow($settings, 'title_text_shadow', true); $css .= $cssHelper->generateStyle('.sppb-dynamic-content-text, .sppb-dynamic-content-text a', $settings, [ 'color' => 'color', 'alignment' => 'justify-content', 'title_margin' => 'margin', 'title_padding' => 'padding', 'title_text_shadow' => 'text-shadow', ], false); $iconWrapperStyle = $cssHelper->generateStyle('.sppb-dynamic-content-text', $settings, ['icon_gap' => 'gap'], false); $iconStyle = $cssHelper->generateStyle('.sppb-dynamic-content-text__icon', $settings, ['icon_color' => 'color', 'icon_size' => 'font-size'], false); $css .= $cssHelper->typography('.sppb-dynamic-content-text', $settings, 'typography'); $css .= $iconWrapperStyle . $iconStyle; if ($settings->attribute->type === FieldTypes::RATING) { $css .= ' .sppb-rating-stars { display: inline-flex; gap: ' . (!empty($settings->rating_gap) ? $settings->rating_gap : '2px') . '; align-items: center; } .sppb-rating-star { color: ' . (!empty($settings->rating_empty_color) ? $settings->rating_empty_color : '#d1d5db') . '; font-size: ' . (!empty($settings->rating_size) ? $settings->rating_size : '1.2em') . '; line-height: 1; transition: color 0.2s ease; } .sppb-rating-star-filled { color: ' . (!empty($settings->rating_color) ? $settings->rating_color : '#fbbf24') . '; } .sppb-rating-star-half { color: ' . (!empty($settings->rating_empty_color) ? $settings->rating_empty_color : '#d1d5db') . '; position: relative; } .sppb-rating-star-half::after { content: "★"; position: absolute; top: 0; left: 0; width: 50%; height: 100%; color: ' . (!empty($settings->rating_color) ? $settings->rating_color : '#fbbf24') . '; overflow: hidden; } /* Custom icon styles */ .sppb-rating-star i { font-size: inherit; color: inherit; } .sppb-rating-custom-half { position: relative; } .sppb-rating-custom-half i:first-child { color: ' . (!empty($settings->rating_empty_color) ? $settings->rating_empty_color : '#d1d5db') . '; position: relative; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; } .sppb-rating-custom-half i.half-overlay { color: ' . (!empty($settings->rating_color) ? $settings->rating_color : '#fbbf24') . '; position: absolute; top: 0; left: 0; width: ' . (!empty($settings->rating_size) ? ('calc(' . $settings->rating_size . ' / 2)') : '0.6em') . '; height: 100%; z-index: 1; overflow: hidden; } '; } return $css; } public static function getTemplate() { $lodash = new Lodash('#sppb-addon-{{ data.id }}'); $output = '<style type="text/css">'; $output .= $lodash->generateTransformCss('', 'data.transform'); $output .= $lodash->typography('.sppb-dynamic-content-text', 'data.typography'); $output .= '</style>'; return $output; } }