Server : LiteSpeed System : Linux server 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64 User : alsaif ( 1057) PHP Version : 7.4.33 Disable Function : show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/alsaif/public_html/plugins/system/nrframework/NRFramework/Widgets/ |
<?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\Widgets;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\Registry\Registry;
use Joomla\CMS\HTML\HTMLHelper;
class Accordion extends Widget
{
/**
* Widget default options
*
* @var array
*/
protected $widget_options = [
/**
* Accordion Settings
*/
/**
* The titles and contents of the accordion items.
*
* Format:
*
* [
* [
* 'title' => 'Title 1',
* 'content' => 'Content 1'
* ],
* [
* 'title' => 'Title 2',
* 'content' => 'Content 2'
* ],
* ]
*/
'value' => '',
/**
* Choose how spacious or compact you'd like to list accordion.
* Consider this the padding of each accordion item.
*
* Available values:
* - none
* - default
* - comfortable
* - compact
*/
'density' => 'default',
// Set the font size.
'font_size' => '16px',
/**
* Set the gap between the items.
*
* Available values:
* - none
* - small
* - large
*/
'gap' => 'none',
// Set the background color of the panel.
'panel_background_color' => '#fff',
// Set the color of the text and the icon.
'text_color' => '#333',
// Set the color of the 1px border that affects both item and container. Set to 'none' for no border color.
'border_color' => '#ddd',
/**
* Set the rounded corners of the items.
*
* Available values:
* - none
* - small
* - large
*/
'rounded_corners' => 'small',
/**
* Item Icon Settings
*/
/**
* Set whether to display a toggle icon next to the title, or not.
*
* Available values:
* - none
* - left
* - right
*/
'show_icon' => 'left',
/**
* Set the icon URL.
*/
'icon' => '',
/**
* Behavior
*/
/**
* Define the initial state of the accordion.
* By default all items are initially shown collapsed.
*
* Available values:
*
* - collapsed: All panels appear as collapsed.
* - expanded: All panels appear as expanded.
* - expanded-first: Expand the first panel only.
*/
'initial_state' => 'collapsed',
// Set whether to allow only one panel to be expanded at a time.
'only_one_panel_expanded' => false,
// Set whether to generate the FAQ Schema on the page.
'generate_faq' => false,
// Custom Panel CSS Class
'panel_css_class' => ''
];
/**
* Class constructor
*
* @param array $options
*/
public function __construct($options = [])
{
parent::__construct($options);
$this->prepare();
}
/**
* Prepares the FAQ.
*
* @return void
*/
private function prepare()
{
$this->validateValue();
$this->generateFAQ();
// Set density
switch ($this->options['density'])
{
case 'none':
$this->options['density'] = 0;
break;
case 'default':
$this->options['density'] = '1em 1.25em';
break;
case 'comfortable':
$this->options['density'] = '1.25em 1.75em';
break;
case 'compact':
$this->options['density'] = '.65em 1.25em';
break;
}
// Set gap
switch ($this->options['gap'])
{
case 'none':
$this->options['gap'] = 0;
break;
case 'small':
$this->options['gap'] = '.3em';
break;
case 'large':
$this->options['gap'] = '.7em';
break;
}
// Set rounded corners
switch ($this->options['rounded_corners'])
{
case 'none':
$this->options['rounded_corners'] = 0;
break;
case 'small':
$this->options['rounded_corners'] = '.3em';
break;
case 'large':
$this->options['rounded_corners'] = '.7em';
break;
}
if ($this->options['only_one_panel_expanded'])
{
$this->options['css_class'] .= ' only-one-panel-expanded';
}
if ($this->options['load_css_vars'])
{
$this->options['custom_css'] = $this->getWidgetCSS();
}
}
/**
* Validates the value.
*
* @return void
*/
private function validateValue()
{
if (!is_array($this->options['value']))
{
return;
}
$st = new \NRFramework\SmartTags\SmartTags();
foreach ($this->options['value'] as $key => &$val)
{
if ((isset($val['title']) && empty($val['title'])) && (isset($val['content'])) && empty($val['content']))
{
unset($this->options['value'][$key]);
}
if ($this->options['pro'])
{
$val['title'] = HTMLHelper::_('content.prepare', $val['title']);
$val['content'] = HTMLHelper::_('content.prepare', $val['content']);
}
}
}
/**
* Generates the FAQ.
*
* @return void
*/
private function generateFAQ()
{
// Ensure "generate_faq" is enabled
if (!$this->options['generate_faq'])
{
return;
}
// Ensure we have value
if (!is_array($this->options['value']) && !count($this->options['value']))
{
return;
}
// Abort if FAQ cannot be compiled
if (!$faq = $this->getFAQ())
{
return;
}
// Hook into GSD to add the FAQ
Factory::getApplication()->registerEvent('onGSDBeforeRender', function(&$data) use ($faq)
{
try
{
// get the data
$tmpData = $data;
if (defined('nrJ4'))
{
$tmpData = $data->getArgument('0');
}
// Append the FAQ Schema
$tmpData[] = $faq;
// Ensure unique FAQ
$tmpData = array_unique($tmpData);
// Set back the new value to $data object
if (defined('nrJ4'))
{
$data->setArgument(0, $tmpData);
}
else
{
$data = $tmpData;
}
} catch (\Throwable $th)
{
$this->throwError($th->getMessage());
}
});
}
/**
* Returns the FAQ JSON/LD code.
*
* @return string
*/
private function getFAQ()
{
$autoload_file = JPATH_ADMINISTRATOR . '/components/com_gsd/autoload.php';
if (!file_exists($autoload_file))
{
return;
}
require_once $autoload_file;
$value = $this->options['value'];
if (is_array($value))
{
foreach ($value as $key => &$val)
{
if (isset($val['title']))
{
$val['question'] = $val['title'];
unset($val['title']);
}
if (isset($val['content']))
{
$val['answer'] = $val['content'];
unset($val['content']);
}
}
}
// Prepare the FAQ
$payload = [
'mode' => 'manual',
'faq_repeater_fields' => json_decode(json_encode($value))
];
$payload = new Registry($payload);
$faq = new \GSD\Schemas\Schemas\FAQ($payload);
// Get the JSON/LD code of the FAQ
$json = new \GSD\Json($faq->get());
// Return the code
return $json->generate();
}
/**
* Returns the CSS for the widget.
*
* @param array $exclude_breakpoints Define breakpoints to exclude their CSS
*
* @return string
*/
public function getWidgetCSS($exclude_breakpoints = [])
{
$border_color = $this->options['border_color'] !== 'none' ? $this->options['border_color'] : 'transparent';
$controls = [];
// If no density is set, set the padding-top to 5px
if (!$this->options['density'])
{
$controls[] = [
'property' => '--content-padding-top',
'value' => '5px'
];
}
if (!$this->options['gap'])
{
$controls[] = [
'property' => '--container-border-color',
'value' => $border_color
];
$this->options['css_class'] .= ' no-gap';
}
$controls = array_merge($controls, [
// CSS Variables
[
'property' => '--panel-background-color',
'value' => $this->options['panel_background_color']
],
[
'property' => '--text-color',
'value' => $this->options['text_color']
],
[
'property' => '--panel-border-color',
'value' => $border_color
],
// CSS
[
'property' => '--padding',
'type' => 'Spacing',
'value' => $this->options['density']
],
[
'property' => '--gap',
'value' => $this->options['gap'],
'unit' => 'px'
],
[
'property' => '--rounded-corners',
'type' => 'Spacing',
'value' => $this->options['rounded_corners'],
'unit' => 'px'
],
[
'property' => '--font-size',
'value' => $this->options['font_size'],
'unit' => 'px'
]
]);
$selector = '.tf-accordion-widget.' . $this->options['id'];
$controlsInstance = new \NRFramework\Controls\Controls(null, $selector, $exclude_breakpoints);
if (!$controlsCSS = $controlsInstance->generateCSS($controls))
{
return;
}
return $controlsCSS;
}
/**
* Returns all CSS files.
*
* @return array
*/
public static function getCSS()
{
return [
'plg_system_nrframework/widgets/accordion.css'
];
}
/**
* Returns all JS files.
*
* @param string $theme
*
* @return array
*/
public static function getJS()
{
return [
'plg_system_nrframework/widgets/accordion.js'
];
}
}