Multicat Market — Multiple Categories for a Single Product in Market Module v.5.x.x (Cotonti Siena)
🇬🇧 Description and How It Works
The Multicat Market plugin adds the ability to place a single listing/product (Market module page) in multiple categories of the market structure simultaneously.
Before installing this plugin, each Market page could belong to only one category (page_cat → fieldmrkt_cat). After installation:
- The primary category is still stored in the standard field
fieldmrkt_cat (required for compatibility with the core and other plugins). - All selected categories (including the primary one) are additionally saved in a separate table
cot_market_multicats. - When viewing the product list in any category (
market.list), the plugin automatically adds a condition to the query that finds products both by the old field and by the new relationship table — so the product appears in all selected categories. - When editing a listing, instead of a single category dropdown, a set of checkboxes appears — you can select as many categories as you want.
- The first selected category automatically becomes the "primary" one (
fieldmrkt_cat) — this guarantees full compatibility with all existing templates and core functions.
Thus, the plugin is completely transparent to the user and other extensions: everything continues to work as before, but a new feature appears — multi-categorization.
Important: The plugin will not work with your Market module if it is not version 5 and not developed by me. You can order adaptation of the plugin for freelance exchange builds. . To do so, write to me on the page
Installation
- Unpack the archive and upload the
multicatmarket folder to the plugins/ directory on the server. - Go to Admin Panel → Extensions → Multicat Market → Install.
- After installation, in the
market.edit.tpl template, add the two tags right after the standard category selector:
<!-- IF {PHP|cot_plugin_active('multicatmarket')} -->
<divclass="col-12">
<labelfor="marketCat" class="form-label fw-semibold">{PHP.L.multicatmarket_cats_edit}</label>
<divclass="input-group has-validation">{MARKET_FORM_MULTICAT}</div>
<smallclass="form-text text-muted mt-1">{MARKET_FORM_MULTICAT_HINT}</small>
</div>
<!-- ENDIF -->
In the market.admin.tpl template, in the desired place (e.g., right after the status), add:
<!-- IF {PHP|cot_plugin_active('multicatmarket')} -->
<div class="text-muted small">{ADMIN_PAGE_MULTICATS}</div>
<!-- ENDIF -->
Done! Now when editing a product card, you will see a list of category checkboxes.
Important: If you do not add these tags to the template — multiple categories will not work (there will simply be no selection form).
Plugin Files Structure & Purpose
/multicatmarket/
├── inc/
│ └── multicatmarket.functions.php ← Core functions for multi-categories
├── lang/
│ ├── multicatmarket.ru.lang.php ← Russian language file
│ └── multicatmarket.en.lang.php ← English language file
├── setup/
│ ├── multicatmarket.install.sql ← Creates table `cot_market_multicats` + migrates existing data
│ └── multicatmarket.uninstall.sql ← Removes table on uninstall
├── multicatmarket.admin.loop.php ← Hook market.admin.loop — displays categories in admin list
├── multicatmarket.market.delete.first.php ← Hook market.delete.first — removes relations when deleting product
├── multicatmarket.market.edit.import.php ← Hook market.edit.update.import — takes categories from POST and sets first as main
├── multicatmarket.market.edit.tags.php ← Hook market.edit.tags — generates checkboxes in edit form
├── multicatmarket.market.edit.update.done.php ← Hook market.edit.update.done — saves relations to DB after update
├── multicatmarket.market.list.query.php ← Hook market.list.query — main list filter with multi-category support
├── multicatmarket.global.php ← Global hook — table registration, without it → 500 error
└── multicatmarket.setup.php ← Registers plugin in Cotonti core and config
Detailed Description of Each File & Hook
1. multicatmarket.global.php
Global plugin file. Loaded automatically on every Cotonti load. Registers the cot_market_multicats table in the system:
Cot::$db->registerTable('market_multicats');
Without this file, accessing the table will cause a 500 error.
2. multicatmarket.setup.php
- Registers plugin metadata in the
cot_core table. - Adds configuration settings to the
cot_config table.
3. inc/multicatmarket.functions.php
Contains three core functions:
multicatmarket_get_cats($page_id) — returns array of structure_id of categories where the product is located.multicatmarket_get_cat_titles($page_id) — returns array of category titles (used in admin).multicatmarket_save_cats($page_id, $cats) — on save, completely replaces product-category relations (deletes old, inserts new in cot_market_multicats). Do not confuse with fieldmrkt_cat.
4. lang/multicatmarket.ru.lang.php
All interface strings and hints in Russian:
- Plugin name
- Text hint under checkboxes
- Error message if no category is selected
- Instructions for inserting tags into the template
5. setup/multicatmarket.install.sql
Creates the table and migrates existing data:
CREATETABLEIF NOT EXISTS `cot_market_multicats` (
`pcat_page_id`int UNSIGNED NOT NULL,
`pcat_cat_id` mediumint UNSIGNED NOT NULL,
UNIQUE KEY `pcat_unique` (`pcat_page_id`, `pcat_cat_id`),
KEY `pcat_page_id` (`pcat_page_id`),
KEY `pcat_cat_id` (`pcat_cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Migration of existing categories
INSERT IGNORE INTO`cot_market_multicats` (`pcat_page_id`, `pcat_cat_id`)
SELECTp.fieldmrkt_id, s.structure_id
FROM`cot_market` p
JOIN`cot_structure` s
ONp.fieldmrkt_cat=s.structure_code
WHEREp.fieldmrkt_id>0
ANDs.structure_id>0
ANDp.fieldmrkt_cat!=''
ANDs.structure_area='market';
6. multicatmarket.admin.loop.php → hook market.admin.loop
In the admin panel, adds a column listing all categories a product belongs to using multicatmarket_get_cat_titles(). Outputs ADMIN_PAGE_MULTICATS.
7. multicatmarket.market.delete.first.php → hook market.delete.first
Runs before product deletion. Removes all entries from cot_market_multicats for that page_id to avoid dangling relations.
8. multicatmarket.market.edit.import.php → hook market.edit.update.import
During form import, if $_POST['rcat'] contains selected categories, takes the first one, finds its structure_code, and writes it to fieldmrkt_cat. Ensures primary category is filled.
9. multicatmarket.market.edit.tags.php → hook market.edit.tags
Generates checkboxes for all Market categories, respecting user write permissions. Creates two template tags:
{MARKET_FORM_MULTICAT} — the checkboxes{MARKET_FORM_MULTICAT_HINT} — hint "Select categories (you can choose several)"
10. multicatmarket.market.edit.update.done.php → hook market.edit.update.done
After successful product update, saves all selected category relations using multicatmarket_save_cats().
11. multicatmarket.market.list.query.php → hook market.list.query
Handles displaying products in multiple categories:
- Finds the
structure_id of the category $c. - Replaces filter condition:
(p.fieldmrkt_cat='code'OR EXISTS (SELECT1FROM cot_market_multicats …))
Returns products with primary or additional categories.
Summary
The plugin fully enables multiple categories for the Market module while maintaining 100% compatibility with Cotonti core and other extensions. No changes to core files or Market module are required — everything is implemented via standard hooks and a separate relationship table.
Install Multicat Market and add the template tags to your product editing templates to make one product appear in multiple categories.
Version: 1.1.0
Date: 2025-12-05
Author: webitproff
Compatibility: Cotonti Siena 0.9.26+,
Market v5+, PHP 8.1–8.4, MySQL 8.0+
License: BSD
Repository: https://github.com/webitproff/cotonti-multicatmarket