Page XTools — плагин фильтра статей в Cotonti CMF

Плагин добавляет в админ-панель модуля Pages фильтр по категориям с поддержкой Select2 и полнотекстовый поиск по заголовку и описанию, сортировка по полям

Статус: Опубликован

1

Page XTools для Cotonti

Плагин для CMS Cotonti, добавляющий в админ-панель модуля Pages удобный фильтр по категориям (с поддержкой Select2) и полнотекстовый поиск по заголовку и телу страницы. Сортировка по полям таблицы, статусу и направлению. Работает без правок ядра — вся логика реализована через штатные хуки Cotonti.

Version Cotonti PHP License


📑 Оглавление


1. Общие сведения

1.1. Что такое Page XTools

Page XTools — это плагин для Cotonti CMF, который расширяет стандартную админ-панель модуля Pages:

  • быстрый поиск по тексту — по заголовку и содержимому страницы;
  • фильтр по категории — с поддержкой Select2 и подкатегорий;
  • дружелюбный дефолт — фильтр «Все» вместо «В очереди».

Плагин устанавливается как обычное расширение Cotonti и не требует правок ядра ни при установке, ни при обновлении CMS. Вся логика работает через два хука: page.admin.first и page.admin.tags.

1.2. Ключевые возможности

  • Полнотекстовый поиск по page_title и page_text с поддержкой нескольких слов (AND-семантика).
  • Фильтр по категории — с учётом иерархии (включая подкатегории).
  • Select2-совместимый выпадающий список — поддерживает поиск и отображение дерева.
  • Fallback-функционал — если Select2 не подключён, используется обычный ``.
  • Сохранение фильтров в URL — можно делиться ссылкой с активным фильтром, работает навигация по страницам.
  • Мультиязычность — файлы локализации для ru и en.
  • Никаких правок ядра — только штатные хуки Cotonti.

1.3. Системные требования

Компонент Минимальная версия Рекомендуемая
PHP 8.4 8.5+
MySQL 8.0 8.4+
MariaDB 10.2 10.6+
Cotonti 1.0.x Verona 1.0.x
Модуль Page должен быть активен —

Расширения PHP:

  • pdo_mysql — обязательно;
  • mbstring — для работы с кириллицей и UTF-8;
  • json — встроен в PHP ≥ 8.0.

Тема админки:

  • CotCP (рекомендуется) — уже включает Select2;
  • любая другая тема — плагин откатится на обычный ``.

1.4. Совместимость

Плагин протестирован на:

  • Cotonti 1.0.x;
  • MySQL 8.4;
  • MariaDB 10.2 — 10.11;
  • PHP 8.5;
  • Apache 2.4, Nginx (с php-fpm), LiteSpeed.

1.5. Ссылки


2. Принципы работы

2.1. Архитектура

Плагин состоит из двух файлов-обработчиков и одного вспомогательного файла с функциями. Никаких фоновых процессов, крон-задач или изменений в схеме БД нет.

Поток работы:

  1. Пользователь открывает /admin.php?m=page.
  2. Ядро Cotonti запускает page.admin.php.
  3. В момент, когда ядро собирает SQL-запросы списка страниц, срабатывает хук page.admin.first — плагин подменяет фильтр по категории и добавляет LIKE-условия поиска.
  4. Далее ядро выполняет SQL и рендерит шаблон.
  5. Перед парсингом шаблона срабатывает хук page.admin.tags — плагин добавляет в шаблон теги {SEARCH_SQ}, - форма поиска по ключевому слову
    {SEARCH_CAT_SELECT2}, - категория подставляется автоматически
    {SEARCH_CAT_SELECT2_CAT_EMPTY}, - позволяет выполнять поиск, не указывая категорию
    {SEARCH_CAT}, - обратная совместимость
    {CATTITLE}, заголовок категории, если зашли в нее
    {SEARCH_ACTION_URL}.
  6. Шаблон page.admin.tpl отображает форму поиска и фильтра.

2.2. Структура плагина

plugins/pagextools/
├── pagextools.setup.php               # метаданные плагина
├── pagextools.page.admin.first.php    # хук: построение SQL
├── pagextools.page.admin.tags.php     # хук: теги для шаблона
├── inc/
│   └── pagextools.functions.php       # функции рендеринга 
└── lang/
    ├── pagextools.ru.lang.php         # русская локализация
    └── pagextools.en.lang.php         # английская локализация

2.3. Хуки и их роль

Хук Когда вызывается Что делает плагин
page.admin.first после построения базового $sqlwhere, до SQL-запросов подменяет фильтр по категории, добавляет LIKE-условия поиска, пересобирает $urlParams и $backUrl
page.admin.tags после стандартного $t->assign([...]), до парсинга добавляет теги SEARCH_SQ, SEARCH_CAT_SELECT2, SEARCH_CAT, CATTITLE, SEARCH_ACTION_URL

Важно: хуки объявляются в самих файлах-обработчиках через блок [BEGIN_COT_EXT], а не в setup-файле. Setup содержит только метаданные (Code, Name, Version и т.д.).

2.4. Как работает фильтр по категориям

  1. Пользователь выбирает категорию в выпадающем списке → ?c=cat_code.
  2. В хуке page.admin.first значение $pxt_c = cot_import('c', 'G', 'ALP') извлекается и валидируется.
  3. Из базового $sqlwhere удаляется стандартная конструкция AND page_cat IN (...) через preg_replace.
  4. Вместо неё подставляется фильтр по категории и её подкатегориям через cot_structure_children('page', $pxt_c).
  5. Если категория не выбрана — используется стандартное поведение Cotonti.

2.5. Как работает поиск

  1. Пользователь вводит строку в поле «Поиск» → ?sq=слово.
  2. Строка разбивается по пробелам (preg_split('/\s+/u', ...)).
  3. Каждое слово экранируется через Cot::$db->prep().
  4. Собирается LIKE-паттерн: %слово1%слово2%.
  5. Условие добавляется в $sqlwhere:
    AND (page_title LIKE '%слово1%слово2%' OR page_text LIKE '%слово1%слово2%')
  6. Поиск работает с несколькими словами и по кириллице (UTF-8).

2.6. Параметры URL

Параметр Значение Описание
m page модуль (стандартный)
sq строка поисковый запрос
c код код категории
filter код стандартный фильтр Cotonti (all/valqueue/validated/drafts/expired)
sorttype код поле сортировки
sortway код направление (asc/desc)
d число номер страницы пагинации

Все фильтры сохраняются в URL, поэтому ими можно делиться и они работают при переходах по страницам.

2.7. Безопасность

  • cot_import('c', 'G', 'ALP') — категория принимается только как буквенно-цифровая строка (ALP), что исключает SQL-инъекции и XSS.
  • cot_import('sq', 'G', 'TXT') — поисковая строка очищается штатным импортёром Cotonti.
  • Cot::$db->prep() — экранирует спецсимволы перед подстановкой в LIKE.
  • htmlspecialchars() — применяется ко всем пользовательским данным перед вставкой в HTML.
  • Права доступа — плагин работает только для администраторов Cotonti с доступом к модулю Page. Проверка прав выполняется ядром.
  • CSRF — стандартные действия (validate, delete, update_checked) защищены штатным cot_check_xg() / cot_check_xp(), которые плагин не трогает.

3. Пошаговая установка

3.1.

Скачать архив с GitHub.

3.2.

  1. Сделать бекап сайта и базы данных.
  2. Распаковать локально на ПК скачанный архив.
  3. Загрузить папку pagextools/ в /plugins/ вашего Cotonti-сайта.
  4. Убедиться, что структура такая:
    /plugins/pagextools/pagextools.setup.php
    /plugins/pagextools/pagextools.page.admin.first.php
    /plugins/pagextools/pagextools.page.admin.tags.php
    /plugins/pagextools/inc/pagextools.functions.php
    /plugins/pagextools/lang/pagextools.ru.lang.php
    /plugins/pagextools/lang/pagextools.en.lang.php
  5. Войти в админку Cotonti.
  6. Перейти в Расширения → Управление плагинами.
  7. Найти Page XTools pagextools в списке и нажать «Установить».

3.3. Добавление кода в шаблон

Важно: плагин добавляет теги в шаблон, но не перезаписывает его.
Нужно самостоятельно вставить HTML-блок в свой page.admin.tpl темы админки.

НАЙТИ ДЕФОЛТНЫЙ ШАБЛОН modules/page/tpl/page.admin.tpl И ПЕРЕМЕСТИТЬ ЕГО В ПАПКУ ТЕМЫ АДМИНКИ, НАПРИМЕР ВОТ ТАК themes/admin/cotcp/modules/page/page.admin.tpl

В ДЕФОЛТНОМ ШАБЛОНЕ НАЙТИ БЛОК:

<!-- - -->
    <!-- IF {ADMIN_PAGE_TOTALDBPAGES} -->

        <!-- IF !{PHP|cot_plugin_active('urleditor')} OR {PHP.cfg.plugin.urleditor.preset} != 'handy' -->

        <!-- ENDIF -->
        <table class="cells">
            <thead>
                <tr>
                    <th class="coltop w-5"></th>
                    <th class="coltop w-5"></th>
                    <th class="coltop w-15 filterSelect">{ADMIN_PAGE_FILTER}</th>
                    <th class="coltop w-60">
                        <!-- IF {TOTAL_ENTRIES} > 1 -->
                        {PHP.L.adm_sort} {ADMIN_PAGE_ORDER} {ADMIN_PAGE_WAY}
                        <!-- ENDIF -->
                    </th>
                    <td class="coltop">{PHP.L.Filter}</td>
                </tr>
            </thead>
        </table>

    <!-- ENDIF -->
<!-- - -->  

И ПОЛНОСТЬЮ ЕГО ЗАМЕНИТЬ НА БЛОК НИЖЕ:

<!-- - -->

<!-- IF {CATTITLE} -->
<div class="alert alert-info my-2">
  {PHP.L.Category}: {CATTITLE}
</div>
<!-- ENDIF -->
<div class="card filter-section p-3 mb-4" style="border:5px solid;">
  <!-- IF {ADMIN_PAGE_TOTALDBPAGES} -->

    <!-- IF !{PHP|cot_plugin_active('urleditor')} OR {PHP.cfg.plugin.urleditor.preset} != 'handy' -->

    <!-- ENDIF -->
    <div class="row g-2 align-items-end">
      <div class="col-12 col-lg-3 d-flex flex-column h-100">
        <label class="form-label">{PHP.L.Search}</label>
        <div class="flex-grow-1">{SEARCH_SQ}</div>
      </div>
      <div class="col-12 col-lg-3 d-flex flex-column h-100">
        <label class="form-label">{PHP.L.Category}</label>
        <div class="flex-grow-1 filterSelect">{SEARCH_CAT_SELECT2}</div>
      </div>
      <div class="col-12 col-lg-3 d-flex flex-column h-100">
        <label class="form-label">{PHP.L.pagextools_filter_option_status}</label>
        <div class="flex-grow-1">{ADMIN_PAGE_FILTER}</div>
      </div>
      <!-- IF {TOTAL_ENTRIES} > 1 -->
      <div class="col-12 col-lg-3 d-flex flex-column h-100">
        <label class="form-label">{PHP.L.pagextools_filter_sorting_fields}</label>
        <div class="flex-grow-1">{ADMIN_PAGE_ORDER}</div>
      </div>
      <div class="col-12 col-lg-3 d-flex flex-column h-100">
        <label class="form-label">{PHP.L.pagextools_filter_sorting_direction}</label>
        <div class="flex-grow-1">{ADMIN_PAGE_WAY}</div>
      </div>
      <!-- ENDIF -->
      <div class="col-12 col-lg-3 d-flex flex-column h-100">

          {PHP.L.pagextools_filter} 
      </div>
      <div class="col-12 col-lg-3 d-flex flex-column h-100">
        <a class="btn btn-outline-danger w-100 mt-auto" href="%7BPHP%7Ccot_url('admin','m=page')%7D">{PHP.L.pagextools_prune} </a>
      </div>
    </div>

  <!-- ENDIF -->
</div>

<!-- - -->

в конце файла добавить

<style scoped>
    .filterSelect select {
        width: 100%;
    }
</style>

перед закрывающим шаблон блоком:

<!-- END: MAIN -->

3.4. Проверка работоспособности

  1. Открыть Инструменты → Страницы (/admin.php?m=page).
  2. Проверяем, что вверху появился блок с полями:
    • Поиск;
    • Категория (Select2 или обычный select);
    • Фильтр (стандартный Cotonti);
    • Сортировка (если записей > 1).
  3. Ввести в поле «Поиск» слово, например пример — нажать «Фильтровать».
  4. Проверяем, что список отфильтровался по page_title и page_text.
  5. Выбрать категорию — проверить, что список фильтруется по ней и подкатегориям.
  6. Нажать «Сбросить» — фильтры очищаются.

4. Пошаговое руководство по использованию

4.1. Поиск по тексту

  1. В поле «Поиск» ввести слово или фразу (можно несколько слов).
  2. Нажать «Фильтровать».
  3. Список сузится до записей, у которых page_title или page_text содержит все введённые слова.

Примеры:

  • привет — найдёт все страницы, где есть «привет».
  • привет мир — найдёт страницы, где есть и «привет», и «мир».
  • Поиск чувствителен к регистру? Нет, MySQL-коллация utf8mb4_unicode_ci не различает регистр.

4.2. Фильтр по категории

  1. Открыть выпадающий список «Категория».
  2. Выбрать нужную категорию (в дереве отображаются и подкатегории).
  3. Нажать «Фильтровать».
  4. Список покажет записи из выбранной категории и всех её подкатегорий.

Сброс категории: выбрать пустой вариант (---) или нажать «Сбросить».

4.3. Стандартный фильтр Cotonti

Поле «Фильтр» — стандартный фильтр Cotonti:

Значение Что показывает
Все все страницы (это дефолт плагина)
В очереди page_state = 1 (pending)
Одобренные page_state = 0 (published)
Истёкшие page_begin &gt; now OR (page_expire &lt;&gt; 0 AND page_expire &lt; now)
Черновики page_state = 2 (draft)

Замечание: базовый Cotonti использует valqueue по умолчанию. Плагин меняет дефолт на all, чтобы сразу видеть все записи.

4.4. Сортировка

  • «Сортировка» — поле сортировки (ID, заголовок, дата, дата публикации, автор и т.д.).
  • «Направление» — по возрастанию / по убыванию.

Оба параметра сохраняются в URL и работают при переходах по страницам.

4.5. Сброс фильтров

Кнопка «Сбросить» (иконка метлы) — переходит на чистый /admin.php?m=page без каких-либо фильтров.


5. Пошаговое руководство по безопасности

Плагин не вводит новых рисков, но для полной безопасности рекомендуется:

  1. Не давайте доступ к админке Pages не-администраторам. Плагин работает только для тех, у кого есть доступ к модулю Page. Проверка выполняется ядром Cotonti.
  2. Используйте HTTPS. Поисковые запросы и выбранные категории передаются в URL, и без HTTPS они видны в открытом виде.
  3. Ограничьте длину поисковых запросов через настройки PHP (например, max_input_vars, post_max_size). Плагин не ограничивает длину sq, поэтому гигантская строка может лечь в лог MySQL.
  4. Не убирайте вызов cot_check_xg() из кода. Это функция проверки XK-токена (аналог CSRF), а не настройка — включить или отключить её из админки нельзя. Она либо вызывается в файле обработчика (например, в page.admin.php перед действиями validate / unvalidate / delete / update_checked), либо нет. Если кто-то удалит эту строку из кода, действие станет уязвимо к CSRF. Плагин pagextools сам cot_check_xg() не трогает.
  5. Регулярно обновляйте Cotonti. Плагин не правит ядро, поэтому обновление CMS — это всегда безопасно (при условии, что структура ядра не меняется радикально).
  6. Не отключайте .htaccess и index.php в админ-папке. Это базовая гигиена Cotonti, но стоит упомянуть.
  7. Проверяйте шаблон до и после обновления темы админки. Если тема обновится — ваш добавленный блок в page.admin.tpl может исчезнуть. Это не риск для безопасности, но потребует повторной правки шаблона. Всегда спасают бекапы, если вы их делали.

6. Возможные проблемы и их решения

6.1. Форма поиска не появилась

Симптом: открываю /admin.php?m=page — формы нет.

Причины:

  • Плагин не установлен — проверить в Расширения → Управление плагинами.
  • Плагин не активирован — включить.
  • Не добавлен код в page.admin.tpl — проверить шаг 3.3.
  • Кэш темы/шаблонов — очистить кэш Cotonti в админке.

6.2. Ошибка «Call to undefined function cot_pagextools_selectcat_select2()»

Причина: не загружен файл функций.

Решение: проверить, что файл plugins/pagextools/inc/pagextools.functions.php существует и в хуках есть строка:

require_once cot_incfile('pagextools', 'plug');

6.3. Ошибка SQL: «Unknown column ...»

Причина: используется нестандартное поле page_* или шаблон таблицы был изменён.

Решение:

  • Проверить структуру таблицы cot_pages (SHOW COLUMNS FROM cot_pages).
  • Поиск в плагине работает по page_title и page_text. Если их нет — плагин некорректен.

6.4. Select2 не работает

Симптом: селект категории выглядит как обычный ``.

Причины:

  • Тема админки без Select2 — плагин откатывается на cot_pagextools_selectcat() (обычный select). Это нормальное поведение, не баг.
  • Select2 подключён, но инициализация JS не сработала — проверить консоль браузера.

Решение:

  • Установить тему CotCP — она уже включает совместимость шаблона админки модуля страниц с Select2.
  • Или добавить инициализацию Select2 в свой шаблон админки.

6.5. Поиск не находит ничего

Причина: ищется по page_title и page_text. Если искомая фраза в page_desc или мета-полях — поиск её не найдёт.

Решение:

  • Расширить поиск, добавив в $sqlwhere поля page_desc и/или page_keywords. Это делается в pagextools.page.admin.first.php:
$sqlwhere .= " AND (page_title LIKE '...' OR page_text LIKE '...' OR page_desc LIKE '...')";
  • Или использовать штатный поиск Cotonti (/index.php?e=search).

6.6. Поиск не находит кириллицу

Причина: база данных в latin1 или соединение не в utf8mb4.

Решение:

  • Проверить кодировку БД: SHOW CREATE DATABASE your_db; — должна быть utf8mb4.
  • Проверить datas/config.php → $cfg['mysqlcharset'] — должно быть utf8mb4.

6.7. Фильтр по категории не работает

Причина: код категории содержит спецсимволы или её нет в структуре.

Решение:

  • Проверить, что категория существует: Cot::$structure['page'][$code].
  • Проверить, что код категории — буквенно-цифровой (без пробелов, дефисов).

6.8. Форма исчезла после обновления темы админки

Причина: обновление темы перезаписало page.admin.tpl.

Решение:

  • Повторно вставить код из шага 3.3.

7. Логи и диагностика

7.1. Где смотреть

Что Где
Ошибки PHP /var/log/php/error.log, error_log сайта
Ошибки MySQL /var/log/mysql/error.log
Ошибки Apache /var/log/apache2/error.log
Ошибки Nginx /var/log/nginx/error.log
Cotonti debug datas/config.php → $cfg['debug_mode'] = true

7.2. Включение подробного логирования

В datas/config.php:

$cfg['debug_mode'] = true;
$cfg['devmode']    = true;
@SEE 
system/footer.php  
if (Cot::$cfg['devmode'] &amp;&amp; cot_auth('admin', 'a', 'A')) {  

После этого все SQL-запросы (включая запросы плагина) будут видны в дебаг области Cotonti с временем выполнения и stack trace.

Внимание: не оставляйте эти флаги на production.


8. FAQ — часто задаваемые вопросы

Q: Плагин работает без Select2? A: Да. Если Select2 не подключён, используется обычный `черезcot_pagextools_selectcat()`.

Q: Поиск чувствителен к регистру? A: Нет. Коллация utf8mb4_unicode_ci в MySQL/MariaDB не различает регистр.

Q: Поиск работает по описанию (page_desc)? A: Нет, по умолчанию только по page_title и page_text. Расширяется правкой хука page.admin.first.

Q: Можно ли искать по мета-полям (page_keywords, page_metatitle)? A: Штатно — нет. Требуется правка хука.

Q: Работает ли на Cotonti Verona 1.0.x? A: Да, начиная с версии 1.0.0 плагина. Используется Cot::$db, Cot::$structure — совместимо.

Q: Плагин совместим с Cotonti Siena 0.9.x? A: Да, начиная с 1.0.0.

Q: Нужно ли править ядро? A: Нет. Всё через хуки. При обновлении Cotonti плагин продолжит работать.

Q: Что будет, если я отключу плагин? A: Форма поиска и фильтра перестанут отображаться, остальное поведение админки вернётся к штатному. Никаких данных в БД плагин не хранит.

Q: Можно ли добавить сортировку по дате? A: Да, это штатная возможность Cotonti — поле sorttype в форме уже содержит все поля, включая date.

Q: Поиск тормозит на большой базе? A: Да, если в page_title и page_text нет индексов. Для больших таблиц (100k+ записей) добавьте FULLTEXT-индекс:

ALTER TABLE cot_pages ADD FULLTEXT(page_title, page_text);

и используйте MATCH ... AGAINST вместо LIKE. Это требует правки хука.

Q: Поддерживает ли плагин мультиязычность? A: Да, есть pagextools.ru.lang.php и pagextools.en.lang.php.

Q: Можно ли использовать плагин на нескольких сайтах? A: Да. Он не привязан к домену.


9. Обновление плагина

  1. Сделать бэкап файлов плагина и (на всякий случай) базы данных.
  2. Скачать новую версию из маркетплейса или с GitHub.
  3. В админке Cotonti → Расширения → Управление плагинами → Page XTools → Обновить.
  4. Если обновление через админку недоступно — распаковать поверх старой папки plugins/pagextools/.
  5. Проверить, что файлы pagextools.page.admin.first.php и pagextools.page.admin.tags.php не потеряли блок [BEGIN_COT_EXT] с хуками.
  6. Открыть /admin.php?m=page и проверить работоспособность.

10. Удаление плагина

  1. В админке Cotonti → Расширения → Управление плагинами → Page XTools → Удалить.
  2. Удалить папку plugins/pagextools/ вручную, если она осталась.
  3. Удалить блок формы из themes/admin/{тема}/modules/page/page.admin.tpl (иначе останутся «висячие» теги {SEARCH_SQ} — Cotonti их просто проигнорирует, но чистота важна).
  4. Удалить `` в конце шаблона.
  5. Очистить кэш Cotonti.

Важно: плагин не хранит данные в БД, поэтому удаление безопасно.


11. Дорожная карта

  • [ ] Расширение поиска — включить page_desc, page_keywords, page_metatitle.
  • [ ] FULLTEXT-индекс — опциональная настройка через конфиг.
  • [ ] Мультифильтр по нескольким категориям — множественный выбор.
  • [ ] Сохранение фильтров в cookie — чтобы при открытии админки фильтры восстанавливались.
  • [ ] Диапазон дат — фильтр по page_date / page_begin / page_expire.
  • [ ] Автор — фильтр по page_ownerid.
  • [ ] Экспорт списка — выгрузка отфильтрованного списка в CSV.
  • [ ] Поддержка Postgres — при переходе Cotonti на другие СУБД.
  • [ ] Расширенная сортировка — несколько полей.
  • [ ] Поиск по extrafields — по настраиваемым полям.

12. История изменений

v1.0.0 (2026-10-17)

  • Первая публичная версия.
  • Хуки page.admin.first и page.admin.tags.
  • Поиск по page_title и page_text с поддержкой нескольких слов.
  • Фильтр по категории с подкатегориями.
  • Select2-совместимый селект + fallback.
  • Дефолт фильтра изменён с valqueue на all.
  • Локализация ru / en.
  • Метаданные в setup-файле, хуки — в отдельных файлах.

13. Участие в разработке

Pull-request'ы приветствуются. Перед отправкой:

  1. Форкните репозиторий.
  2. Создайте ветку feature/your-feature или fix/your-bug.
  3. Следуйте PSR-12.
  4. Добавьте тесты, если возможно.
  5. Обновите README.md и CHANGELOG.
  6. Отправьте PR (Pull-request) с описанием: что, зачем, как проверить.

Правила для кода:

  • Имя функций — с префиксом cot_pagextools_.
  • Никаких правок ядра.
  • Все SQL-параметры — через Cot::$db-&gt;prep() или биндинг.
  • Все пользовательские данные в HTML — через htmlspecialchars().
  • Мультиязычность — через $L['pagextools_*'].

14. Лицензия

BSD 3-Clause. Полный текст — в файле License.txt.


15. Контакты и поддержка

Купить Page XTools — плагин фильтра статей в Cotonti CMF по низким ценам. Интернет-магазин предлагает заказать Page XTools — плагин фильтра статей в Cotonti CMF, просмотреть полное описание, детальные характеристики, фото товара и актуальные цены со скидками
С этим товаром, люди часто заказывают: Установка, интеграция и адаптация плагинов под Cotonti CMF.


Рейтинг на основе отзывов:
Звезд получено: 0
Oтзывов всего: 0
Средняя оценка: 0
14 минут чтения
Владелец: Carbonate Sodium

You may have been looking for this for a long time.:

Модуль Market PRO v.5+ для Cotonti CMF.

webitproff
Продавец товара: webitproff
Витрина продавца

Оффлайн

Последняя авторизация: 17.10.2026 16:52

Обо мне кратко
Поддержка и разработка веб-проектов на CMF Cotonti: приватные мессенджеры через сайт, открытые и закрытые небольшие социальные сети, торговые площадки и маркетплейсы, портал биржи фриланса и услуг, каталоги товаров оптовых поставщиков, дропшиппинг-платформы, интернет-магазины и многое другое.
Смотреть разработки и скачать
Публичное портфолио моих работ и разработок
Телеграм для сообщений
@webitproff
Телеграм-канал
@s/aBuyFILE
Публичный профиль
  • Дата размещения 17.10.2026 04:46
  • Обновлено 17.10.2026 17:07

Витрина Market PRO

CMS, Скрипт и Движок - веб сайта онлайн-витрины, интернет магазина инфопродуктов и цифровых товаров. Разные цены в разных валютах на товар. Онлайн-оплата в криптовалюте за товары и услуги.