Файловый менеджер - Редактировать - /home/lmsyaran/public_html/joomla5/administrator/components/com_fabrik/models/element.php
Назад
<?php /** * Admin Element Model * * @package Joomla.Administrator * @subpackage Fabrik * @copyright Copyright (C) 2005-2020 Media A-Team, Inc. - All rights reserved. * @license GNU/GPL http://www.gnu.org/copyleft/gpl.html * @since 1.6 */ // No direct access defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\Table\Table; use Joomla\CMS\Language\Text; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Date\Date; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Utilities\ArrayHelper; use Joomla\String\StringHelper; use Joomla\CMS\Factory; jimport('joomla.application.component.modeladmin'); require_once 'fabmodeladmin.php'; /** * Admin Element Model * * @package Joomla.Administrator * @subpackage Fabrik * @since 3.0 */ class FabrikAdminModelElement extends FabModelAdmin { /** * The prefix to use with controller messages. * * @var string */ protected $text_prefix = 'COM_FABRIK_ELEMENT'; /** * Validation plugin models for this element * * @since 3.0.6 * * @var array */ protected $aValidations = null; /** * Core Joomla and Fabrik table names * * @var array */ /* protected $core = array('#__assets', '#__banner_clients', '#__banner_tracks', '#__banners', '#__categories', '#__contact_details', '#__content', '#__content_frontpage', '#__content_rating', '#__core_log_searches', '#__extensions', '#__fabrik_connections', '#__fabrik_cron', '#__fabrik_elements', '#__fabrik_form_sessions', '#__fabrik_formgroup', '#__fabrik_forms', '#__fabrik_groups', '#__fabrik_joins', '#__fabrik_jsactions', '#__fabrik_lists', '#__fabrik_log', '#__fabrik_packages', '#__fabrik_validations', '#__fabrik_visualizations', '#__fb_contact_sample', '#__languages', '#__menu', '#__menu_types', '#__messages', '#__messages_cfg', '#__modules', '#__modules_menu', '#__newsfeeds', '#__redirect_links', '#__schemas', '#__session', '#__template_styles', '#__update_categories', '#__update_sites', '#__update_sites_extensions', '#__updates', '#__user_profiles', '#__user_usergroup_map', '#__usergroups', '#__users', '#__viewlevels', '#__weblinks'); */ protected $core = array('#__assets', '#__banner_clients', '#__banner_tracks', '#__banners', '#__categories', '#__contact_details', '#__content', '#__content_frontpage', '#__content_rating', '#__core_log_searches', '#__extensions', '#__fabrik_connections', '#__fabrik_cron', '#__fabrik_elements', '#__fabrik_form_sessions', '#__fabrik_formgroup', '#__fabrik_forms', '#__fabrik_groups', '#__fabrik_joins', '#__fabrik_jsactions', '#__fabrik_lists', '#__fabrik_log', '#__fabrik_validations', '#__fabrik_visualizations', '#__fb_contact_sample', '#__languages', '#__menu', '#__menu_types', '#__messages', '#__messages_cfg', '#__modules', '#__modules_menu', '#__newsfeeds', '#__redirect_links', '#__schemas', '#__session', '#__template_styles', '#__update_categories', '#__update_sites', '#__update_sites_extensions', '#__updates', '#__user_profiles', '#__user_usergroup_map', '#__usergroups', '#__users', '#__viewlevels', '#__weblinks'); /** * Constructor. * Ensure that we use the fabrik db model for the dbo * * @param array $config An optional associative array of configuration settings. */ public function __construct($config = array()) { $config['dbo'] = FabrikWorker::getDbo(true); parent::__construct($config); } /** * Returns a reference to the a Table object, always creating it. * * @param string $type The table type to instantiate * @param string $prefix A prefix for the table class name. Optional. * @param array $config Configuration array for model. Optional. * * @return Table A database object */ public function getTable($type = 'Element', $prefix = 'FabrikTable', $config = array()) { $config['dbo'] = FabrikWorker::getDbo(true); return FabTable::getInstance($type, $prefix, $config); } /** * Method to get the record form. * * @param array $data Data for the form. * @param bool $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A Form object on success, false on failure */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_fabrik.element', 'element', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } $form->model = $this; return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. */ protected function loadFormData() { // Check the session for previously entered form data. $data = $this->app->getUserState('com_fabrik.edit.element.data', array()); if (empty($data)) { $data = $this->getItem(); } return $data; } /** * Get elements * * @deprecated since 3.1b2 * * @return array */ public function getElements() { return array(); } /** * Toggle adding / removing the elment from the list view * * @param array &$pks primary keys * @param var $value add (1) or remove (0) from list view * * @return bool */ public function addToListView(&$pks, $value = 1) { // Initialise variables. // $dispatcher = JEventDispatcher::getInstance(); // $dispatcher = Factory::getApplication()->getDispatcher(); $item = $this->getTable(); $pks = (array) $pks; // Include the content plugins for the change of state event. PluginHelper::importPlugin('content'); // Access checks. foreach ($pks as $i => $pk) { if ($item->load($pk)) { if (!$this->canEditState($item)) { // Prune items that you can't change. unset($pks[$i]); // JError::raiseWarning(403, Text::_('JLIB_APPLICATION_ERROR_EDIT_STATE_NOT_PERMITTED')); \Joomla\CMS\Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDIT_STATE_NOT_PERMITTED'), 'warning'); } } } // Attempt to change the state of the records. if (!$item->addToListView($pks, $value, $this->user->get('id'))) { $this->setError($item->getError()); return false; } $context = $this->option . '.' . $this->name; // Trigger the onContentChangeState event. // $result = $dispatcher->triggerEvent($this->event_change_state, array($context, $pks, $value)); $result = Factory::getApplication()->triggerEvent($this->event_change_state, array($context, $pks, $value)); if (in_array(false, $result, true)) { $this->setError($item->getError()); return false; } return true; } /** * Get the js events that are used by the element * * @return array */ public function getJsEvents() { $db = FabrikWorker::getDbo(true); $query = $db->getQuery(true); $id = (int) $this->getItem()->id; $query->select('*')->from('#__fabrik_jsactions')->where('element_id = ' . $id)->order('id'); $db->setQuery($query); $items = $db->loadObjectList(); for ($i = 0; $i < count($items); $i++) { $items[$i]->params = json_decode($items[$i]->params); $items[$i]->params->js_e_value = htmlspecialchars_decode($items[$i]->params->js_e_value); } return $items; } /** * Load the actual validation plugins that the element uses * * @return array plugins */ public function getPlugins() { $item = $this->getItem(); $plugins = (array) FArrayHelper::getNestedValue($item->params, 'validations.plugin', array()); $published = (array) FArrayHelper::getNestedValue($item->params, 'validations.plugin_published', array()); $icons = (array) FArrayHelper::getNestedValue($item->params, 'validations.show_icon', array()); $must_validate = (array) FArrayHelper::getNestedValue($item->params, 'validations.must_validate', array()); $in = (array) FArrayHelper::getNestedValue($item->params, 'validations.validate_in', array()); $on = (array) FArrayHelper::getNestedValue($item->params, 'validations.validation_on', array()); $hidden = (array) FArrayHelper::getNestedValue($item->params, 'validations.validate_hidden', array()); $return = array(); for ($i = 0; $i < count($plugins); $i++) { $o = new stdClass; $o->plugin = $plugins[$i]; $o->published = FArrayHelper::getValue($published, $i, 1); $o->show_icon = FArrayHelper::getValue($icons, $i, 1); $o->must_validate = FArrayHelper::getValue($must_validate, $i, 1); $o->validate_in = FArrayHelper::getValue($in, $i, 'both'); $o->validation_on = FArrayHelper::getValue($on, $i, 'both'); $o->validate_hidden = FArrayHelper::getValue($hidden, $i, 1); $return[] = $o; } return $return; } /** * Get the js code to build the plugins etc * * @return string js code */ public function getJs() { $item = $this->getItem(); $opts = new stdClass; $opts->plugin = $item->plugin; $opts->parentid = (int) $item->parent_id; $opts->jsevents = $this->getJsEvents(); $opts->id = (int) $item->id; // $opts->deleteButton = FabrikWorker::j3() ? '<a class="btn btn-danger"><i class="icon-delete"></i> ' : '<a class="removeButton">'; $opts->deleteButton = '<a class="btn btn-danger"><i class="icon-delete"></i> '; $opts->deleteButton .= Text::_('COM_FABRIK_DELETE') . '</a>'; $opts = json_encode($opts); Text::script('COM_FABRIK_PLEASE_SELECT'); Text::script('COM_FABRIK_JS_SELECT_EVENT'); Text::script('COM_FABRIK_JS_INLINE_JS_CODE'); Text::script('COM_FABRIK_JS_INLINE_COMMENT_WARNING'); Text::script('COM_FABRIK_JS_WHEN_ELEMENT'); Text::script('COM_FABRIK_JS_IS'); Text::script('COM_FABRIK_JS_NO_ACTION'); $js[] = "window.addEvent('domready', function () {"; $js[] = "\tvar opts = $opts;"; $plugins = json_encode($this->getPlugins()); $js[] = "\tFabrik.controller = new fabrikAdminElement($plugins, opts, " . (int) $this->getItem()->id . ");"; $js[] = "})"; return implode("\n", $js); } /** * Get html form fields for a plugin (filled with * current element's plugin data * * @param string $plugin plugin name * * @return string html form fields */ public function getPluginHTML($plugin = null) { $app = $this->app; $input = $app->input; $str = ''; $item = $this->getItem(); /* J4 hack to update the bootstrap class from existing elements */ $item = $this->updBsClass($item); if (empty($plugin)) { $plugin = $item->plugin; } $input->set('view', 'element'); PluginHelper::importPlugin('fabrik_element', $plugin); if ($plugin == '') { $str = '<div class="alert">' . Text::_('COM_FABRIK_SELECT_A_PLUGIN') . '</div>'; } else { try { $plugin = $this->pluginManager->getPlugIn($plugin, 'Element'); // $mode = FabrikWorker::j3() ? 'nav-tabs' : ''; $mode = 'nav-tabs'; $str = $plugin->onRenderAdminSettings(ArrayHelper::fromObject($item), null, $mode); } catch (RuntimeException $e) { $str = '<div class="alert">' . Text::_('COM_FABRIK_SELECT_A_PLUGIN') . '</div>'; } } return $str; } /** * Method to look for old style boostrap classes and transform to new BS5 classes. * * @param mixed $data The data for the form * @return mixed The data for the form. */ protected function updBsClass($item) { $classList = [ 'input-mini' => 'col-sm-2', 'input-small' => 'col-sm-4', 'input-medium' => 'col-sm-6', 'input-large' => 'col-sm-8', 'input-xlarge' => 'col-sm-10', 'input-xxlarge' => 'col-sm-12', 'input-block-level' => 'col-sm-12', ]; if (property_exists($item, 'params') && array_key_exists('bootstrap_class', $item->params)) { // check for old col-md and span classes $bsClass = str_replace(['col-md-', 'span'], 'col-sm-', $item->params['bootstrap_class']); if (array_key_exists($bsClass, $classList)) { $bsClass = $classList[$bsClass]; } // If after all that the class is empty, set a sensible default if (empty($bsClass)) $bsClass = 'col-sm-6'; // We will just go ahead and update it, if it didn't change there is no harm $item->params['bootstrap_class'] = $bsClass; } return $item; } /** * Prepare and sanitise the table data prior to saving. * * @param Table $table A reference to a Table object. * * @return void * * @since 12.2 */ protected function prepareTable($table) { } /** * Method to validate the form data. * * @param Form $form The form to validate against. * @param array $data The data to validate. * @param string $group The name of the field group to validate. * * @see FormRule * @see InputFilter * * @return mixed Array of filtered data if valid, false otherwise. */ public function validate($form, $data, $group = null) { $ok = parent::validate($form, $data); $input = $this->app->input; // Standard jForm validation failed so we shouldn't test further as we can't be sure of the data if (!$ok) { return false; } $db = FabrikWorker::getDbo(true); $elementModel = $this->getElementPluginModel($data); $nameChanged = $data['name'] !== $elementModel->getElement()->name; $elementModel->getElement()->bind($data); $listModel = $elementModel->getListModel(); $isView = (bool)$listModel->isView(); if ($data['id'] == '') { // Have to forcefully set group id otherwise listmodel id is blank $elementModel->getElement()->group_id = $data['group_id']; if ($listModel->canAddFields() === false && $listModel->noTable() === false) { if ($isView) { $this->app->enqueueMessage(Text::_('COM_FABRIK_LIST_VIEW_SCHEMA_NOT_ALTERED')); } else { $this->setError(Text::_('COM_FABRIK_ERR_CANT_ADD_FIELDS')); } } if (!FabrikWorker::validElementName($data['name'])) { $this->setError(Text::_('COM_FABRIK_RESERVED_NAME_USED')); } } else { if ($listModel->canAlterFields() === false && $nameChanged && $listModel->noTable() === false) { if ($isView) { $this->app->enqueueMessage(Text::_('COM_FABRIK_LIST_VIEW_SCHEMA_NOT_ALTERED')); } else { $this->setError(Text::_('COM_FABRIK_ERR_CANT_ALTER_EXISTING_FIELDS')); } } if ($nameChanged && !FabrikWorker::validElementName($data['name'], false)) { $this->setError(Text::_('COM_FABRIK_RESERVED_NAME_USED')); } } $listModel = $elementModel->getListModel(); $groupModel = $elementModel->getGroupModel(); /** * Test for duplicate names * un-linking produces this error */ if (!$input->get('unlink', false) && (int) $data['id'] === 0) { /** * @FIXME - if a repeat group is created through the Group settings, we don't add the auto-created * table to the #_fabrik_lists table, so the following query obviously doesn't find it ... so we * barf when creating element in the repeat group with a "duplicate name", even though it's going * to be on a separate table. */ $query = $db->getQuery(true); $query->select('t.id')->from('#__fabrik_joins AS j'); $query->join('INNER', '#__fabrik_lists AS t ON j.table_join = t.db_table_name'); $query->where('group_id = ' . (int) $data['group_id'] . ' AND element_id = 0'); $db->setQuery($query); $sql = (string)$query; $joinTblId = (int) $db->loadResult(); $ignore = array($data['id']); if ($joinTblId === 0) { if ($listModel->fieldExists($data['name'], $ignore, $groupModel)) { $this->setError(Text::_('COM_FABRIK_ELEMENT_NAME_IN_USE')); } } else { /** @var FabrikFEModelList $joinListModel */ $joinListModel = Factory::getApplication()->bootComponent('com_fabrik')->getMVCFactory()->createModel('List', 'FabrikFEModel'); $joinListModel->setId($joinTblId); $joinEls = $joinListModel->getElements(); foreach ($joinEls as $joinEl) { if ($joinEl->getElement()->name == $data['name']) { $ignore[] = $joinEl->getElement()->id; } } if ($joinListModel->fieldExists($data['name'], $ignore, $groupModel)) { $this->setError(Text::_('COM_FABRIK_ELEMENT_NAME_IN_USE')); } } } // Strip <p> tag from label $data['label'] = StringHelper::str_ireplace(array('<p>', '</p>'), '', $data['label']); return count($this->getErrors()) == 0 ? $data : false; } /** * Load the element plugin / model for the posted data * * @param array $data posted data * * @return object element model */ private function getElementPluginModel($data) { $id = $data['id']; $elementModel = $this->pluginManager->getPlugIn($data['plugin'], 'element'); /** * $$$ rob f3 - need to bind the data in here otherwise validate fails on dup name test (as no group_id set) * $$$ rob 29/06/2011 removed as you can't then test name changes in validate() so now bind should be done after * getElementPluginModel is called. * $elementModel->getElement()->bind($data); */ $elementModel->setId($id); return $elementModel; } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success, False on error. */ public function save($data) { $config = ComponentHelper::getParams('com_fabrik'); if ($config->get('fbConf_wysiwyg_label', 0) == 0) { // Ensure the data is in the same format as when saved by the wysiwyg element e.g. < becomes < $data['label'] = htmlspecialchars($data['label']); } jimport('joomla.utilities.date'); $input = $this->app->input; $new = $data['id'] == 0 ? true : false; $params = $data['params']; $data['name'] = FabrikString::iclean($data['name']); $name = $data['name']; $params['validations'] = FArrayHelper::getValue($data, 'validationrule', array()); $elementModel = $this->getElementPluginModel($data); $elementModel->getElement()->bind($data); $origId = $input->getInt('id'); $row = $elementModel->getElement(); if ($new) { // Can't have elements starting with _ $name = ltrim($name, '_'); $data['name'] = $name; // Have to forcefully set group id otherwise list model id is blank $elementModel->getElement()->group_id = $data['group_id']; } $listModel = $elementModel->getListModel(); $item = $listModel->getTable(); // Are we updating the name of the primary key element? if ($row->name === FabrikString::shortColName($item->db_primary_key)) { if ($name !== $row->name) { // Yes we are so update the table $item->db_primary_key = str_replace($row->name, $name, $item->db_primary_key); $item->store(); } } $jsons = array('sub_values', 'sub_labels', 'sub_initial_selection'); foreach ($jsons as $json) { if (array_key_exists($json, $data)) { $data[$json] = json_encode($data[$json]); } } // Only update the element name if we can alter existing columns, otherwise the name and field name become out of sync $data['name'] = ($listModel->canAlterFields() || $new || $listModel->noTable()) ? $name : $input->get('name_orig', ''); $ar = array('published', 'use_in_page_title', 'show_in_list_summary', 'link_to_detail', 'can_order', 'filter_exact_match'); foreach ($ar as $a) { if (!array_key_exists($a, $data)) { $data[$a] = 0; } } /** * $$$ rob - test for change in element type * (eg if changing from db join to field we need to remove the join * entry from the #__fabrik_joins table */ $elementModel->beforeSave($row); // Unlink linked elements if ($input->get('unlink') == 'on') { $data['parent_id'] = 0; } $dateNow = new Date; if ($row->id != 0) { $data['modified'] = $dateNow->toSql(); $data['modified_by'] = $this->user->get('id'); if (FabrikWorker::isNullDate($data['created'])) { $data['created'] = null; } } else { $data['created'] = $dateNow->toSql(); $data['created_by'] = $this->user->get('id'); $data['created_by_alias'] = $this->user->get('username'); } /** * $$$ hugh * This insane chunk of code is needed because the validation rule params are not in sequential, * completely indexed arrays. What we have is single item arrays, with specific numeric * keys, like foo-something[0], bar-otherthing[2], etc. And if you json_encode an array with incomplete * or out of sequence numeric indexes, it encodes it as an object instead of an array. Which means the first * validation plugin will encode as an array, as it's params are single [0] index, and the rest as objects. * This foobars things, as we then don't know if validation params are arrays or objects! * * One option would be to modify every validation, and test every param we use, and if necessary convert it, * but that would be a major pain in the ass. * * So ... we need to fill in the blanks in the arrays, and ksort them. But, we need to know the param names * for each validation. But as they are just stuck in with the rest of the element params, there is no easy * way of knowing which are validation params and which are element params. * * So ... we need to load the validation objects, then load the XML file for each one, and iterate through * the fieldsets! Well, that's the only way I could come up with doing it. Hopefully Rob can come up with * a quicker and simpler way of doing this! */ $validations = FArrayHelper::getValue($params['validations'], 'plugin', array()); $num_validations = count($validations); $validation_plugins = $this->getValidations($elementModel, $validations); $i=0; foreach ($validation_plugins as $plugin) { $pluginName = $validations[$i]; $i++; $plugin_form = $plugin->getJForm(); /*Trob: plugin->get is not longer working, didn't find an other method, so fetching the pluginName from $validations JForm::addFormPath(JPATH_SITE . '/plugins/fabrik_validationrule/' . $plugin->get('pluginName')); $xmlFile = JPATH_SITE . '/plugins/fabrik_validationrule/' . $plugin->get('pluginName') . '/forms/fields.xml'; */ Form::addFormPath(JPATH_SITE . '/plugins/fabrik_validationrule/' . $pluginName); $xmlFile = JPATH_SITE . '/plugins/fabrik_validationrule/' . $pluginName . '/forms/fields.xml'; $xml = $plugin->jform->loadFile($xmlFile, false); foreach ($plugin_form->getFieldsets() as $fieldset) { foreach ($plugin_form->getFieldset($fieldset->name) as $field) { if (isset($params[$field->fieldname])) { if (is_array($params[$field->fieldname])) { for ($x = 0; $x < $num_validations; $x++) { if (!(array_key_exists($x, $params[$field->fieldname]))) { $params[$field->fieldname][$x] = ''; } } ksort($params[$field->fieldname]); } } } } } $data['params'] = json_encode($params); $row->params = $data['params']; $cond = 'group_id = ' . (int) $row->group_id; if ($new) { $data['ordering'] = $row->getNextOrder($cond); } $row->reorder($cond); /** * $$$ hugh - shouldn't updateChildIds() happen AFTER we save the main row? * Same place we do updateJavascript()? */ //$this->updateChildIds($row); $elementModel->getElement()->bind($data); $origName = $input->get('name_orig', ''); list($update, $q, $oldName, $newdesc, $origDesc) = $listModel->shouldUpdateElement($elementModel, $origName); if ($update && $input->get('task') !== 'save2copy') { $origPlugin = $input->get('plugin_orig'); $prefix = $this->config->get('dbprefix'); $tableName = $listModel->getTable()->db_table_name; $hasPrefix = (strstr($tableName, $prefix) === false) ? false : true; $tableName = str_replace($prefix, '#__', $tableName); if (in_array($tableName, $this->core)) { $this->app->enqueueMessage(Text::_('COM_FABRIK_WARNING_UPDATE_CORE_TABLE'), 'notice'); } else { if ($hasPrefix) { $this->app->enqueueMessage(Text::_('COM_FABRIK_WARNING_UPDATE_TABLE_WITH_PREFIX'), 'notice'); } } $this->app->setUserState('com_fabrik.confirmUpdate', 1); $this->app->setUserState('com_fabrik.plugin_orig', $origPlugin); $this->app->setUserState('com_fabrik.q', $q); $this->app->setUserState('com_fabrik.newdesc', $newdesc); $this->app->setUserState('com_fabrik.origDesc', $origDesc); $this->app->setUserState('com_fabrik.origplugin', $origPlugin); $this->app->setUserState('com_fabrik.oldname', $oldName); $this->app->setUserState('com_fabrik.newname', $data['name']); $this->app->setUserState('com_fabrik.origtask', $input->get('task')); $this->app->setUserState('com_fabrik.plugin', $data['plugin']); $task = $input->get('task'); $url = 'index.php?option=com_fabrik&view=element&layout=confirmupdate&id=' . (int) $origId . '&origplugin=' . $origPlugin . '&origtask=' . $task . '&plugin=' . $row->plugin; $this->app->setUserState('com_fabrik.redirect', $url); } else { $this->app->setUserState('com_fabrik.confirmUpdate', 0); } if ((int) $listModel->getTable()->id !== 0) { $this->updateIndexes($elementModel, $listModel, $row); } $return = parent::save($data); if ($return) { $this->updateJavascript($data); $elementModel->setId($this->getState($this->getName() . '.id')); $row->id = $elementModel->getId(); $data['id'] = $row->id; $this->createRepeatElement($elementModel, $row); // If new, check if the element's db table is used by other tables and if so add the element to each of those tables' groups if ($new) { $this->addElementToOtherDbTables($elementModel, $row); } if (!$elementModel->onSave($data)) { $this->setError(Text::_('COM_FABRIK_ERROR_SAVING_ELEMENT_PLUGIN_OPTIONS')); return false; } $this->updateChildIds($row); } parent::cleanCache('com_fabrik'); return $return; /** * used for prefab * return $elementModel; */ } /** * When saving an element, it may need to be added to other Fabrik lists * If those lists point to the same database table. * * @param object $elementModel element * @param object $row item * * @return void */ private function addElementToOtherDbTables($elementModel, $row) { $db = FabrikWorker::getDbo(true); $list = $elementModel->getListModel()->getTable(); $origElid = $row->id; $tmpgroupModel = $elementModel->getGroup(); $config = ComponentHelper::getParams('com_fabrik'); if ($tmpgroupModel->isJoin()) { $dbName = $tmpgroupModel->getJoinModel()->getJoin()->table_join; } else { $dbName = $list->db_table_name; } $query = $db->getQuery(true); $query->select('DISTINCT(l.id) AS id, db_table_name, l.label, l.form_id, l.label AS form_label, g.id AS group_id'); $query->from('#__fabrik_lists AS l'); $query->join('INNER', '#__fabrik_forms AS f ON l.form_id = f.id'); $query->join('LEFT', '#__fabrik_formgroup AS fg ON f.id = fg.form_id'); $query->join('LEFT', '#__fabrik_groups AS g ON fg.group_id = g.id'); $query->where('db_table_name = ' . $db->q($dbName) . ' AND l.id != ' . (int) $list->id . ' AND is_join = 0'); $db->setQuery($query); $otherTables = $db->loadObjectList('id'); /** * $$$ rob 20/02/2012 if you have 2 lists, counters, regions and then you join regions to countries to get a new group "countries - [regions]" * Then add elements to the regions list, the above query wont find the group "countries - [regions]" to add the elements into */ $query->clear(); $query->select('DISTINCT(l.id) AS id, l.db_table_name, l.label, l.form_id, l.label AS form_label, fg.group_id AS group_id') ->from('#__fabrik_joins AS j')->join('LEFT', '#__fabrik_formgroup AS fg ON fg.group_id = j.group_id') ->join('LEFT', '#__fabrik_forms AS f ON fg.form_id = f.id')->join('LEFT', '#__fabrik_lists AS l ON l.form_id = f.id') ->where('j.table_join = ' . $db->quote($dbName) . ' AND j.list_id <> 0 AND j.element_id = 0 AND list_id <> ' . (int) $list->id); $db->setQuery($query); $joinedLists = $db->loadObjectList('id'); $otherTables = array_merge($joinedLists, $otherTables); if (!empty($otherTables)) { /** * $$$ hugh - we use $row after this, so we need to work on a copy, otherwise * (for instance) we redirect to the wrong copy of the element */ $rowCopy = clone ($row); foreach ($otherTables as $listId => $t) { $rowCopy->id = 0; $rowCopy->parent_id = $origElid; $rowCopy->group_id = $t->group_id; $rowCopy->name = str_replace('`', '', $rowCopy->name); if ($config->get('unpublish_clones', false)) { $rowCopy->published = 0; } $rowCopy->store(); // Copy join records $join = $this->getTable('join'); if ($join->load(array('element_id' => $origElid))) { $join->id = 0; unset($join->id); $join->element_id = $rowCopy->id; $join->list_id = $listId; $join->store(); } } } } /** * Update child elements * * @param object &$row element * * @return mixed */ private function updateChildIds(&$row) { if ((int) $row->id === 0) { // New element so don't update child ids return; } $ids = $this->getElementDescendents($row->id); $ignore = array( '_tbl', '_tbl_key', '_db', 'id', 'group_id', 'created', 'created_by', 'parent_id', 'ordering', 'published', 'checked_out_time', 'show_in_list_summary' ); foreach ($ids as $id) { $plugin = $this->pluginManager->getElementPlugin($id); $leave = $plugin->getFixedChildParameters(); $item = $plugin->getElement(); foreach ($row as $key => $val) { if (!in_array($key, $ignore)) { if ($key == 'params') { $origParams = json_decode($item->params); $newParams = json_decode($val); foreach ($newParams as $pKey => $pVal) { if (!in_array($pKey, $leave)) { $origParams->$pKey = $pVal; } } $val = json_encode($origParams); } else { // $$$rob - i can't replicate bug #138 but this should fix things anyway??? if ($key == 'name') { $val = str_replace("`", '', $val); } } $item->$key = $val; } } $item->store(); } return true; } /** * Update table indexes based on element settings * * @param object &$elementModel element model * @param object &$listModel list model * @param object &$row element item * * @return void */ private function updateIndexes(&$elementModel, &$listModel, &$row) { if ($elementModel->getGroup()->isJoin()) { return; } // Update table indexes $fieldType = $elementModel->getFieldDescription(); // Int elements can't have a index size attribute $size = StringHelper::stristr($fieldType, 'int') || $fieldType == 'DATETIME' ? '' : '10'; if ($elementModel->getParams()->get('can_order')) { $listModel->addIndex($row->name, 'order', 'INDEX', $size); } else { $listModel->dropIndex($row->name, 'order', 'INDEX'); } if ($row->filter_type != '') { $listModel->addIndex($row->name, 'filter', 'INDEX', $size); } else { $listModel->dropIndex($row->name, 'filter', 'INDEX'); } } /** * Delete old javascript actions for the element * & add new javascript actions * * @param array $data to save * * @return void */ protected function updateJavascript($data) { /** * $$$ hugh - 2012/04/02 * updated to apply js changes to descendants as well. NOTE that this means * all descendants (i.e. children of children, etc.), not just direct children. */ $input = $this->app->input; $this_id = $this->getState($this->getName() . '.id'); $ids = $this->getElementDescendents($this_id); $ids[] = $this_id; $db = FabrikWorker::getDbo(true); $query = $db->getQuery(true); $query->delete('#__fabrik_jsactions')->where('element_id IN (' . implode(',', $ids) . ')'); $db->setQuery($query); $db->execute(); $jForm = $input->get('jform', array(), 'array'); $eEvent = FArrayHelper::getValue($jForm, 'js_e_event', array()); $eTrigger = FArrayHelper::getValue($jForm, 'js_e_trigger', array()); $eCond = FArrayHelper::getValue($jForm, 'js_e_condition', array()); $eVal = FArrayHelper::getValue($jForm, 'js_e_value', array()); $ePublished = FArrayHelper::getValue($jForm, 'js_published', array()); $action = (array) FArrayHelper::getValue($jForm, 'action', array()); foreach ($action as $c => $jsAction) { if ($jsAction === '') { continue; } $params = new stdClass; $params->js_e_event = $eEvent[$c]; $params->js_e_trigger = $eTrigger[$c]; $params->js_e_condition = $eCond[$c]; $foo = str_replace('\\', '\\\\', ($eVal[$c])); $params->js_e_value = htmlspecialchars($foo); $params->js_published = $ePublished[$c]; $params = json_encode($params); $code = $jForm['code'][$c]; $code = htmlspecialchars($code, ENT_QUOTES); foreach ($ids as $id) { $query = $db->getQuery(true); $query->insert('#__fabrik_jsactions'); $query->set('element_id = ' . (int) $id); $query->set('action = ' . $db->quote($jsAction)); $query->set('code = ' . $db->quote($code)); $query->set('params = \'' . $params . "'"); $db->setQuery($query); $db->execute(); } } } /** * Take an array of group ids and return the corresponding element * used in list publish code * * @param array $ids group ids * * @return array element ids */ public function swapGroupToElementIds($ids = array()) { if (empty($ids)) { return array(); } $ids = ArrayHelper::toInteger($ids); $db = FabrikWorker::getDbo(true); $query = $db->getQuery(true); $query->select('id')->from('#__fabrik_elements')->where('group_id IN (' . implode(',', $ids) . ')'); return $db->setQuery($query)->loadColumn(); } /** * Potentially drop fields then remove element record * Will also do the same for child elements * * @param array &$pks To delete * * @return boolean True if successful, false if an error occurs. */ public function delete(&$pks) { // Initialize variables $elementIds = $this->app->input->get('elementIds', array(), 'array'); foreach ($elementIds as $id) { if ((int) $id === 0) { continue; } $pluginModel = $this->pluginManager->getElementPlugin($id); $pluginModel->onRemove(); $children = $pluginModel->getElementDescendents($id); foreach ($children as $childId) { $childModel = $this->pluginManager->getElementPlugin($childId); $childModel->onRemove(); } // Enables the deletion of child elements $pks = array_merge($pks, $children); $element = $pluginModel->getElement(); if ($pluginModel->isRepeatElement()) { $listModel = $pluginModel->getListModel(); $db = $listModel->getDb(); $tableName = $db->qn($this->getRepeatElementTableName($pluginModel)); $db->setQuery('DROP TABLE ' . $tableName); $db->execute(); } $listModel = $pluginModel->getListModel(); $item = $listModel->getTable(); // $$$ hugh - might be a table-less form! if (!empty($item->id)) { $db = $listModel->getDb(); $db->setQuery('ALTER TABLE ' . $db->qn($item->db_table_name) . ' DROP ' . $db->qn($element->name)); $db->execute(); } } return parent::delete($pks); } /** * Copy an element * * @return mixed true or warning */ public function copy() { $input = $this->app->input; $cid = $input->get('cid', array(), 'array'); $cid = ArrayHelper::toInteger($cid); $names = $input->get('name', array(), 'array'); $rule = $this->getTable('element'); foreach ($cid as $id => $groupid) { $rule->load((int) $id); $name = FArrayHelper::getValue($names, $id, $rule->name); $data = ArrayHelper::fromObject($rule); $elementModel = $this->getElementPluginModel($data); $elementModel->getElement()->bind($data); $newRule = $elementModel->copyRow($id, $rule->label, $groupid, $name); if ($newRule === false) { return false; } $data = ArrayHelper::fromObject($newRule); $elementModel = $this->getElementPluginModel($data); $elementModel->getElement()->bind($data); $listModel = $elementModel->getListModel(); $res = $listModel->shouldUpdateElement($elementModel); $this->addElementToOtherDbTables($elementModel, $rule); } return true; } /** * If repeated element we need to make a joined db table to store repeated data in * * @param object $elementModel element model * @param object $row element item * * @return void */ public function createRepeatElement($elementModel, $row) { if (!$elementModel->isJoin()) { return; } $row->name = str_replace('`', '', $row->name); $listModel = $elementModel->getListModel(); $groupModel = $elementModel->getGroupModel(); $tableName = $this->getRepeatElementTableName($elementModel, $row); // Create db table! $formModel = $elementModel->getForm(); $db = $listModel->getDb(); $desc = $elementModel->getFieldDescription(); $name = $db->qn($row->name); $db ->setQuery( 'CREATE TABLE IF NOT EXISTS ' . $db->qn($tableName) . ' ( id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, parent_id INT(11), ' . $name . ' ' . $desc . ', ' . $db->qn('params') . ' TEXT );'); $db->execute(); // Remove previous join records if found /* if ((int) $row->id !== 0) { $jdb = FabrikWorker::getDbo(true); $query = $jdb->getQuery(true); $query->delete('#__fabrik_joins')->where('element_id = ' . (int) $row->id); $jdb->setQuery($query); $jdb->execute(); } */ // Create or update fabrik join if ($groupModel->isJoin()) { $joinFromTable = $groupModel->getJoinModel()->getJoin()->table_join; } else { $joinFromTable = $listModel->getTable()->db_table_name; } $data = array( 'list_id' => $listModel->getTable()->id, 'element_id' => $row->id, 'join_from_table' => $joinFromTable, 'table_join' => $tableName, 'table_key' => $row->name, 'table_join_key' => 'parent_id', 'join_type' => 'left' ); $join = $this->getTable('join'); $join->load(array('element_id' => $data['element_id'])); $opts = new stdClass; $opts->type = 'repeatElement'; $opts->pk = FabrikString::safeQuoteName($tableName . '.id'); $data['params'] = json_encode($opts); $join->bind($data); $join->store(); // update the join for any children $ids = $this->getElementDescendents($row->id); foreach ($ids as $id) { $childElementModel = $this->pluginManager->getElementPlugin($id); $data['list_id'] = $childElementModel->getListModel()->getTable()->id; $data['element_id'] = $id; $join->load(array('element_id' => $data['element_id'])); $join->bind($data); $join->store(); } $fieldName = $tableName . '___parent_id'; $listModel->addIndex($fieldName, 'parent_fk', 'INDEX', ''); $fields = $listModel->getDBFields($tableName, 'Field'); $field = FArrayHelper::getValue($fields, $row->name, false); switch ($field->BaseType) { case 'VARCHAR': $size = (int) $field->BaseLength < 10 ? $field->BaseLength : 10; break; case 'INT': case 'DATETIME': default: $size = ''; break; } $fieldName = $tableName . '___' . $row->name; $listModel->addIndex($fieldName, 'repeat_el', 'INDEX', $size); } /** * Get the name of the repeated elements table * * @param object $elementModel element model * @param object $row element item * * @return string table name */ protected function getRepeatElementTableName($elementModel, $row = null) { $listModel = $elementModel->getListModel(); $groupModel = $elementModel->getGroupModel(); if (is_null($row)) { $row = $elementModel->getElement(); } if ($groupModel->isJoin()) { $origTableName = $groupModel->getJoinModel()->getJoin()->table_join; } else { $origTableName = $listModel->getTable()->db_table_name; } return $origTableName . '_repeat_' . str_replace('`', '', $row->name); } /** * Gets the element's parent element * * @return mixed 0 if no parent, object if exists. */ public function getParent() { $item = $this->getItem(); $item->parent_id = (int) $item->parent_id; if ($item->parent_id === 0) { $parent = 0; } else { $db = FabrikWorker::getDbo(true); $query = $db->getQuery(true); $query->select('*')->from('#__fabrik_elements')->where('id = ' . (int) $item->parent_id); $db->setQuery($query); $parent = $db->loadObject(); if (is_null($parent)) { // Perhaps the parent element was deleted? $parent = 0; $item->parent_id = 0; } } return $parent; } /** * A protected method to get a set of ordering conditions. * * @param object $table A Table object. * * @return array An array of conditions to add to ordering queries. * * @since Fabrik 3.0b */ protected function getReorderConditions($table) { return array('group_id = ' . $table->group_id); } /** * Recursively get all linked children of an element * * @param int $id element id * * @return array */ protected function getElementDescendents($id = 0) { if (empty($id)) { $id = $this->getState($this->getName() . '.id'); } $db = FabrikWorker::getDbo(true); $query = $db->getQuery(true); $query->select('id')->from('#__fabrik_elements')->where('parent_id = ' . (int) $id); $db->setQuery($query); $kids = $db->loadObjectList(); $all_kids = array(); foreach ($kids as $kid) { $all_kids[] = $kid->id; $all_kids = array_merge($this->getElementDescendents($kid->id), $all_kids); } return $all_kids; } /** * Loads in elements validation objects * $$$ hugh - trying to fix issue on saving where we have to massage the plugin * params, which means knowing all the param names, but we can't call the FE model * version of this method 'cos ... well, it breaks. * * @param object $elementModel a front end element model * @param array $usedPlugins an array of validation plugin names to load * * @return array validation objects */ private function getValidations($elementModel, $usedPlugins = array()) { if (isset($this->_aValidations)) { return $this->_aValidations; } $pluginManager = FabrikWorker::getPluginManager(); $pluginManager->getPlugInGroup('validationrule'); $this->aValidations = array(); // $dispatcher = JEventDispatcher::getInstance(); $dispatcher = Factory::getApplication()->getDispatcher(); $ok = PluginHelper::importPlugin('fabrik_validationrule'); foreach ($usedPlugins as $usedPlugin) { if ($usedPlugin !== '') { $class = 'plgFabrik_Validationrule' . StringHelper::ucfirst($usedPlugin); $conf = array(); $conf['name'] = StringHelper::strtolower($usedPlugin); $conf['type'] = StringHelper::strtolower('fabrik_Validationrule'); $plugIn = new $class($dispatcher, $conf); // $plugIn = Factory::getApplication()->bootPlugin($conf['name'], $conf['type']); $oPlugin = PluginHelper::getPlugin('fabrik_validationrule', $usedPlugin); $plugIn->elementModel = $elementModel; $this->aValidations[] = $plugIn; } } return $this->aValidations; } }
| ver. 1.4 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0.09 |
proxy
|
phpinfo
|
Настройка