Skip to content

Commit

Permalink
fix: "Привязка к местоположению" LocationType
Browse files Browse the repository at this point in the history
Исправлено:

- свойство "Привязка к местоположению" LocationType работало со
  множеством ошибок во множественном режиме: нельзя было
  добавить новые поля, не поддерживалось поле описания значения.
  • Loading branch information
webarchitect609 committed Jun 14, 2022
1 parent 86ac2f2 commit 8bc23b7
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 20 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Change Log
==========

2.0.2
-----

### Исправлено:

- свойство "Привязка к местоположению" `LocationType` работало со множеством ошибок во множественном режиме: нельзя было
добавить новые поля, не поддерживалось поле описания значения.

2.0.1
-----

Expand Down
9 changes: 9 additions & 0 deletions src/main/Abstraction/IblockPropertyTypeBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,13 @@ public function getUIFilterProperty(array $property, array $control, array &$fil
throw new NotImplementedMethodException('getUIFilterProperty', static::class);
}

/**
* @return array|bool|mixed
*/
protected function includeIblockElementAdminLangFile()
{
return IncludeModuleLangFile(
$_SERVER["DOCUMENT_ROOT"] . BX_ROOT . '/modules/iblock/admin/iblock_element_admin.php'
);
}
}
9 changes: 9 additions & 0 deletions src/main/Exception/ModuleNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace WebArch\BitrixIblockPropertyType\Exception;

use RuntimeException;

class ModuleNotFoundException extends RuntimeException implements BitrixIblockPropertyTypeExceptionInterface
{
}
188 changes: 168 additions & 20 deletions src/main/LocationType.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<?php

/** @noinspection PhpMissingReturnTypeInspection */

namespace WebArch\BitrixIblockPropertyType;

use Bitrix\Main\Loader;
use Bitrix\Main\LoaderException;
use Bitrix\Sale\Location\Admin\LocationHelper;
use HtmlObject\Element;
use WebArch\BitrixIblockPropertyType\Abstraction\IblockPropertyTypeBase;
use WebArch\BitrixIblockPropertyType\Exception\ModuleNotFoundException;

/**
* Class LocationType
Expand All @@ -14,6 +18,8 @@
*/
class LocationType extends IblockPropertyTypeBase
{
private const MODULE_SALE = 'sale';

/**
* @inheritdoc
*/
Expand All @@ -36,25 +42,132 @@ public function getDescription()
public function getCallbacksMapping()
{
return [
'GetAdminListViewHTML' => [$this, 'getAdminListViewHTML'],
'GetPropertyFieldHtml' => [$this, 'getPropertyFieldHtml'],
'GetAdminListViewHTML' => [$this, 'getAdminListViewHTML'],
'GetPropertyFieldHtml' => [$this, 'getPropertyFieldHtml'],
'GetPropertyFieldHtmlMulty' => [$this, 'getPropertyFieldHtmlMulty'],
];
}

/**
* @inheritDoc
*/
public function getPropertyFieldHtml(array $property, array $value, array $control) {
try {
$this->includeIblockElementAdminLangFile();
$descInput = '';
if (key_exists('WITH_DESCRIPTION', $property) && 'Y' === $property['WITH_DESCRIPTION']) {
$descInput = $this->getDescriptionInput(
$control['DESCRIPTION'],
$value['DESCRIPTION']
);
}

return $this->getValueInputWithAutoComplete($value['VALUE'], $control['VALUE']) . $descInput;
} catch (LoaderException|ModuleNotFoundException $exception) {
return $this->getErrorSpan($exception->getMessage());
}
}

/**
* @inheritDoc
* @noinspection PhpUndefinedMethodInspection
*/
public function getPropertyFieldHtmlMulty(array $property, array $valueList, array $control)
{
try {
$this->includeIblockElementAdminLangFile();
$rowList = [];
// Существующие значения
foreach ($valueList as $valueId => $singleValue) {
$rowList[] = $this->getMultiRow(
$valueId,
$property,
$singleValue,
$control
);
}
// Новые значения
for ($n = 0; $n < ($property['MULTIPLE_CNT'] ?? 1); $n++) {
$rowList[] = $this->getMultiRow(
'n' . $n,
$property,
['VALUE' => '', 'DESCRIPTION' => ''],
$control
);
}

/**
* К этой таблице НЕЛЬЗЯ добавлять кнопку "Добавить"/"Ещё", т.к. крайне сложно
* скопировать поле поиска местоположения, не сломав его.
*/
return Element::table(
implode('', $rowList),
['width' => '100%']
);
} catch (LoaderException|ModuleNotFoundException $exception) {
return $this->getErrorSpan($exception->getMessage());
}
}

/**
* @inheritDoc
*/
public function getAdminListViewHTML(array $property, array $value, array $control)
{
try {
$this->assertSaleModuleIncluded();

return LocationHelper::getLocationStringByCode($property['VALUE']);
} catch (LoaderException|ModuleNotFoundException $exception) {
return $this->getErrorSpan($exception->getMessage());
}
}

/**
* @param string $valueId
* @param array $property
* @param array $singleValue
* @param array $control
*
* @throws LoaderException
* @throws ModuleNotFoundException
* @return Element
* @noinspection PhpUndefinedMethodInspection
*/
public function getPropertyFieldHtml(
array $property,
array $value,
array $control
) {
private function getMultiRow(string $valueId, array $property, array $singleValue, array $control): Element
{
$descriptionCell = '';
if (key_exists('WITH_DESCRIPTION', $property) && 'Y' === $property['WITH_DESCRIPTION']) {
$descriptionCell = $this->getDescriptionInput(
$control['VALUE'] . '[' . $valueId . '][DESCRIPTION]',
$singleValue['DESCRIPTION']
);
}

return Element::tr(
Element::td(
$this->getValueInputWithAutoComplete(
$singleValue['VALUE'],
$control['VALUE'] . '[' . $valueId . '][VALUE]'
)
. $descriptionCell
)
);
}

/**
* @param null|string $valueValue
* @param string $inputName
*
* @throws LoaderException
* @throws ModuleNotFoundException
* @return false|string
*/
private function getValueInputWithAutoComplete(?string $valueValue, string $inputName): string
{
global $APPLICATION;

if (!Loader::includeModule('sale')) {
return $value['VALUE'];
}
$this->assertSaleModuleIncluded();

ob_start();
$APPLICATION->IncludeComponent(
Expand All @@ -63,8 +176,8 @@ public function getPropertyFieldHtml(
[
'COMPONENT_TEMPLATE' => 'search',
'ID' => '',
'CODE' => htmlspecialcharsbx($value['VALUE']),
'INPUT_NAME' => htmlspecialcharsbx($control['VALUE']),
'CODE' => htmlspecialcharsbx($valueValue),
'INPUT_NAME' => htmlspecialcharsbx($inputName),
'PROVIDE_LINK_BY' => 'code',
'JSCONTROL_GLOBAL_ID' => '',
'JS_CALLBACK' => '',
Expand All @@ -82,19 +195,54 @@ public function getPropertyFieldHtml(
}

/**
* @param array $property
* @param array $value
* @param array $control
* @param string $name
* @param null|string $value
*
* @return Element
* @noinspection PhpUndefinedMethodInspection
*/
private function getDescriptionInput(string $name, ?string $value): Element
{
return Element::label(
GetMessage('IBLOCK_ELEMENT_EDIT_PROP_DESC_1')
. Element::input(
null,
[
'name' => $name,
'value' => (string)$value,
]
)
);
}

/**
* @throws LoaderException
* @return string
* @throws ModuleNotFoundException
* @return void
*/
public function getAdminListViewHTML(array $property, array $value, array $control)
private function assertSaleModuleIncluded(): void
{
if (!Loader::includeModule('sale')) {
return $value['VALUE'];
if (!Loader::includeModule(self::MODULE_SALE)) {
throw new ModuleNotFoundException(
sprintf(
'Модуль %s не установлен.',
self::MODULE_SALE
)
);
}
}

return LocationHelper::getLocationStringByCode($value['VALUE']);
/**
* @param string $message
*
* @return Element
* @noinspection PhpUndefinedMethodInspection
*/
private function getErrorSpan(string $message): Element
{
return Element::span(
$message,
['style' => 'color: red; font-weight: bold;']
);
}
}

0 comments on commit 8bc23b7

Please sign in to comment.