Пометка о том, что нужно добавить в компонент 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>