* @git Joomla Component Builder * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // No direct access to this file defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Registry\Registry; JLoader::register('ComponentbuilderHelper', JPATH_ADMINISTRATOR . '/components/com_componentbuilder/helpers/componentbuilder.php'); /** * Extension - Componentbuilder Headers Compiler plugin. * * @package ComponentbuilderHeadersCompiler * @since 2.1.0 */ class PlgExtensionComponentbuilderHeadersCompiler extends CMSPlugin { /** * Global switch to see if a file has custom headers. * * @var boolean * @since 1.0.0 */ protected $loadHeaders = false; /** * The active headers * * @var array * @since 1.0.8 */ protected $activeHeaders = array(); /** * The compiler placeholders values * * @var array * @since 1.0.6 */ protected $placeholders = array(); /** * The powers to include in project * * @var array * @since 1.0.6 */ protected $linkedPowers = array(); /** * The Targets * * @var array * @since 1.0.8 */ protected $targets = array( 'admin_view_headers' => array( 'add_admin_view_model' => array( 'field' => 'admin_view_model', 'context' => 'admin.view.model', 'view' => 'name_single' ), 'add_admin_view' => array( 'field' => 'admin_view', 'context' => 'admin.view', 'view' => 'name_single' ), 'add_admin_view_html' => array( 'field' => 'admin_view_html', 'context' => 'admin.view.html', 'view' => 'name_single' ), 'add_site_admin_view_html' => array( 'field' => 'site_admin_view_html', 'context' => 'site.admin.view.html', 'view' => 'name_single' ), 'add_admin_view_controller' => array( 'field' => 'admin_view_controller', 'context' => 'admin.view.controller', 'view' => 'name_single' ), 'add_ajax_model' => array( 'field' => 'ajax_model', 'context' => 'ajax.admin.model', 'view' => 'ajax' ), 'add_admin_views_model' => array( 'field' => 'admin_views_model', 'context' => 'admin.views.model', 'view' => 'name_list' ), 'add_admin_views' => array( 'field' => 'admin_views', 'context' => 'admin.views', 'view' => 'name_list' ), 'add_admin_views_html' => array( 'field' => 'admin_views_html', 'context' => 'admin.views.html', 'view' => 'name_list' ), 'add_admin_views_controller' => array( 'field' => 'admin_views_controller', 'context' => 'admin.views.controller', 'view' => 'name_list' ) ), 'site_view_headers' => array( 'add_site_view_model' => array( 'field' => 'site_view_model', 'context' => 'site.view.model', 'view' => 'code' ), 'add_site_view' => array( 'field' => 'site_view', 'context' => 'site.view', 'view' => 'code' ), 'add_site_view_html' => array( 'field' => 'site_view_html', 'context' => 'site.view.html', 'view' => 'code' ), 'add_site_view_controller' => array( 'field' => 'site_view_controller', 'context' => 'site.view.controller', 'view' => 'code' ), 'add_site_views_model' => array( 'field' => 'site_views_model', 'context' => 'site.views.model', 'view' => 'code' ), 'add_site_views' => array( 'field' => 'site_views', 'context' => 'site.views', 'view' => 'code' ), 'add_site_views_html' => array( 'field' => 'site_views_html', 'context' => 'site.views.html', 'view' => 'code' ), 'add_site_views_controller' => array( 'field' => 'site_views_controller', 'context' => 'site.views.controller', 'view' => 'code' ), 'add_ajax_model' => array( 'field' => 'ajax_model', 'context' => 'ajax.site.model', 'view' => 'ajax' ) ), 'custom_admin_view_headers' => array( 'add_custom_admin_view_model' => array( 'field' => 'custom_admin_view_model', 'context' => 'custom.admin.view.model', 'view' => 'code' ), 'add_custom_admin_view' => array( 'field' => 'custom_admin_view', 'context' => 'custom.admin.view', 'view' => 'code' ), 'add_custom_admin_view_html' => array( 'field' => 'custom_admin_view_html', 'context' => 'custom.admin.view.html', 'view' => 'code' ), 'add_custom_admin_view_controller' => array( 'field' => 'custom_admin_view_controller', 'context' => 'custom.admin.view.controller', 'view' => 'code' ), 'add_custom_admin_views_model' => array( 'field' => 'custom_admin_views_model', 'context' => 'custom.admin.views.model', 'view' => 'code' ), 'add_custom_admin_views' => array( 'field' => 'custom_admin_views', 'context' => 'custom.admin.views', 'view' => 'code' ), 'add_custom_admin_views_html' => array( 'field' => 'custom_admin_views_html', 'context' => 'custom.admin.views.html', 'view' => 'code' ), 'add_custom_admin_views_controller' => array( 'field' => 'custom_admin_views_controller', 'context' => 'custom.admin.views.controller', 'view' => 'code' ), 'add_ajax_model' => array( 'field' => 'ajax_model', 'context' => 'ajax.admin.model', 'view' => 'ajax' ) ), 'dynamic_get_headers' => array( 'add_site_view_model' => array( 'field' => 'site_view_model', 'context' => 'site.view.model', 'view' => 'code' ), 'add_site_view' => array( 'field' => 'site_view', 'context' => 'site.view', 'view' => 'code' ), 'add_site_view_html' => array( 'field' => 'site_view_html', 'context' => 'site.view.html', 'view' => 'code' ), 'add_site_view_controller' => array( 'field' => 'site_view_controller', 'context' => 'site.view.controller', 'view' => 'code' ), 'add_site_views_model' => array( 'field' => 'site_views_model', 'context' => 'site.views.model', 'view' => 'code' ), 'add_site_views' => array( 'field' => 'site_views', 'context' => 'site.views', 'view' => 'code' ), 'add_site_views_html' => array( 'field' => 'site_views_html', 'context' => 'site.views.html', 'view' => 'code' ), 'add_site_views_controller' => array( 'field' => 'site_views_controller', 'context' => 'site.views.controller', 'view' => 'code' ), 'add_custom_admin_view_model' => array( 'field' => 'custom_admin_view_model', 'context' => 'custom.admin.view.model', 'view' => 'code' ), 'add_custom_admin_view' => array( 'field' => 'custom_admin_view', 'context' => 'custom.admin.view', 'view' => 'code' ), 'add_custom_admin_view_html' => array( 'field' => 'custom_admin_view_html', 'context' => 'custom.admin.view.html', 'view' => 'code' ), 'add_custom_admin_view_controller' => array( 'field' => 'custom_admin_view_controller', 'context' => 'custom.admin.view.controller', 'view' => 'code' ), 'add_custom_admin_views_model' => array( 'field' => 'custom_admin_views_model', 'context' => 'custom.admin.views.model', 'view' => 'code' ), 'add_custom_admin_views' => array( 'field' => 'custom_admin_views', 'context' => 'custom.admin.views', 'view' => 'code' ), 'add_custom_admin_views_html' => array( 'field' => 'custom_admin_views_html', 'context' => 'custom.admin.views.html', 'view' => 'code' ), 'add_custom_admin_views_controller' => array( 'field' => 'custom_admin_views_controller', 'context' => 'custom.admin.views.controller', 'view' => 'code' ), 'add_ajax_model' => array( 'field' => 'ajax_model', 'context' => 'ajax.admin.model', 'view' => 'ajax' ) ), 'component_dashboard_headers' => array( 'add_dashboard_model' => array( 'field' => 'dashboard_model', 'context' => 'dashboard.model', 'view' => 'dashboard' ), 'add_dashboard_view' => array( 'field' => 'dashboard_view', 'context' => 'dashboard.view', 'view' => 'dashboard' ), 'add_dashboard_view_html' => array( 'field' => 'dashboard_view_html', 'context' => 'dashboard.view.html', 'view' => 'dashboard' ), 'add_dashboard_controller' => array( 'field' => 'dashboard_controller', 'context' => 'dashboard.controller', 'view' => 'dashboard' ), 'add_ajax_model' => array( 'field' => 'ajax_model', 'context' => 'ajax.admin.model', 'view' => 'ajax' ) ), 'joomla_component_headers' => array( 'add_admin_component' => array( 'field' => 'admin_component', 'context' => 'admin.component', 'view' => 'admin' ), 'add_site_component' => array( 'field' => 'site_component', 'context' => 'site.component', 'view' => 'site' ), 'add_admin_helper' => array( 'field' => 'admin_helper', 'context' => 'admin.helper', 'view' => 'admin' ), 'add_site_helper' => array( 'field' => 'site_helper', 'context' => 'site.helper', 'view' => 'site' ) ) ); /** * Event Triggered in the compiler [on Before Model View Data] * * @return void * * @since 1.0 */ public function jcb_ce_onBeforeModelViewData(&$context, &$view, &$placeholders) { // check that the params are set if (isset($view->params)) { // add the headers for the Admin Views $this->setHeaders($view->params, $view, 'admin_view_headers'); } } /** * Event Triggered in the compiler [on Before Model Custom View Data] * * @return void * * @since 1.0.2 */ public function jcb_ce_onBeforeModelCustomViewData(&$context, &$view, &$id, &$table) { // check that the params are set if (isset($view->params)) { // add the headers for the Site Views $this->setHeaders($view->params, $view, 'site_view_headers'); // add the headers for the Custom Admin Views $this->setHeaders($view->params, $view, 'custom_admin_view_headers'); } } /** * Event Triggered in the compiler [on Before Model Dynamic Get Data] * * @return void * * @since 1.0.10 */ public function jcb_ce_onBeforeModelDynamicGetData(&$context, &$dynamicGet, &$id, &$code, &$area) { // check that the params are set if (isset($dynamicGet->params)) { // add the headers for the Site Views $this->setDynamicHeaders($dynamicGet->params, $code, 'dynamic_get_headers'); } } /** * Event Triggered in the compiler [on Before Model Component Data] * * @return void * * @since 1.0.4 */ public function jcb_ce_onBeforeModelComponentData(&$context, &$component) { // check that the params are set if (isset($component->params)) { // add the headers for the Joomla Component $this->setHeaders($component->params, $component, 'joomla_component_headers'); } // check that the dashboard params are set if (isset($component->dashboard_params)) { // add the headers for the Component Dashboard $this->setHeaders($component->dashboard_params, $component, 'component_dashboard_headers'); } } /** * Event Triggered in the compiler [on set Class Header] * * @return void * * @since 1.0 */ public function jcb_ce_setClassHeader(&$context, &$event_context, &$view_name, &$headers) { if ($this->loadHeaders && isset($this->activeHeaders[$view_name]) && isset($this->activeHeaders[$view_name][$event_context])) { // we have default headers we actually need foreach ($headers as $n => $header) { // if an empty line is found just skip it if (empty($header)) { continue; } // we check if this header is also set from the user if (isset($this->activeHeaders[$view_name][$event_context]) && strpos( $this->activeHeaders[$view_name][$event_context], $header ) !== false) { // since it is set, remove it here unset($headers[$n]); } } // now add the custom headers // yes they are below the defaults, unless overridden and removed above $headers[] = $this->activeHeaders[$view_name][$event_context]; } } /** * Event Triggered in the compiler [on Before Get Component Data] * * @return void * * @since 1.0.6 */ public function jcb_ce_onBeforeGetComponentData(&$context, $compiler) { // get placeholders from the compiler $this->placeholders = $compiler->globalPlaceholders; } /** * Event Triggered in the compiler [on After Get Component Data] * * @return void * * @since 1.0.6 */ public function jcb_ce_onAfterGetComponentData(&$context, $compiler) { // add the powers to the component if (ComponentbuilderHelper::checkArray($this->linkedPowers, true)) { $compiler->linkedPowers = $this->linkedPowers; } } /** * set the headers * * @return void * * @since 1.0.8 */ protected function setHeaders(&$params, &$obj, $key) { // add the headers $params = (ComponentbuilderHelper::checkJson($params)) ? json_decode($params, true) : $params; // make sure we have the keys values in the params area if (ComponentbuilderHelper::checkArray($params) && isset($params[$key]) && ComponentbuilderHelper::checkArray($params[$key])) { foreach ($this->targets[$key] as $target => $event) { if (isset($params[$key][$target]) && $params[$key][$target] == 1) { // get the header string if set $this->getHeaders( $params[$key], $event, $this->getViewName( $obj, $event['view'] ) ); } } } } /** * set the dynamic get headers * * @return void * * @since 1.0.10 */ protected function setDynamicHeaders($params, $code, $key) { // add the headers $params = (ComponentbuilderHelper::checkJson($params)) ? json_decode($params, true) : $params; // make sure we have the keys values in the params area if (ComponentbuilderHelper::checkArray($params) && isset($params[$key]) && ComponentbuilderHelper::checkArray($params[$key])) { foreach ($this->targets[$key] as $target => $event) { if (isset($params[$key][$target]) && $params[$key][$target] == 1) { // get the header string if set $this->getHeaders( $params[$key], $event, $code ); } } } } /** * get the headers * * @return void * * @since 1.0 */ protected function getHeaders(&$params, &$get, $view_name) { // we first check if the value is set if (isset($params[$get['field']]) || isset($params['power_' . $get['field']])) { // start little headers bucket $headers = array(); // load the headers if text if (isset($params[$get['field']]) && ComponentbuilderHelper::checkString($params[$get['field']])) { $headers[] = $params[$get['field']]; } // load the headers if power if (isset($params['power_' . $get['field']]) && ComponentbuilderHelper::checkArray($params['power_' . $get['field']], true) && ($powers = $this->getPowers($params['power_' . $get['field']])) !== false) { $headers[] = $powers; } // check if we found some header values if (ComponentbuilderHelper::checkArray($headers, true)) { // activate the load of the headers $this->loadHeaders = true; // check if this active header is already set if (!isset($this->activeHeaders[$view_name][$get['context']])) { // start the active header $this->activeHeaders[$view_name][$get['context']] = ''; } else { // each addition we add a new line $this->activeHeaders[$view_name][$get['context']] = PHP_EOL; } // load the found headers $this->activeHeaders[$view_name][$get['context']] .= implode(PHP_EOL, $headers); } } } /** * get the view name * * @return string * * @since 1.0.8 */ protected function getViewName(&$view, &$get) { if ($get === 'site' || $get === 'admin' || $get === 'ajax' || $get === 'dashboard') { // static key name return $get; } elseif (isset($view->{$get})) { return ComponentbuilderHelper::safeString( $view->{$get} ); } return '_error'; } /** * get the powers header use strings * * @return mixed * * @since 1.0.6 */ protected function getPowers($rows) { // load the active powers $powers = array_filter( // get the power namespace array_map(function ($row) { if (($power = ComponentbuilderHelper::getGUID($row['power'], 'power', ['a.guid', 'a.namespace'])) !== false) { $power->build = (int) $row['build']; $power->as = (string) $row['as']; return $power; } return false; }, $rows), // check that we have valid powers function ($row) { return is_object($row) && isset($row->guid); } ); // add to active powers if (ComponentbuilderHelper::checkArray($powers)) { // convert the dots to namespace $powers = array_map(function ($power) { // add to compiler (to build) if ($power->build != 6) { // secure that always will remain always even if only set that way once if (empty($this->linkedPowers[$power->guid]) || $power->build == 1) { $this->linkedPowers[$power->guid] = $power->build; } } // build the namespace $namespace = ComponentbuilderHelper::safeNamespace( str_replace( array_keys($this->placeholders), array_values($this->placeholders), str_replace('.', '\\', $power->namespace) ) ); // check if it has an AS option if (ComponentbuilderHelper::checkString($power->as) && $power->as !== 'default') { return 'use ' . $namespace . ' as ' . $power->as . ';'; } return 'use ' . $namespace . ';'; }, $powers); // return the found powers return implode(PHP_EOL, $powers); } return false; } }