Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
- **Некорректные URL в ЛК заказов клиента (#141):** кнопка «Сбросить» фильтра и ссылки пагинации вели на корень сайта (`/?`) из-за `<base href>` в шаблоне MODX — URL формируются server-side через `makeUrl()` + `http_build_query()`, пагинация сохраняет фильтр по статусу. Добавлены недостающие SVG-иконки в спрайт (`icon-arrow-left`, `icon-truck`, `icon-credit-card`, `icon-message`), исправлен `fill` → `stroke` для Feather-иконок в деталях заказа
- **Некорректные URL и хардкод английских сообщений в ЛК адресов (#142):** кнопки «Добавить адрес», «Редактировать», «Отмена» вели на корень сайта — URL формируются server-side через `makeUrl()` + `http_build_query()`. API-контроллер `CustomerAddressController` содержал хардкод английских строк вместо лексиконов — все сообщения заменены на `$this->modx->lexicon()`, добавлено 7 ключей в ru/en лексиконы
- **Отсутствие ключа `desc` в свойствах сниппетов и источников при сборке пакета (#127):** добавлена инициализация `desc` пустой строкой если ключ отсутствует в определении свойства — устраняет warning/ошибку в `resolver_04_sources` и `resolver_08_snippet_properties`
- **Ссылка на товар в таблице категории открывалась в новой вкладке:** у шаблона колонки `pagetitle` убран `target="_blank"` в дефолтном конфиге Vue, в сидере грида и миграцией для уже сохранённых записей `ms3_grid_fields`

#### ⚠️ Breaking changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function up()
'min_width' => '200px',
'config' => json_encode([
'type' => 'template',
'template' => '<span class="product-id">({id})</span> <a href="?a=resource/update&id={id}" target="_blank" class="product-link">{pagetitle}</a>'
'template' => '<span class="product-id">({id})</span> <a href="?a=resource/update&id={id}" class="product-link">{pagetitle}</a>'
], JSON_UNESCAPED_UNICODE),
'is_system' => 0,
'is_default' => 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

/**
* Open product title link in the same tab (MODX manager category products grid).
*/
final class CategoryProductsPagetitleLinkSameTab extends AbstractMigration
{
public function up(): void
{
$table = $this->gridFieldsTable();
$stmt = $this->getAdapter()->getConnection()->prepare(
"UPDATE `{$table}` SET config = ? WHERE id = ?"
);

foreach ($this->fetchPagetitleFieldRows() as $row) {
$config = json_decode($row['config'], true);
if (!is_array($config) || empty($config['template']) || !is_string($config['template'])) {
continue;
}
$template = $config['template'];
if (!$this->templateHasBlankTarget($template)) {
continue;
}
$config['template'] = $this->stripBlankTargetFromTemplate($template);
$stmt->execute([json_encode($config, JSON_UNESCAPED_UNICODE), (int) $row['id']]);
}
}

public function down(): void
{
$table = $this->gridFieldsTable();
$stmt = $this->getAdapter()->getConnection()->prepare(
"UPDATE `{$table}` SET config = ? WHERE id = ?"
);

foreach ($this->fetchPagetitleFieldRows() as $row) {
$config = json_decode($row['config'], true);
if (!is_array($config) || empty($config['template']) || !is_string($config['template'])) {
continue;
}
$template = $config['template'];
if ($this->templateHasBlankTarget($template)) {
continue;
}
$restored = $this->restoreBlankTargetBeforeProductLinkClass($template);
if ($restored === null) {
continue;
}
$config['template'] = $restored;
$stmt->execute([json_encode($config, JSON_UNESCAPED_UNICODE), (int) $row['id']]);
}
}

private function gridFieldsTable(): string
{
$prefix = $this->getAdapter()->getOption('table_prefix');

return $prefix . 'ms3_grid_fields';
}

/**
* @return list<array{id: int|string, config: string|null}>
*/
private function fetchPagetitleFieldRows(): array
{
$table = $this->gridFieldsTable();

return $this->fetchAll(
"SELECT id, config FROM `{$table}` WHERE grid_key = 'category-products' AND field_name = 'pagetitle'"
);
}

private function templateHasBlankTarget(string $template): bool
{
return str_contains($template, 'target="_blank"')
|| str_contains($template, "target='_blank'");
}

private function stripBlankTargetFromTemplate(string $template): string
{
return str_replace([' target="_blank"', " target='_blank'"], '', $template);
}

/**
* Re-inserts target="_blank" only for templates that use class product-link (stock layout).
*/
private function restoreBlankTargetBeforeProductLinkClass(string $template): ?string
{
if (str_contains($template, 'class="product-link"')) {
return str_replace(' class="product-link"', ' target="_blank" class="product-link"', $template);
}
if (str_contains($template, "class='product-link'")) {
return str_replace(" class='product-link'", " target='_blank' class='product-link'", $template);
}

return null;
}
}
2 changes: 1 addition & 1 deletion vueManager/src/components/CategoryProductsGrid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ function getDefaultColumns() {
minWidth: '12.5rem',
type: 'template',
template:
'<span class="product-id">({id})</span> <a href="?a=resource/update&id={id}" target="_blank" class="product-link">{pagetitle}</a>',
'<span class="product-id">({id})</span> <a href="?a=resource/update&id={id}" class="product-link">{pagetitle}</a>',
},
{
name: 'article',
Expand Down