* @link https://www.tassos.gr * @copyright Copyright © 2024 Tassos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; // No direct access defined('_JEXEC') or die; use NRFramework\Cache; use NRFramework\Functions; use NRFramework\Extension; use Joomla\CMS\Language\Text; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Factory; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Uri\Uri; use Joomla\CMS\Session\Session; class HTML { /** * Display field help text as tooltip in Joomla 4 * * @return void */ public static function fixFieldTooltips() { // Run once static $run; if ($run) { return; } $run = true; HTMLHelper::_('bootstrap.popover'); HTMLHelper::_('jquery.framework'); $doc = Factory::getDocument(); $doc->addStyleDeclaration(' .form-text, .form-control-feedback { display:none; } .tooltip .arrow:before { border-top-color:#444; border-bottom-color:#444; } .tooltip-inner { text-align: left; background-color: #444; padding: 7px 9px; max-width:300px; } '); $doc->addScriptDeclaration(' document.addEventListener("DOMContentLoaded", function() { initPopover(); document.addEventListener("joomla:updated", initPopover); function initPopover(event) { var target = event && event.target ? event.target : document; var fields = target.querySelectorAll(".control-group"); fields.forEach(function(field) { var desc = field.querySelector(".form-text"); if (desc) { var label = field.querySelector("label"); if (label) { label.classList.add("tTooltip"); label.setAttribute("title", desc.innerHTML); } } }); jQuery(target).find(".tTooltip").tooltip({ placement: "top", html: true, delay: { show: 200 } }); } }); '); } /** * Renders the HTML layout * * @param string $layout The HTML class of the layout. * @param array $options A list of attributes passed to the layout * * @return string */ public static function render($layout, $options = []) { if (!$layout) { return; } $class = '\NRFramework\HTML\\' . $layout; // ensure class exists if (!class_exists($class)) { return; } return (new $class($options))->render(); } /** * Renders Pro Button * * @param string $feature_label The text that will be used as the modal popup feature * @param string $buttonClass The class of the button * * @return void */ public static function renderProButton($feature_label = null, $buttonClass = 'btn-sm') { include_once JPATH_PLUGINS . '/system/nrframework/fields/pro.php'; $field = new \JFormFieldNR_PRO; $element = new \SimpleXMLElement(' '); $field->setup($element, null); echo $field->__get('input'); } /** * Renders a modal that will be shown on Pro only features * * @param string $extension_name * * @return void */ public static function renderProOnlyModal($extension = null) { $hash = 'proOnlyModal'; // Render modal once if (Cache::get($hash)) { return; } $options = [ 'extension_name' => is_null($extension) ? Extension::getExtensionNameByRequest(true) : Extension::getExtensionName($extension), 'upgrade_url' => Extension::getTassosExtensionUpgradeURL($extension) ]; $html = LayoutHelper::render('proonlymodal', $options, dirname(__DIR__) . '/layouts'); echo HTMLHelper::_('bootstrap.renderModal', 'proOnlyModal', ['backdrop' => 'static'], $html); Cache::set($hash, true); } public static function smartTagsBox($options = array()) { HTMLHelper::_('jquery.framework'); include_once JPATH_PLUGINS . '/system/nrframework/fields/smarttagsbox.php'; $field = new \JFormFieldSmartTagsBox; $element = new \SimpleXMLElement(''); $field->setup($element, null); return $field->__get('input'); } /** * Construct the HTML for the input field in a tree * Logic from administrator\components\com_modules\views\module\tmpl\edit_assignment.php */ public static function treeselect(&$options, $name, $value, $id, $size = 300, $simple = 0, $class = '') { Functions::loadLanguage('com_menus', JPATH_ADMINISTRATOR); Functions::loadLanguage('com_modules', JPATH_ADMINISTRATOR); if (empty($options)) { return '
' . Text::_('NR_NO_ITEMS_FOUND') . '
'; } if (!is_array($value)) { $value = explode(',', $value); } $count = 0; if ($options != -1) { foreach ($options as $option) { $count++; if (isset($option->links)) { $count += count($option->links); } } } if ($options == -1) { if (is_array($value)) { $value = implode(',', $value); } if (!$value) { $input = ''; } else { $input = ''; } return '
' . $input . '
'; } if ($simple) { $attr = 'style="width: ' . $size . 'px" multiple="multiple"'; if (!empty($class)) { $attr .= ' class="' . $class . '"'; } $html = HTMLHelper::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); return $html; } HTMLHelper::script('plg_system_nrframework/treeselect.js', ['relative' => true, 'version' => true]); HTMLHelper::stylesheet('plg_system_nrframework/treeselect.css', ['relative' => true, 'version' => true]); $html = array(); $html[] = '
'; $html[] = ' '; $o = array(); foreach ($options as $option) { $option->level = isset($option->level) ? $option->level : 0; $o[] = $option; if (isset($option->links)) { foreach ($option->links as $link) { $link->level = $option->level + (isset($link->level) ? $link->level : 1); $o[] = $link; } } } $html[] = '
    '; $prevlevel = 0; foreach ($o as $i => $option) { if ($prevlevel < $option->level) { // correct wrong level indentations $option->level = $prevlevel + 1; $html[] = '
      '; } else if ($prevlevel > $option->level) { $html[] = str_repeat('
    ', $prevlevel - $option->level); } else if ($i) { $html[] = ''; } $labelclass = trim('pull-left ' . (isset($option->labelclass) ? $option->labelclass : '')); $html[] = '
  • '; $item = '
    '; if (isset($option->title)) { $labelclass .= ' nav-header'; } if (isset($option->title) && (!isset($option->value) || !$option->value)) { $item .= ''; } else { $selected = in_array($option->value, $value) ? ' checked="checked"' : ''; $disabled = (isset($option->disable) && $option->disable) ? ' readonly="readonly" style="visibility:hidden"' : ''; $item .= ' '; } $item .= '
    '; $html[] = $item; if (!isset($o[$i + 1]) && $option->level > 0) { $html[] = str_repeat('
', (int) $option->level); } $prevlevel = $option->level; } $html[] = ''; $html[] = ' '; $html[] = '
'; $html = implode('', $html); return $html; } public static function treeselectSimple(&$options, $name, $value, $id, $size = 300, $class = '') { return self::treeselect($options, $name, $value, $id, $size, 1, $class); } /** * Wrapper for the HTMLHelper::script method to support old method signatures in Joomla < 3.7.0. * * @param string $path * * @deprecated Since we no longer support 3.7.0, use HTMLHelper::script directly. * @return void */ public static function script($path) { if (version_compare(JVERSION, '3.7.0', 'lt')) { HTMLHelper::script($path, false, true); } else { HTMLHelper::script($path, ['relative' => true, 'version' => 'auto']); } } /** * Wrapper for the HTMLHelper::stylesheet method to support old method signatures in Joomla < 3.7.0. * * @param string $path * * @return void * @deprecated Since we no longer support 3.7.0, use HTMLHelper::script directly. */ public static function stylesheet($path) { if (version_compare(JVERSION, '3.7.0', 'lt')) { HTMLHelper::stylesheet($path, false, true); } else { HTMLHelper::stylesheet($path, ['relative' => true, 'version' => 'auto']); } } /** * For Backwards Compatibility * * @deprecated 4.9.50 */ public static function checkForOutdatedExtension($extension, $days_old = 120) { if (!Extension::isOutdated($extension, $days_old)) { return; } // Load extension's language file Functions::loadLanguage($extension); $payload = [ 'extension' => Text::_($extension), 'days_old' => $days_old ]; // load template return LayoutHelper::render('outdated_extension', $payload, dirname(__DIR__) . '/layouts'); } public static function updateNotification($extension) { $version_installed = Extension::getVersion($extension); $version_latest = Extension::getLatestVersion($extension); if (!$needsUpdate = version_compare($version_latest, $version_installed, 'gt')) { return; } // Load extension's language file Functions::loadLanguage($extension); // Extension Title $title = Text::_($extension); $title = str_replace('System -', '', $title); // Remove plugin folder prefix from plugins // Render Layout $data = [ 'title' => $title, 'version_installed' => $version_installed, 'version_latest' => $version_latest, 'ispro' => Extension::isPro($extension), 'upgradeurl' => Extension::getTassosExtensionUpgradeURL($extension), 'product_url' => Extension::getProductURL($extension) ]; return LayoutHelper::render('updatechecker', $data, JPATH_PLUGINS . '/system/nrframework/layouts'); } /** * TODO: Not used anywhere, should delete. * * @deprecated 4.11.7 */ public static function checkForUpdates($element) { HTMLHelper::script('plg_system_nrframework/updatechecker.js', ['relative' => true, 'version' => true]); HTMLHelper::stylesheet('plg_system_nrframework/updatechecker.css', ['relative' => true, 'version' => true]); return '
'; } }