Переписать логику перевода товаров
Подготовить и сделать по примеру
может кому пригодится. переписал:
<?php
/**
* Page translation tool i18n4marketpro.market.php
*
* @package I18n
* @copyright (c) Cotonti Team
* @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
*/
use cot\plugins\trashcan\inc\TrashcanService;
defined('COT_CODE') or die('Wrong URL.');
require_once cot_incfile('market', 'module');
require_once cot_incfile('forms');
$id = cot_import('id', 'G', 'INT');
$l = cot_import('l', 'G', 'ALP');
if (!$id || $id < 1) {
cot_die_message(404);
}
/* === Hook === */
foreach (cot_getextplugins('i18n4marketpro.market.first') as $pl) {
include $pl;
}
/* =============*/
$stmt = Cot::$db->query('SELECT * FROM ' . Cot::$db->market . ' WHERE fieldmrkt_id = ?', $id);
if ($id > 0 && $stmt->rowCount() == 1) {
$item= $stmt->fetch();
$stmt->closeCursor();
// Для добавления перевод не загружаем
if ($a == 'add') {
$pag_i18n4marketpro = [];
} else {
$stmt = Cot::$db->query('SELECT * FROM ' . $db->i18n4marketpro_pages . " WHERE ipage_id = ? AND ipage_locale = ?",
[$id, $i18n4marketpro_locale]);
$pag_i18n4marketpro = $stmt->rowCount() == 1 ? $stmt->fetch() : [];
$stmt->closeCursor();
}
// ------------------------------------------------------------------
// ДОБАВЛЕНИЕ НОВОГО ПЕРЕВОДА
// ------------------------------------------------------------------
if ($a == 'add' && empty($pag_i18n4marketpro)) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$selected_locale = cot_import('locale', 'P', 'ALP');
if (!in_array($selected_locale, array_keys($i18n4marketpro_locales))) {
cot_error('i18n_incorrect_locale', 'locale');
}
if (empty(cot_error_found())) {
$checkStmt = Cot::$db->query(
'SELECT 1 FROM ' . $db->i18n4marketpro_pages . ' WHERE ipage_id = ? AND ipage_locale = ?',
[$id, $selected_locale]
);
if ($checkStmt->rowCount() > 0) {
cot_error('i18n_translation_exists', 'locale');
}
$checkStmt->closeCursor();
}
$pag_i18n4marketpro = [
'ipage_id' => $id,
'ipage_locale' => $selected_locale,
'ipage_translatorid' => Cot::$usr['id'],
'ipage_translatorname' => Cot::$usr['name'],
'ipage_date' => Cot::$sys['now'],
'ipage_title' => cot_import('title', 'P', 'TXT'),
'ipage_desc' => cot_import('desc', 'P', 'TXT'),
'ipage_text' => cot_import('translate_text', 'P', 'HTM')
];
if (mb_strlen($pag_i18n4marketpro['ipage_title']) < 2) {
cot_error('page_titletooshort', 'title');
}
if (!cot_error_found()) {
Cot::$db->insert($db->i18n4marketpro_pages, $pag_i18n4marketpro);
foreach (cot_getextplugins('i18n4marketpro.market.add.done') as $pl) {
include $pl;
}
cot_message('Added');
cot_log('Add translate for page #' . $id, 'i18n4marketpro', 'market', 'add');
$page_urlp = empty($item['fieldmrkt_alias']) ? "c={$item['fieldmrkt_cat']}&id=$id&l=" . $selected_locale
: 'c=' . $item['fieldmrkt_cat'] . '&al=' . $item['fieldmrkt_alias'] . '&l=' . $selected_locale;
cot_redirect(cot_url('market', $page_urlp, '', true, false, true));
}
}
Cot::$out['subtitle'] = Cot::$L['i18n4marketpro_adding'];
$t = new XTemplate(cot_tplfile('i18n4marketpro.market', 'plug'));
$lc_list = $i18n4marketpro_locales;
unset($lc_list[Cot::$cfg['defaultlang']]);
foreach (cot_i18n4marketpro_list_page_locales($id) as $lc) {
unset($lc_list[$lc]);
}
$lc_values = array_keys($lc_list);
$lc_names = array_values($lc_list);
$selected_in_selector = ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($pag_i18n4marketpro['ipage_locale'])) ? $pag_i18n4marketpro['ipage_locale'] : '';
$title_val = isset($pag_i18n4marketpro['ipage_title']) ? $pag_i18n4marketpro['ipage_title'] : '';
$desc_val = isset($pag_i18n4marketpro['ipage_desc']) ? $pag_i18n4marketpro['ipage_desc'] : '';
$text_val = isset($pag_i18n4marketpro['ipage_text']) ? $pag_i18n4marketpro['ipage_text'] : (isset($item['fieldmrkt_text']) ? $item['fieldmrkt_text'] : '');
$t->assign([
'I18N4MARKETPRO_ACTION' => cot_url('plug', "e=i18n4marketpro&m=market&a=add&id=$id"),
'I18N4MARKETPRO_TITLE' => Cot::$L['i18n4marketpro_adding'],
'I18N4MARKETPRO_ORIGINAL_LANG' => $i18n4marketpro_locales[Cot::$cfg['defaultlang']],
'I18N4MARKETPRO_LOCALIZED_LANG' => cot_selectbox($selected_in_selector, 'locale', $lc_values, $lc_names, false),
'I18N4MARKETPRO_PAGE_TITLE' => htmlspecialchars($item['fieldmrkt_title']),
'I18N4MARKETPRO_PAGE_DESC' => htmlspecialchars($item['fieldmrkt_desc']),
'I18N4MARKETPRO_PAGE_TEXT' => cot_parse($item['fieldmrkt_text'], Cot::$cfg['market']['marketmarkup']),
'I18N4MARKETPRO_IPAGE_TITLE' => htmlspecialchars($title_val),
'I18N4MARKETPRO_IPAGE_DESC' => htmlspecialchars($desc_val),
'I18N4MARKETPRO_IPAGE_TEXT' => cot_textarea('translate_text', $text_val, 32, 80, '', 'input_textarea_editor')
]);
cot_display_messages($t);
foreach (cot_getextplugins('i18n4marketpro.market.translate.tags') as $pl) {
include $pl;
}
}
// ------------------------------------------------------------------
// РЕДАКТИРОВАНИЕ (ДОБАВЛЕН СЕЛЕКТОР ЛОКАЛИ)
// ------------------------------------------------------------------
elseif (
$a == 'edit' && !empty($pag_i18n4marketpro)
&& ($i18n4marketpro_admin || $i18n_edit || Cot::$usr['id'] == $pag_i18n4marketpro['ipage_translatorid'])
) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Получаем новую локаль из POST
$new_locale = cot_import('locale', 'P', 'ALP');
// Проверяем допустимость
if (!in_array($new_locale, array_keys($i18n4marketpro_locales))) {
cot_error('i18n_incorrect_locale', 'locale');
}
// Если локаль изменилась, проверяем, нет ли уже перевода для новой локали
if ($new_locale != $i18n4marketpro_locale && empty(cot_error_found())) {
$checkStmt = Cot::$db->query(
'SELECT 1 FROM ' . $db->i18n4marketpro_pages . ' WHERE ipage_id = ? AND ipage_locale = ?',
[$id, $new_locale]
);
if ($checkStmt->rowCount() > 0) {
cot_error('i18n_translation_exists', 'locale');
}
$checkStmt->closeCursor();
}
// Обновляем данные перевода
$pag_i18n4marketpro['ipage_date'] = Cot::$sys['now'];
$pag_i18n4marketpro['ipage_title'] = cot_import('title', 'P', 'TXT');
if (mb_strlen($pag_i18n4marketpro['ipage_title']) < 2) {
cot_error('page_titletooshort', 'rpagetitle');
}
$pag_i18n4marketpro['ipage_desc'] = cot_import('desc', 'P', 'TXT');
$pag_i18n4marketpro['ipage_text'] = cot_import('translate_text', 'P', 'HTM');
// Если локаль изменилась, обновляем и её
$pag_i18n4marketpro['ipage_locale'] = $new_locale;
if (cot_error_found()) {
// При ошибках не делаем редирект, а покажем форму снова с заполненными полями
// Для этого нужно сохранить $pag_i18n4marketpro с новыми данными и $new_locale
// Просто продолжим выполнение до отрисовки формы
} else {
// Если локаль изменилась, удаляем старую запись и вставляем новую?
// Или просто обновляем, меняя ipage_locale.
// Проще обновить, но условие WHERE должно быть по старой локали.
Cot::$db->update($db->i18n4marketpro_pages,
[
'ipage_locale' => $new_locale,
'ipage_date' => $pag_i18n4marketpro['ipage_date'],
'ipage_title' => $pag_i18n4marketpro['ipage_title'],
'ipage_desc' => $pag_i18n4marketpro['ipage_desc'],
'ipage_text' => $pag_i18n4marketpro['ipage_text']
],
"ipage_id = ? AND ipage_locale = ?",
[$id, $i18n4marketpro_locale]
);
/* === Hook === */
foreach (cot_getextplugins('i18n4marketpro.market.edit.update') as $pl) {
include $pl;
}
/* =============*/
cot_message('Updated');
cot_log("Edited translate for page #" . $id, 'i18n4marketpro', 'market', 'edit');
$page_urlp = empty($item['fieldmrkt_alias']) ? 'c=' . $item['fieldmrkt_cat'] . "&id=$id&l=" . $new_locale
: 'c=' . $item['fieldmrkt_cat'] . '&al=' . $item['fieldmrkt_alias'] . '&l=' . $new_locale;
cot_redirect(cot_url('market', $page_urlp, '', true, false, true));
}
}
Cot::$out['subtitle'] = Cot::$L['i18n4marketpro_editing'];
$t = new XTemplate(cot_tplfile('i18n4marketpro.market', 'plug'));
// Формируем список локалей для селектора
// Все доступные локали
$lc_list = $i18n4marketpro_locales;
// Исключаем язык оригинала
unset($lc_list[Cot::$cfg['defaultlang']]);
// Получаем все существующие переводы для этой страницы
$existing = cot_i18n4marketpro_list_page_locales($id);
// Удаляем из списка те локали, которые уже заняты (кроме текущей)
foreach ($existing as $lc) {
if ($lc != $i18n4marketpro_locale) {
unset($lc_list[$lc]);
}
}
$lc_values = array_keys($lc_list);
$lc_names = array_values($lc_list);
// Значение для селектора: если форма отправлена с ошибкой, берём из POST, иначе текущая локаль
$selected_in_selector = ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($new_locale)) ? $new_locale : $i18n4marketpro_locale;
// Для полей формы при ошибке подставляем введённые данные
$title_val = ($_SERVER['REQUEST_METHOD'] == 'POST') ? cot_import('title', 'P', 'TXT') : $pag_i18n4marketpro['ipage_title'];
$desc_val = ($_SERVER['REQUEST_METHOD'] == 'POST') ? cot_import('desc', 'P', 'TXT') : $pag_i18n4marketpro['ipage_desc'];
$text_val = ($_SERVER['REQUEST_METHOD'] == 'POST') ? cot_import('translate_text', 'P', 'HTM') : $pag_i18n4marketpro['ipage_text'];
$t->assign([
'I18N4MARKETPRO_ACTION' => cot_url('plug', "e=i18n4marketpro&m=market&a=edit&id=$id&l=$i18n4marketpro_locale"),
'I18N4MARKETPRO_TITLE' => Cot::$L['i18n4marketpro_editing'],
'I18N4MARKETPRO_ORIGINAL_LANG' => $i18n4marketpro_locales[Cot::$cfg['defaultlang']],
// Вместо текста теперь селектор
'I18N4MARKETPRO_LOCALIZED_LANG' => cot_selectbox($selected_in_selector, 'locale', $lc_values, $lc_names, false),
'I18N4MARKETPRO_PAGE_TITLE' => htmlspecialchars($item['fieldmrkt_title']),
'I18N4MARKETPRO_PAGE_DESC' => htmlspecialchars($item['fieldmrkt_desc']),
'I18N4MARKETPRO_PAGE_TEXT' => cot_parse($item['fieldmrkt_text'], Cot::$cfg['market']['marketmarkup']),
'I18N4MARKETPRO_IPAGE_TITLE' => htmlspecialchars($title_val),
'I18N4MARKETPRO_IPAGE_DESC' => htmlspecialchars($desc_val),
'I18N4MARKETPRO_IPAGE_TEXT' => cot_textarea('translate_text', $text_val, 32, 80, '', 'input_textarea_editor')
]);
cot_display_messages($t);
/* === Hook === */
foreach (cot_getextplugins('i18n4marketpro.market.edit.tags') as $pl) {
include $pl;
}
/* =============*/
}
// ------------------------------------------------------------------
// УДАЛЕНИЕ
// ------------------------------------------------------------------
elseif ($a == 'delete' && ($i18n4marketpro_admin || Cot::$usr['id'] == $pag_i18n4marketpro['ipage_translatorid'])) {
if (cot_plugin_active('trashcan') && Cot::$cfg['plugin']['trashcan']['trash_page']) {
require_once cot_incfile('trashcan', 'plug');
$row = Cot::$db->query('SELECT * FROM ' . $db->i18n4marketpro_pages .
' WHERE ipage_id = ? AND ipage_locale = ?', [$id, $i18n4marketpro_locale])->fetch();
TrashcanService::getInstance()->put(
'i18n4marketpro_page',
Cot::$L['i18n4marketpro_translation'] . " #$id ($i18n4marketpro_locale) " . $row['ipage_title'],
(string) $id,
$row
);
}
Cot::$db->delete($db->i18n4marketpro_pages, "ipage_id = $id AND ipage_locale = '$i18n4marketpro_locale'");
$urlParams = [];
/* === Hook === */
foreach (cot_getextplugins('i18n4marketpro.market.delete.done') as $pl) {
include $pl;
}
/* =============*/
cot_message(Cot::$L['Deleted']);
cot_log("Deleted translate for page #" . $id, 'i18n4marketpro', 'market', 'delete');
if (empty($urlParams)) {
$urlParams = ['c' => $item['fieldmrkt_cat']];
if (!empty($item['fieldmrkt_alias'])) {
$urlParams['al'] = $item['fieldmrkt_alias'];
} else {
$urlParams['id'] = $id;
}
}
cot_redirect(cot_url('market', $urlParams, '', true));
} else {
cot_die(true, true);
}
} else {
cot_die(true, true);
}
и код шаблона
<!-- BEGIN: MAIN -->
<div class="border-bottom border-secondary py-3 px-3">
<nav aria-label="breadcrumb">
<div class="ps-container-breadcrumb">
<ol class="breadcrumb d-flex mb-0">
{I18N4MARKETPRO_TITLE}
</ol>
</div>
</nav>
</div>
<div class="py-4 px-4 min-height-50vh">
<h2 class="mb-4"></h2>
{FILE "{PHP.cfg.themes_dir}/{PHP.cfg.defaulttheme}/warnings.tpl"}
<form action="{I18N4MARKETPRO_ACTION}" method="post">
<div class="row">
<div class="col-12 mb-5">
<div class="row">
<div class="col-6">
<div class="p-3 mb-2 bg-success text-white">{PHP.L.i18n4marketpro_original} ({I18N4MARKETPRO_ORIGINAL_LANG})</div>
</div>
<div class="col-6">
<div class="p-3 mb-2 bg-warning text-dark">
<div class="row">
<div class="col-6">{PHP.L.i18n4marketpro_localized}</div>
<div class="col-6">{I18N4MARKETPRO_LOCALIZED_LANG}</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="card border-0 mb-5" style="border-radius: 0;">
<div class="card-body p-0">
<div class="row">
<div class="col-12 col-md-6 bg-success-subtle">
<p class="fw-semibold mt-2">{PHP.L.Title}</p>
<div class="mb-3 border rounded border-secondary p-2"><span class="fw-semibold">{I18N4MARKETPRO_PAGE_TITLE}</span></div>
<p class="fw-semibold">{PHP.L.Description}</p>
<div class="mb-3 border rounded border-secondary p-2">{I18N4MARKETPRO_PAGE_DESC}</div>
<p class="fw-semibold">{PHP.L.Tags}</p>
<div class="mb-3 border rounded border-secondary p-2">{I18N4MARKETPRO_PAGE_TAGS}</div>
<p class="fw-semibold">{PHP.L.Text}</p>
<div class="mb-3 border rounded border-secondary p-2">{I18N4MARKETPRO_PAGE_TEXT}</div>
</div>
<div class="col-12 col-md-6 bg-warning-subtle">
<div class="py-2">
<label class="form-label"><span class="fw-semibold">{PHP.L.Title}</span></label>
<input type="text" class="form-control" name="title" value="{I18N4MARKETPRO_IPAGE_TITLE}" maxlength="128" />
</div>
<div class="py-2">
<label class="form-label"><span class="fw-semibold">{PHP.L.Description}</span></label>
<textarea class="form-control" name="desc" maxlength="255" rows="4">{I18N4MARKETPRO_IPAGE_DESC}</textarea>
</div>
<!-- BEGIN: TAGS -->
<div class="py-2">
<label class="form-label"><span class="fw-semibold">{PHP.L.Tags}</span></label>
{I18N4MARKETPRO_IPAGE_TAGS}
<small class="text-muted">({PHP.L.tags_comma_separated})</small>
</div>
<!-- END: TAGS -->
<div class="py-2">
<label class="form-label"><span class="fw-semibold">{PHP.L.Text}</span></label>
{I18N4MARKETPRO_IPAGE_TEXT}
</div>
<div class="col-12 text-center py-4">
<button type="submit" class="btn btn-primary col-6">{PHP.L.Submit}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<!-- This is the name of the template for informing the administrator -->
<!-- IF {PHP.usr.maingrp} == 5 -->
<div class="alert alert-warning" role="alert">
<strong>{PHP.usr.name}</strong>, This is the HTML template <code>i18n4marketpro.market.tpl</code>
</div>
<!-- ENDIF -->
<!-- END: MAIN -->
🧙♂️ Радуйся, странниче добрый и честный! Не понапрасну привела тя стезя в земли сии. Зде бо мужи мудры и искусники дела писменнаго и численнаго, что куют словеса и плетут узоры кода, тайны разгадывают и знанием делятся, летописи множа и ремесло цифровое творя.
⬅️ Аще налево пойдеши — обрящеши грамоты древния, писания старинныя и свитки учения. ⬆️ Аще прямо — слово мудрое и совет от мужей разумеющих, что в деле кодописном искусны, получиши. ➡️ Аще направо — сам в писцы и летописцы внидеши, и в ремесло цифровое, где строки и знаки в дело живое обращаются, слово свое в память веков вложиши.
📝 Не медли же — нареки имя свое, и вниди в чин наш, и стань с нами в братстве, где код есть магия, а строки — заклятия живыя, числом и буквою слово едины суть.
🏰 Не тайно есть собрание сие, и не инициации в нем, но многое сокрыто от пришлых и ступалого, понеже не всякому открывается знание, но токмо ищущим и пребывающим в деле сем.