Files
conservatorio-tomadini/plugins/system/nrframework/NRFramework/HTML.php
2024-12-31 11:07:09 +01:00

508 lines
14 KiB
PHP

<?php
/**
* @author Tassos Marinos <info@tassos.gr>
* @link https://www.tassos.gr
* @copyright Copyright © 2024 Tassos All Rights Reserved
* @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> 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 name="pro" type="nr_pro"
buttonClass="' . $buttonClass . '"
label="' . $feature_label . '"
/>');
$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 name="pro" type="SmartTagsBox"/>');
$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 '<fieldset class="radio">' . Text::_('NR_NO_ITEMS_FOUND') . '</fieldset>';
}
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 = '<textarea name="' . $name . '" id="' . $id . '" cols="40" rows="5">' . $value . '</textarea>';
}
else
{
$input = '<input type="text" name="' . $name . '" id="' . $id . '" value="' . $value . '" size="60">';
}
return '<fieldset class="radio"><label for="' . $id . '">' . Text::_('NR_ITEM_IDS') . ':</label>' . $input . '</fieldset>';
}
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[] = '<div class="nr_treeselect" id="' . $id . '">';
$html[] = '
<div class="form-inline nr_treeselect-controls">
<span class="nr_treeselect_control">' . Text::_('JSELECT') . ':
<a class="nr_treeselect-checkall" href="javascript:;">' . Text::_('JALL') . '</a>,
<a class="nr_treeselect-uncheckall" href="javascript:;">' . Text::_('JNONE') . '</a>,
<a class="nr_treeselect-toggleall" href="javascript:;">' . Text::_('NR_TOGGLE') . '</a>
</span>
<span class="nr_treeselect_control">' . Text::_('NR_EXPAND') . ':
<a class="nr_treeselect-expandall" href="javascript:;">' . Text::_('JALL') . '</a>,
<a class="nr_treeselect-collapseall" href="javascript:;">' . Text::_('JNONE') . '</a>
</span>
<span class="nr_treeselect_control">' . Text::_('JSHOW') . ':
<a class="nr_treeselect-showall" href="javascript:;">' . Text::_('JALL') . '</a>,
<a class="nr_treeselect-showselected" href="javascript:;">' . Text::_('NR_SELECTED') . '</a>
</span>
<span class="nr_treeselect_control nr_treeselect-filter right">
<input type="text" name="nr_treeselect-filter" class="search-query nr_treeselect-filter" size="16"
autocomplete="off" placeholder="' . Text::_('JSEARCH_FILTER') . '" aria-invalid="false" tabindex="-1">
</span>
</div>';
$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[] = '<ul class="nr_treeselect-ul" style="max-height:300px;min-width:' . $size . 'px;overflow-x: hidden;">';
$prevlevel = 0;
foreach ($o as $i => $option)
{
if ($prevlevel < $option->level)
{
// correct wrong level indentations
$option->level = $prevlevel + 1;
$html[] = '<ul class="nr_treeselect-sub">';
}
else if ($prevlevel > $option->level)
{
$html[] = str_repeat('</li></ul>', $prevlevel - $option->level);
}
else if ($i)
{
$html[] = '</li>';
}
$labelclass = trim('pull-left ' . (isset($option->labelclass) ? $option->labelclass : ''));
$html[] = '<li>';
$item = '<div class="' . trim('nr_treeselect-item pull-left ' . (isset($option->class) ? $option->class : '')) . '">';
if (isset($option->title))
{
$labelclass .= ' nav-header';
}
if (isset($option->title) && (!isset($option->value) || !$option->value))
{
$item .= '<label class="' . $labelclass . '">' . $option->title . '</label>';
}
else
{
$selected = in_array($option->value, $value) ? ' checked="checked"' : '';
$disabled = (isset($option->disable) && $option->disable) ? ' readonly="readonly" style="visibility:hidden"' : '';
$item .= '<input type="checkbox" class="pull-left" name="' . $name . '" id="' . $id . $option->value . '" value="' . $option->value . '"' . $selected . $disabled . '>
<label for="' . $id . $option->value . '" class="' . $labelclass . '">' . $option->text . '</label>';
}
$item .= '</div>';
$html[] = $item;
if (!isset($o[$i + 1]) && $option->level > 0)
{
$html[] = str_repeat('</li></ul>', (int) $option->level);
}
$prevlevel = $option->level;
}
$html[] = '</ul>';
$html[] = '
<div style="display:none;" class="nr_treeselect-menu-block">
<div class="pull-left nav-hover nr_treeselect-menu">
<div class="btn-group">
<a href="#" data-toggle="dropdown" data-bs-toggle="dropdown" class="dropdown-toggle btn btn-secondary">
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li class="nav-header">' . Text::_('COM_MODULES_SUBITEMS') . '</li>
<li class="divider"></li>
<li>
<a class="checkall" href="javascript:;">
<span class="icon-checkbox"></span>
' . Text::_('JSELECT') . '
</a>
</li>
<li>
<a class="uncheckall" href="javascript:;">
<span class="icon-checkbox-unchecked"></span>
' . Text::_('COM_MODULES_DESELECT') . '
</a>
</li>
<div class="nr_treeselect-menu-expand">
<li class="divider"></li>
<li><a class="expandall" href="javascript:;"><span class="icon-plus"></span> ' . Text::_('NR_EXPAND') . '</a></li>
<li><a class="collapseall" href="javascript:;"><span class="icon-minus"></span> ' . Text::_('NR_COLLAPSE') . '</a></li>
</div>
</ul>
</div>
</div>
</div>';
$html[] = '</div>';
$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 '
<div class="nr_updatechecker"
data-element="' . $element. '"
data-base=' . Uri::base() . '
data-token=' . Session::getFormToken() . '>
</div>
';
}
}