Пометка о том, что нужно добавить в компонент Joomla для создания связанных таблиц.
Добавляем в свой компонент Joomla отношение многие к многим
19.09.2017
tables/rel_tags2item.php (Download)
<?php // Запрет прямого доступа. defined('_JEXEC') or die; /** * Класс таблицы. */ class SoShopTableRel_tags2item extends JTable { /** * Конструктор. * * @param JDatabase &$db Коннектор объекта базы данных. */ public function __construct(&$db) { parent::__construct('#__so_shop_rel_tags2item', 'id', $db); } }
models/item.php (Download)
<?php // Запрет прямого доступа. defined('_JEXEC') or die; /** * Модель SoShop Items. */ class SoShopModelItem extends JModelAdmin { /** * Метод для получения данных, которые должны быть загружены в форму. * * @return mixed Данные для формы. */ protected function loadFormData() { // Проверка сессии на наличие ранее введеных в форму данных. $data = JFactory::getApplication()->getUserState($this->option . '.edit.item.data', array()); if (empty($data)) { $data = $this->getItem(); if($data->id) { $oModel = JModelLegacy::getInstance('rel_tags2item', 'SoShopModel'); $data->tags_list = $oModel->getList($data->id, true); } } return $data; } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success, False on error. * * @since 12.2 */ public function save($data) { // Oddler \/ $bStore = FALSE; if($isNew) { if(!$table->ordering) { $table->ordering = $table->id; $bStore = TRUE; } } $oModel = JModelLegacy::getInstance('rel_tags2item', 'SoShopModel'); $oModel->saveList($table->id, $data['tags_list']); if($bStore) { $table->store(); } // Oddler /\ } }
models/rel_tags2item.php (Download)
<?php // Запрет прямого доступа. defined('_JEXEC') or die; /** * Модель SoShop Items. */ class SoShopModelRel_tags2item extends JModelAdmin { /** * Возвращает ссылку на объект таблицы, всегда его создавая. * * @param string $type Тип таблицы для подключения. * @param string $prefix Префикс класса таблицы. Необязателен. * @param array $config Конфигурационный массив. Необязателен. * * @return JTable Объект JTable. */ public function getTable($type = 'Rel_tags2item', $prefix = 'SoShopTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Метод для получения формы. * * @param array $data Данные для формы. * @param boolean $loadData True, если форма загружает свои данные (по умолчанию), false если нет. * * @return mixed Объект JForm в случае успеха, в противном случае false. */ public function getForm($data = array(), $loadData = true) { $form = $this->loadForm( $this->option . '.item', 'item', array('control' => 'jform', 'load_data' => $loadData) ); if (empty($form)) { return false; } return $form; } /** * Метод сохраняет все теги для элемента. * * @param int $id_item Идентификатор элемента для которого сохраняются тэги * @param array $aItems массив тэшов. * * @return void */ public function saveList($id_item, &$aItems) { if(count($aItems)) { $db = JFactory::getDBO(); // Удаляем старые связи $query = $db->getQuery(true); $query->delete() ->from('#__so_shop_rel_tags2item') ->where('id_item='.$id_item) ; $db->setQuery($query); $db->execute(); // Добавляем новые foreach($aItems as $key => $val) { $oTable = JTable::getInstance('rel_tags2item', 'SoShopTable'); $oTable->id_item = $id_item; $oTable->id_tag = $val; $oTable->store(); } } } /** * Метод возвращает все теги для элемента. * * @param int $id_item Идентификатор элемента. * * @return array массив объектов. */ public function getList($id_item, $bOnlyId = FALSE) { $db = JFactory::getDBO(); $sFields = $bOnlyId?'id':'*'; $sSql = 'SELECT '.$sFields.' FROM #__so_shop_tags WHERE id IN(SELECT id_tag FROM #__so_shop_rel_tags2item WHERE id_item='.$id_item.')'; $db->setQuery($sSql); if ($bOnlyId) { $aRet = array(); $aTMP = $db->loadObjectList(); if(count($aTMP)) { foreach($aTMP as $oRow) { $aRet[] = $oRow->id; } } return $aRet; } else { return $db->loadObjectList(); } } }
models/fields/sotags.php (Download)
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем тип поля list. jimport('joomla.form.helper'); JFormHelper::loadFieldClass('list'); /** * Класс поля формы */ class JFormFieldSoRims2 extends JFormFieldList { /** * Тип поля. * * @var string */ protected $type = 'SoRims2'; /** * Мозможено ли выбрать несколько вариантов * * @var mixed */ protected $multiple_select = FALSE; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to the the value. * * @return mixed The property value or null. * * @since 3.2 */ public function __get($name) { switch ($name) { case 'multiple_select': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to the the value. * @param mixed $value The value of the property. * * @return void * * @since 3.2 */ public function __set($name, $value) { switch ($name) { case 'multiple_select': $this->$multiple_select = (string) $value; break; default: parent::__set($name, $value); } } /** * Method to attach a JForm object to the field. * * @param SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see JFormField::setup() * @since 3.2 */ public function setup(SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); if ($return) { $this->multiple_select = (string) $this->element['multiple_select']; } return $return; } /** * Method to get the field input markup for a generic list. * Use the multiple attribute to enable multiselect. * * @return string The field input markup. * * @since 11.1 */ protected function getInput() { if($this->multiple_select) { // Без этого не считает поле массивом и передает только одно значение $this->name = $this->name.'[]'; $this->multiple = 1; } return parent::getInput(); } /** * Method to get the field options. * * @return array The field option objects. * * @since 1.6 */ public function getOptions() { $options = array(); $db = JFactory::getDBO(); $query = $db->getQuery(true) ->select('id As value, title As text') ->from('#__so_shop_tags AS a') ; // Get the options. $db->setQuery($query); $data=$db->loadObjectList(); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } // Merge any additional options in the XML definition. // $options = array_merge(parent::getOptions(), $options); array_unshift($options, JHtml::_('select.option', '0', JText::_('--не указан--'))); return array_merge(parent::getOptions(), $options); } }
models/forms/item.xml (Download)
<?xml version="1.0" encoding="utf-8"?> <form addrulepath="/administrator/components/com_soshop/models/rules" > <fieldset name="details"> <field name="id" type="hidden" /> </fieldset> <fieldset name="tags"> <field label="Тэги" name="tags_list" type="sotags" > </field> </fieldset> </form>