Файловый менеджер - Редактировать - /home/lmsyaran/public_html/joomla5/plugins/content/fabrik/fabrik.php
Назад
<?php /** * Insert Fabrik Content into Joomla Articles * * @package Joomla.Plugin * @subpackage Content.fabrik * @copyright Copyright (C) 2005-2020 Media A-Team, Inc. - All rights reserved. * @license GNU/GPL http://www.gnu.org/copyleft/gpl.html */ // No direct access defined('_JEXEC') or die('Restricted access'); use Joomla\Registry\Registry; use Joomla\CMS\MVC\Model\BaseDatabaseModel; use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\Table\Table; use Joomla\CMS\Language\Text; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Factory; use Joomla\String\StringHelper; jimport('joomla.plugin.plugin'); /** * Fabrik content plugin - renders forms, lists and visualizations * * @package Joomla.Plugin * @subpackage Content.fabrik * @since 1.5 */ #[\AllowDynamicProperties] class PlgContentFabrik extends CMSPlugin { /** * Prepare content method * * Method is called by the view * * @param string $context The context of the content being passed to the plugin. * @param object &$row The article object. Note $article->text is also available * @param object &$params The article params * @param int $page The 'page' number * * @return void */ public function onContentPrepare($context, &$row, &$params, $page = 0) { jimport('joomla.html.parameter'); jimport('joomla.filesystem.file'); //Fabrik doesn't play with Smart Search indexer; don't run content plugin when indexing if ($context == 'com_finder.indexer') return true; // Load fabrik language $lang = Factory::getApplication()->getLanguage(); $lang->load('com_fabrik', JPATH_ROOT . '/components/com_fabrik'); // Don't throw an exception, just don't do nuthin' if system plugin hasn't run if (!defined('COM_FABRIK_FRONTEND')) { //throw new RuntimeException(Text::_('COM_FABRIK_SYSTEM_PLUGIN_NOT_ACTIVE'), 400); return true; } // Get plugin info $plugin = PluginHelper::getPlugin('content', 'fabrik'); // $$$ hugh had to rename this, it was stomping on com_content and friends $params // $$$ which is passed by reference to us! $fParams = new Registry($plugin->params); // Simple performance check to determine whether bot should process further $botRegex = $fParams->get('botRegex') != '' ? $fParams->get('botRegex') : 'fabrik'; if (StringHelper::strpos($row->text, '{' . $botRegex) === false) { return true; } /* $$$ hugh - hacky fix for nasty issue with IE, which (for gory reasons) doesn't like having our JS content * wrapped in P tags. But the default WYSIWYG editor in J! will automagically wrap P tags around everything. * So let's just look for obvious cases of <p>{fabrik ...}</p>, and replace the P's with DIV's. * Yes, it's hacky, but it'll save us a buttload of support work. */ $pregex = "/<p>\s*{" . $botRegex . "\s*.*?}\s*<\/p>/i"; $row->text = preg_replace_callback($pregex, array($this, 'preplace'), $row->text); // $$$ hugh - having to change this to use {[]} $regex = "/{" . $botRegex . "\s+.*?}/i"; $row->text = preg_replace_callback($regex, array($this, 'replace'), $row->text); } /** * Unwrap placeholder text from possible <p> tags * * @param array $match preg matched {fabrik} tag * * @return string */ protected function preplace($match) { $match = $match[0]; $match = StringHelper::str_ireplace('<p>', '<div>', $match); $match = StringHelper::str_ireplace('</p>', '</div>', $match); return $match; } /** * Parse the {fabrik} tag * * @param array $match {fabrik} preg match * * @return string */ protected function parse($match) { $match = $match[0]; // $$$ hugh - see if we can remove formatting added by WYSIWYG editors $match = strip_tags($match); $w = new FabrikWorker; $match = preg_replace('/\s+/', ' ', $match); /* $$$ hugh - only replace []'s in value, not key, so we handle * ranged filters and 'complex' filters */ $match2 = array(); foreach (explode(" ", $match) as $m) { if (strstr($m, '=')) { list($key, $val) = explode('=', $m); $val = str_replace('[', '{', $val); $val = str_replace(']', '}', $val); $match2[] = $key . '=' . $val; } else { $match2[] = $m; } } $match = implode(' ', $match2); $w->replaceRequest($match); // Stop [] for ranged filters from being removed // $match = str_replace('{}', '[]', $match); $match = $w->parseMessageForPlaceHolder($match); return $match; } /** * the function called from the preg_replace_callback - replace the {} with the correct HTML * * @param string $match plug-in match * * @return void */ protected function replace($match) { $app = Factory::getApplication(); $input = $app->input; $match = $match[0]; $match = trim($match, "{"); $match = trim($match, "}"); $ref = preg_replace('/[^A-Z|a-z|0-9]/', '_', $match); $match = $this->parse(array($match)); $match = explode(" ", $match); array_shift($match); $user = Factory::getUser(); $usersConfig = ComponentHelper::getParams('com_fabrik'); $unused = array(); // Special case if we are wanting to write in an element's data $element = false; $repeatCounter = 0; // Was defaulting to 1 but that forced filters to show in cal viz even with showfilter=no option turned on $showFilters = $input->get('showfilters', null); $clearFilters = $input->get('clearfilters', 0); $resetFilters = $input->get('resetfilters', 0); $this->origRequestVars = array(); $id = 0; $origLayout = $input->get('layout'); $origFLayout = $input->get('flayout'); $layoutFound = false; $rowId = ''; $useKey = ''; $limit = false; $ajax = true; $session = Factory::getSession(); $usersConfig->set('rowid', 0); $viewName = ''; foreach ($match as $m) { $m = explode('=', $m); if (!array_key_exists(1, $m)) { //no valid param; skip with debug message FabrikWorker::logError('Extra characters/spaces' . $m[0] . ' ignored in Fabrik content pluging ' . implode(' ',$match), 'info'); continue; } // $$$ hugh - deal with %20 as space in arguments $m[1] = urldecode(FArrayHelper::getValue($m, 1)); switch ($m[0]) { case 'view': $viewName = StringHelper::strtolower($m[1]); break; case 'id': case 'formid': case 'listid': // Cast to int in case there are two spaces after value. $id = (int) $m[1]; break; case 'layout': $layoutFound = true; $layout = $m[1]; $input->set('layout', $layout); break; case 'row': case 'rowid': $row = $m[1]; // When printing the content the rowid can't be passed in the querystring so don't set here if ($row !== '{rowid}') { if ($row == -1) { $row = $user->get('id'); } $usersConfig->set('rowid', $row); // Set the rowid in the session so that print pages can grab it again $session->set('fabrik.plgcontent.rowid', $row); $rowId = $row; } break; case 'element': // {fabrik view=element list=3 rowid=364 element=fielddatatwo} $viewName = 'list'; $element = $m[1]; break; case 'table': case 'list': $listId = $m[1]; break; case 'limit': $limit = $m[1]; break; case 'usekey': $useKey = $m[1]; break; case 'repeatcounter': $repeatCounter = $m[1]; break; case 'showfilters': $showFilters = $m[1]; break; case 'ajax': $ajax = (bool) $m[1]; break; // $$$ rob for these 2 grab the qs var in priority over the plugin settings case 'clearfilters': $clearFilters = $input->get('clearfilters', $m[1]); break; case 'resetfilters': $resetFilters = $input->get('resetfilters', $m[1]); break; default: if (array_key_exists(1, $m)) { /** * These are later set as app->input vars if present in list view * html_entity_decode to allow for content plugin values to contain * Urlencode the value for plugin statements such as: asylum_events___start_date[condition]=> */ $unused[] = trim($m[0]) . '=' . urlencode(html_entity_decode($m[1], ENT_NOQUOTES)); } } } // Get the rowid in the session so that print pages can use it // Commented out - was messing with element rendering and seems to general to be correct. IE what if more than one content plugin being used // $rowId = $session->get('fabrik.plgcontent.rowid', $rowId); if ($viewName == 'table') { // Some backwards compat with fabrik 2 $viewName = 'list'; } // Moved out of switch as otherwise first plugin to use this will effect all subsequent plugins $input->set('usekey', $useKey); // If no layout defined - set it if (!$layoutFound) { $thisLayout = $input->get('layout'); // Also test for saving an article if ($input->get('option') === 'com_content' && ($thisLayout === 'blog' || ($app->isClient('administrator') && $thisLayout === 'edit'))) { $layout = 'default'; $input->set('layout', $layout); } } /* $$$ hugh - added this so the fabrik2article plugin can arrange to have form CSS * included when the article is rendered by com_content, by inserting ... * {fabrik view=form_css id=X layout=foo} * ... at the top of the article. */ if ($viewName == 'form_css') { // The getFormCss() call blows up if we don't do this jimport('joomla.filesystem.file'); $this->generalIncludes('form'); $controller = $this->getController('form', $id); $view = $this->getView($controller, 'form', $id); $model = $this->getModel($controller, 'form', $id); if (!$model) { return; } $model->setId($id); $model->setEditable(false); $layout = !empty($layout) ? $layout : 'default'; $view->setModel($model, true); $model->getFormCss($layout); return ''; } $this->generalIncludes($viewName); $origRowId = $input->get('rowid'); // Allow plugin to reference the origin rowid in the URL $input->set('origRowId', $origRowId); if ($element !== false) { // Special case for rendering element data $controller = $this->getController('list', $listId); $model = $this->getModel($controller, 'list', $listId); if (!$model) { return; } $model->setId($listId); $formModel = $model->getFormModel(); $groups = $formModel->getGroupsHiarachy(); foreach ($groups as $groupModel) { $elements = $groupModel->getMyElements(); foreach ($elements as &$elementModel) { // $$$ rob 26/05/2011 changed it so that you can pick up joined elements without specifying plugin // param 'element' as joinx[x][fullname] but simply 'fullname' if ($element == $elementModel->getFullName(true, false)) { $activeEl = $elementModel; continue 2; } } } // $$$ hugh in case they have a typo in their elementname if (empty($activeEl) || !$activeEl->isPublished()) { throw new RuntimeException('You are trying to embed an element called ' . $element . ' which is not present in the list or has been unpublished'); } if ($rowId === '') { $rows = $model->getData(); $group = array_shift($rows); $row = array_shift($group); if (empty($row)) { return; } $res = $row->$element; } else { $this->_setRequest($unused); $row = $model->getRow($rowId, false, true); if (substr($element, StringHelper::strlen($element) - 4, StringHelper::strlen($element)) !== '_raw') { $element = $element . '_raw'; } // $$$ hugh - need to pass all row data, or calc elements that use {placeholders} won't work //$defaultData = is_object($row) ? get_object_vars($row) : $row; $defaultData = is_object($row) ? FArrayHelper::fromObject($row, true) : $row; /* $$$ hugh - if we don't do this, our passed data gets blown away when render() merges the form data * not sure why, but apparently if you do $foo =& $bar and $bar is NULL ... $foo ends up NULL */ $activeEl->getFormModel()->data = $defaultData; $activeEl->editable = false; // Set row id for things like user element $input->set('rowid', $rowId); // Set detail view for things like youtube element $origView = $input->get('view'); $input->set('view', 'details'); $defaultData = (array) $defaultData; unset($activeEl->defaults); if ($repeatCounter === 'all') { $repeat = $activeEl->getGroupModel()->repeatCount(); $res = array(); for ($j = 0; $j < $repeat; $j++) { $res[] = $activeEl->render($defaultData, $j); } $res = count($res) > 1 ? '<ul><li>' . implode('</li><li>', $res) . '</li></ul>' : $res[0]; } else { $res = $activeEl->render($defaultData, $repeatCounter); $ref = $activeEl->elementJavascript($repeatCounter); } $input->set('rowid', $origRowId); $input->set('view', $origView); $input->set('origRowId', ''); $this->resetRequest(); } return $res; } if (!isset($viewName)) { return; } $origId = $input->get('id', '', 'string'); $origView = $input->get('view'); // Allow for random=1 (which has to map to fabrik_random for list views) $origRandom = $input->get('fabrik_random'); // For fabble $input->set('origid', $origId); $input->set('origview', $origView); $input->set('id', $id); $input->set('view', $viewName); /* * $$$ hugh - at least make the $origId available for certain corner cases, like ... * http://fabrikar.com/forums/showthread.php?p=42960#post42960 */ $input->set('origid', $origId, 'GET', false); $cacheKey = $id; if ($rowId !== '') { $cacheKey .= '.' . $rowId; } $controller = $this->getController($viewName, $cacheKey); $view = $this->getView($controller, $viewName, $cacheKey); if ($model = $this->getModel($controller, $viewName, $cacheKey)) { $view->setModel($model, true); } // Display the view //$view->error = $controller->getError(); $view->isMambot = true; $displayed = false; // Do some view specific code switch ($viewName) { case 'form_css': $model->getFormCss(); break; case 'form': case 'details': if ($id === 0) { $app->enqueueMessage('No id set in fabrik plugin declaration', 'warning'); return; } $model->ajax = $ajax; $model->setId($id); unset($model->groups); // Set default values set in plugin declaration // - note cant check if the form model has the key' as its not yet loaded $this->_setRequest($unused); // $$$ rob - flayout is used in form/details view when _isMamot = true $input->set('flayout', $input->get('layout')); $input->set('rowid', $rowId); break; case 'csv': case 'table': case 'list': /* $$$ rob 15/02/2011 added this as otherwise when you filtered on a table * with multiple filter set up subsequent tables were showing * the first tables data */ if ($input->get('activelistid') == '') { $input->set('activelistid', $input->getId('listid')); } $input->set('listid', $id); // Allow for simple limit=2 in plugin declaration if ($limit) { $limitKey = 'limit' . $id; $this->origRequestVars[$limitKey] = $input->get($limitKey); $input->set($limitKey, $limit); } $this->_setRequest($unused); $input->set('fabrik_random', $input->get('random', $origRandom)); $input->set('showfilters', $showFilters); $input->set('clearfilters', $clearFilters); $input->set('resetfilters', $resetFilters); if ($id === 0) { $app->enqueueMessage('No id set in fabrik plugin declaration', 'warning'); return; } $model->setId($id); $model->isMambot = true; /** * * Reset this otherwise embedding a list in a list menu page, the embedded list takes the show in list fields from the menu list * * $$$ hugh - nasty little hack to reduce 'emptyish' array, 'cos if no 'elements' in the request, the following ends up setting * returning an array with a single empty string. This ends up meaning that we render a list with no * elements in it. We've run across this before, so we have a FArrayHelper:;emptyish() to detect it. */ $show_in_list = explode('|', $input->getString('elements', '')); if (FArrayHelper::emptyIsh($show_in_list, true)) { $show_in_list = array(); } $input->set('fabrik_show_in_list', $show_in_list); $model->ajax = $ajax; $task = $input->get('task',''); if (method_exists($controller, $task) && $input->getInt('activetableid') == $id) { /* * Enable delete() of rows * list controller deals with display after tasks is called * set $displayed to true to stop controller running twice */ $displayed = true; ob_start(); $controller->$task(); $result = ob_get_contents(); ob_end_clean(); } $model->setOrderByAndDir(); $formModel = $model->getFormModel(); break; case 'visualization': $input->set('showfilters', $showFilters); $input->set('clearfilters', $clearFilters); $input->set('resetfilters', $resetFilters); $this->_setRequest($unused); break; } // Hack for gallery viz as it may not use the default view $controller->isMambot = true; if (!$displayed) { ob_start(); if (method_exists($model, 'reset')) { $model->reset(); } $controller->display($model); $result = ob_get_contents(); ob_end_clean(); } $input->set('id', $origId); $input->set('view', $origView); if ($origLayout != '') { $input->set('layout', $origLayout); } if ($origFLayout != '') { $input->set('flayout', $origFLayout); } if ($origRandom) { $input->set('fabrik_random', $origRandom); } $this->resetRequest(); return $result; } /** * Set the input state * * @param array $unused values to inject into the application input * * @return void */ protected function _setRequest($unused) { $app = Factory::getApplication(); $input = $app->input; // Ensure > conditions set in {fabrik} are converted to > foreach ($unused as &$v) { if (is_string($v)) { $v = htmlspecialchars_decode($v); } } /* * $$$ hugh - in order to allow complex filters to work in lists, like ... * foo___bar[value][]=1 foo___bar[value[]=9 foo___bar[condition]=BETWEEN *we have to build a qs style array structure, using parse_str(). */ $qs_arr = array(); $qs_str = implode('&', $unused); parse_str($qs_str, $qs_arr); $this->origRequestVars = array(); foreach ($qs_arr as $k => $v) { $origVar = $input->get($k, '', 'string'); $this->origRequestVars[$k] = $origVar; $_REQUEST[$k] = $_GET[$k] = $v; $input->set($k, $v); } /* * $$$ rob set this array here - we will use in the listfilter::getQuerystringFilters() * code to determine if the filter is a querystring filter or one set from the plugin * if its set from here it becomes sticky and is not cleared from the session. So we basically * treat all filters set up inside {fabrik.....} as prefilters */ $input->set('fabrik_sticky_filters', array_keys($qs_arr)); } /** * Reset the application input * * @return void */ protected function resetRequest() { $app = Factory::getApplication(); $input = $app->input; foreach ($this->origRequestVars as $k => $v) { if (!is_null($v)) { $input->set($k, $v); } else { // $$$ rob 13/04/2012 clear rather than setting to '' as subsequent list plugins with fewer filters // will contain the previous plugins filter, even if not included in the current plugin declaration unset($_GET[$k]); unset($_REQUEST[$k]); } } } /** * Get the model * * @param BaseController &$controller Controller * @param string $viewName View name * @param int $id Item id * * @return mixed JModel or false */ protected function getModel(&$controller, $viewName, $id) { if ($viewName == 'visualization') { $viewName = $this->getPluginVizName($id); } if ($viewName == 'details') { $viewName = 'form'; } if ($viewName == 'csv') { $viewName = 'list'; } $prefix = ''; if ($viewName == 'form' || $viewName == 'list') { $prefix = 'FabrikFEModel'; } if (!isset($controller->_model)) { BaseDatabaseModel::addIncludePath(COM_FABRIK_FRONTEND . '/models', $prefix); if (!$controller->_model = $controller->getModel($viewName, $prefix)) { throw new RuntimeException('Fabrik Content Plug-in: could not create model'); return false; } } return $controller->_model; } /** * Get a view * * @param object &$controller controller * @param string $viewName view name * @param int $id item id * * @return JView */ protected function getView(&$controller, $viewName, $id) { $viewType = Factory::getDocument()->getType(); if ($viewName == 'details') { $viewName = 'form'; } $view = $controller->getView($viewName, $viewType); return $view; } /** * Get the viz plugin name * * @param int $id viz id * * @return string viz plugin name */ protected function getPluginVizName($id) { if (!isset($this->pluginVizName)) { $this->pluginVizName = array(); } if (!array_key_exists($id, $this->pluginVizName)) { $db = FabrikWorker::getDbo(true); $query = $db->getQuery(true); $query->select('plugin')->from('#__fabrik_visualizations')->where('id = ' . (int) $id); $db->setQuery($query); $this->pluginVizName[$id] = $db->loadResult(); } return $this->pluginVizName[$id]; } /** * Get the controller * * @param string $viewName view name * @param int $id item id * * @return object controller */ protected function getController($viewName, $id) { if (!isset($this->controllers)) { $this->controllers = array(); } switch ($viewName) { case 'visualization': $controller = new FabrikControllerVisualization; break; case 'form': $controller = new FabrikControllerForm; break; case 'details': $controller = new FabrikControllerDetails; break; case 'list': // $$$ hugh - had to add [$id] for cases where we have multiple plugins with different tableids if (array_key_exists('list', $this->controllers)) { if (!array_key_exists($id, $this->controllers['list'])) { $this->controllers['list'][$id] = new FabrikControllerList; } } else { $this->controllers['list'][$id] = new FabrikControllerList; } $controller = $this->controllers['list'][$id]; break; case 'package': $controller = new FabrikControllerPackage; break; default: $controller = new FabrikController; break; } // Set a cacheId so that the controller grabs/creates unique caches for each form/table rendered $controller->cacheId = $id; return $controller; } /** * Load the required fabrik files * * @param string $view view name * * @return void */ protected function generalIncludes($view) { if ($view == 'details') { $view = 'form'; } if (!FabrikWorker::isViewType($view)) { throw new RuntimeException('Please specify a valid view type in your fabrik {} code: ' . $view, 500); } require_once COM_FABRIK_FRONTEND . '/controller.php'; // If in admin form or details view and embedding a list - this gave an error - if only needed for 3.0.x if ($view !== 'list') { require_once COM_FABRIK_FRONTEND . '/controllers/form.php'; require_once COM_FABRIK_FRONTEND . '/controllers/details.php'; } //require_once COM_FABRIK_FRONTEND . '/controllers/package.php'; require_once COM_FABRIK_FRONTEND . '/controllers/list.php'; require_once COM_FABRIK_FRONTEND . '/controllers/visualization.php'; Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fabrik/tables'); BaseDatabaseModel::addIncludePath(COM_FABRIK_FRONTEND . '/models'); BaseDatabaseModel::addIncludePath(COM_FABRIK_FRONTEND . '/models', 'FabrikFEModel'); // $$$rob looks like including the view does something to the layout variable require_once COM_FABRIK_FRONTEND . '/views/' . $view . '/view.html.php'; } }
| ver. 1.4 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка