Skip to content

Update to v6.5.1

melbis edited this page Aug 30, 2026 · 1 revision

1. Backup Scripts and Database

Ensure you have complete backups of your current scripts and database before proceeding.

2. Install the New Client Application

Download and install the latest version of the client application (build 515 or newer — the v6.5.1 server rejects older clients).

  • v6.5.1 installs side by side with v6.5.0: separate folder, separate entry in Programs and Features, both versions stay operational.
  • On the first install into a fresh folder the installer carries your settings over from v6.5.0 automatically (MShop.ini, ShopList.ini, editor styles, agent settings).

3. Update Server-Side Scripts

  • Docker Setup: Change the image tag in /var/melbis/docker-compose.yml from melbis/melbis-shop:v6.5.0 to melbis/melbis-shop:v6.5.1, then pull the image and restart the container.
  • Manual Setup: Download the updated scripts and overwrite the core folder on your server.

4. Licences and Server Configuration

v6.5.1 validates daily Ed25519 licence tokens; the old md5 token scheme is removed, so v6.5.0 tokens will not pass.

  1. Before updating, create an empty admin.here file in the shop root, next to index.php. With this file present the client connects without a licence token, so you keep full access during the transition. Note: admin.here is a service mode — user action logging is disabled while it exists.
  2. Update the server and the client.
  3. Purchase new v6.5.1 licences, apply them, and delete admin.here.

Also new in the configuration:

  • Secrets: config.json now stores secrets; manage them from the client under Installation -> Secrets.

5. Execute Database Migrations

Connect to your database and run the following SQL commands:

-- Goods browser: per-topic access flag
ALTER TABLE {DBNICK}_topic_right ADD for_browse TINYINT UNSIGNED DEFAULT '0' NOT NULL AFTER for_ctrl;


-- Taxes
CREATE TABLE {DBNICK}_tax_area (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   code 	      CHAR(100) DEFAULT '' NOT NULL,
   kind_key 	CHAR(100) DEFAULT '' NOT NULL,
   type_key 	CHAR(100) DEFAULT '' NOT NULL,
   params 	   CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (tindex),
   KEY IDX2 (absindex),
   KEY IDX3 (kind_key)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_tax_group (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_tax_rate (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   group_id	   INT UNSIGNED DEFAULT NULL,
   kind_key 	CHAR(100) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   rate_proc	DECIMAL(10,4) DEFAULT '0' NOT NULL,
   rate_sum	   DECIMAL(10,2) DEFAULT '0' NOT NULL,
   rate_sum_curr_id INT UNSIGNED DEFAULT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (group_id),
   KEY IDX2 (kind_key)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_tax_rule (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   area_id	   INT UNSIGNED DEFAULT NULL,
   rate_id	   INT UNSIGNED DEFAULT NULL,
   rule_key 	CHAR(100) DEFAULT '' NOT NULL,
   rule_custom	TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   rule_proc	DECIMAL(10,4) DEFAULT '0' NOT NULL,
   rule_sum	   DECIMAL(10,2) DEFAULT '0' NOT NULL,
   rule_sum_curr_id INT UNSIGNED DEFAULT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (area_id),
   KEY IDX2 (rate_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_tax_area_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_tax_area_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_tax_area_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   tax_area_id        INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (tax_area_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

ALTER TABLE {DBNICK}_store ADD tax_group_id INT UNSIGNED DEFAULT NULL AFTER disc_group_id;

INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('tax_area', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('tax_group', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('tax_rate', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('tax_rule', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('tax_area_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('tax_area_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('tax_area_key_set', 0);


-- Supplier stocks
CREATE TABLE {DBNICK}_provider_stock (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   provider_id 	INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   kind_key 	CHAR(100) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (provider_id),
   KEY IDX2 (kind_key)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_provider_stock_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)   
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_provider_stock_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_provider_stock_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   provider_stock_id INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (provider_stock_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_store_stock (
   id 		      BIGINT UNSIGNED DEFAULT '0' NOT NULL,
   store_id 	   BIGINT UNSIGNED DEFAULT NULL,
   provider_stock_id INT UNSIGNED DEFAULT NULL,
   how 		      INT DEFAULT '0' NOT NULL,
   params 	      CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (store_id),
   KEY IDX2 (provider_stock_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

ALTER TABLE {DBNICK}_orders_store ADD store_stock_id INT UNSIGNED DEFAULT NULL AFTER store_provider_id;

INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('provider_stock', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('provider_stock_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('provider_stock_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('provider_stock_key_set', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('store_stock', 0);


-- Key-value dictionaries for users, groups, parameters, promo blocks and filters
CREATE TABLE {DBNICK}_user_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_user_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_user_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   user_id	      INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (user_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_user_group_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_user_group_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_user_group_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   user_group_id      INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (user_group_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_param_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)   
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_param_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_param_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   param_id	   INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (param_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_param_value_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_param_value_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_param_value_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   param_value_id INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (param_value_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_advert_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_advert_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_advert_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   advert_id          INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (advert_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_topic_filter_key (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   descr	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   mask_edit	CHAR(255) DEFAULT '' NOT NULL,
   PRIMARY KEY (id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_topic_filter_key_value (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   skey 	      CHAR(32) DEFAULT '' NOT NULL,
   key_id	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (key_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_topic_filter_key_set (
   id 		      INT UNSIGNED DEFAULT '0' NOT NULL,
   topic_filter_id    INT UNSIGNED DEFAULT NULL,
   key_id	      INT UNSIGNED DEFAULT NULL,
   value_id	      INT UNSIGNED DEFAULT NULL,
   value_txt 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (topic_filter_id),
   KEY IDX2 (key_id),
   KEY IDX3 (value_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

ALTER TABLE {DBNICK}_param_value
   ADD groupe CHAR(255) DEFAULT '' NOT NULL AFTER param_id,
   ADD kind_key CHAR(100) DEFAULT '' NOT NULL AFTER name,
   ADD KEY IDX2 (kind_key);

INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('user_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('user_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('user_key_set', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('user_group_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('user_group_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('user_group_key_set', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('param_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('param_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('param_key_set', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('param_value_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('param_value_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('param_value_key_set', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('advert_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('advert_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('advert_key_set', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('topic_filter_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('topic_filter_key_value', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('topic_filter_key_set', 0);


-- AI assistant
CREATE TABLE {DBNICK}_agent_memory (
   id 		   INT UNSIGNED NOT NULL AUTO_INCREMENT,
   user_id 	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(100) DEFAULT '' NOT NULL,
   info 	      CHAR(255) DEFAULT '' NOT NULL,
   body 	      MEDIUMTEXT DEFAULT ('') NOT NULL,
   shared 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   edit_time	DATETIME DEFAULT '2000-01-01 00:00:00' NOT NULL,
   PRIMARY KEY (id),
   UNIQUE (user_id, name)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_agent_tool (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   name 	      CHAR(255) DEFAULT '' NOT NULL,
   descr 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   tindex 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   tlevel 	   INT UNSIGNED DEFAULT '0' NOT NULL,
   absindex 	INT UNSIGNED DEFAULT '0' NOT NULL,
   folder 	   TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   unit 	      CHAR(100) DEFAULT '' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (tindex),
   KEY IDX2 (absindex),
   KEY IDX3 (unit)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_agent_tool_command (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   tool_id 	   INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(100) DEFAULT '' NOT NULL,
   descr 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (tool_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_agent_tool_param (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   command_id 	INT UNSIGNED DEFAULT NULL,
   name 	      CHAR(100) DEFAULT '' NOT NULL,
   descr 	   MEDIUMTEXT DEFAULT ('') NOT NULL,
   value_type 	CHAR(20) DEFAULT 'str' NOT NULL,
   value_req 	TINYINT UNSIGNED DEFAULT '0' NOT NULL,
   value_def 	CHAR(255) DEFAULT '' NOT NULL,
   pos 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (command_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

CREATE TABLE {DBNICK}_agent_tool_right (
   id 		   INT UNSIGNED DEFAULT '0' NOT NULL,
   command_id 	INT UNSIGNED DEFAULT NULL,
   user_id 	   INT UNSIGNED DEFAULT NULL,
   group_id 	INT UNSIGNED DEFAULT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (command_id),
   KEY IDX2 (user_id),
   KEY IDX3 (group_id)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('agent_tool', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('agent_tool_command', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('agent_tool_param', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('agent_tool_right', 0);


-- Value lists for personal filters
CREATE TABLE {DBNICK}_user_filter_param (
   id 		INT UNSIGNED DEFAULT '0' NOT NULL,
   alias 	CHAR(32) DEFAULT '' NOT NULL,
   name 	   CHAR(255) DEFAULT '' NOT NULL,
   sql_txt	MEDIUMTEXT DEFAULT ('') NOT NULL,
   pos	 	INT UNSIGNED DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY IDX1 (alias)
) ENGINE = {ENGINE} DEFAULT CHARSET={CHARSET};

INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('user_filter_param', 0);


-- Fixes: missing and orphaned generators
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('files_web_key', 0);
INSERT INTO {DBNICK}_generator (table_name, gen_value) VALUES ('files_web_key_value', 0);
DELETE FROM {DBNICK}_generator WHERE table_name = 'store_set';


-- Only if your v6.5.0 was an upgrade done by the wiki guide (fresh v6.5.0 installs already have this index)
ALTER TABLE {DBNICK}_store_info ADD KEY IDX5 (store_id, info_id, value_dec);

6. Update Client Application Settings

Launch the client application and open System -> Users -> Operations and Permissions. Press Ctrl+S to switch the tree into edit mode, then apply the changes below.

Lines marked ADD, MOVE or RENAME are the changes to make; unmarked lines are the existing branches you navigate through. Data slices are written as server_table local_table fields.

  • Business
    • ADD: Taxes
      • ADD: Get (GET_TAX)
        • ADD: tax_area tax_area *
        • ADD: tax_group tax_group *
        • ADD: tax_rate tax_rate *
        • ADD: tax_rule tax_rule *
        • ADD: tax_area_key cut_tax_area_key *
        • ADD: tax_area_key_value cut_tax_area_key_value *
        • ADD: tax_area_key_set tax_area_key_set *
        • ADD: currency cut_currency *
        • ADD: key_value cut_key_value *
        • ADD: files_key_value cut_files_key_value *
      • ADD: Save (PUT_TAX)
        • ADD: tax_area tax_area *
        • ADD: tax_group tax_group *
        • ADD: tax_rate tax_rate *
        • ADD: tax_rule tax_rule *
        • ADD: tax_area_key_set tax_area_key_set *
    • Suppliers
      • Get (GET_PROVIDER)
        • ADD: provider_stock provider_stock *
        • ADD: provider_stock_key cut_provider_stock_key *
        • ADD: provider_stock_key_value cut_provider_stock_key_value *
        • ADD: provider_stock_key_set provider_stock_key_set *
      • Save (PUT_PROVIDER)
        • ADD: provider_stock provider_stock *
        • ADD: provider_stock_key_set provider_stock_key_set *
    • Orders
      • Refresh Settings (GET_ORDER_RELATIVE)
        • ADD: provider_stock cut_provider_stock *
        • ADD: user_filter_param cut_user_filter_param *
    • Customers
      • Refresh Settings (GET_CLIENT_RELATIVE)
        • ADD: user_filter_param cut_user_filter_param *
  • Products
    • Browser
      • Refresh Settings (GET_SELECT_STORE_RELATIVE)
        • ADD: self_key_value cut_self_key_value *
        • ADD: user cut_user id,group_id,login,name,phone,email,add_group_id
        • ADD: user_group cut_user_group *
        • ADD: user_filter cut_user_filter *
        • ADD: user_filter_param cut_user_filter_param *
        • ADD: oper cut_oper *
        • ADD: oper_right cut_oper_right *
        • ADD: report cut_report *
        • ADD: report_right cut_report_right *
      • ADD: Main
        • ADD: Get section products (GET_PART_BROWSE_STORE)
          • ADD: FUNC:GetPartBrowseStore part_browse_store *
          • ADD: FUNC:GetPartBrowseTopicStore part_browse_topic_store *
        • ADD: Advanced Product Query (GET_EXTEND_BROWSE_STORE)
          • ADD: FUNC:GetExtendBrowseStore part_browse_store *
          • ADD: FUNC:GetExtendBrowseTopicStore part_browse_topic_store *
      • ADD: Auxiliary
        • MOVE: Get section products (GET_PART_SELECT_STORE)
        • MOVE: Find and get products => Advanced Product Query (RENAME: GET_SEARCH_SELECT_STORE => GET_EXTEND_SELECT_STORE)
          • ADD: FUNC:GetExtendSelectStore part_select_store *
          • ADD: FUNC:GetExtendSelectTopicStore part_select_topic_store *
    • Prices
      • Refresh Settings (GET_PRICE_STORE_RELATIVE)
        • ADD: provider_stock cut_provider_stock *
        • ADD: tax_group cut_tax_group *
        • ADD: user_filter_param cut_user_filter_param *
      • Get section products (GET_PART_PRICE_STORE)
        • ADD: FUNC:GetPartPriceStoreStock part_price_store_stock *
      • Advanced Product Query (GET_EXTEND_PRICE_STORE)
        • ADD: FUNC:GetExtendPriceStoreStock part_price_store_stock *
    • Descriptions
      • Personal Section
        • Refresh Settings (GET_USER_FRAME_RELATIVE)
          • ADD: user_filter_param cut_user_filter_param *
  • Structure
    • Parameters
      • Get (GET_PARAM)
        • ADD: param_key cut_param_key *
        • ADD: param_key_value cut_param_key_value *
        • ADD: param_key_set param_key_set *
        • ADD: param_value_key cut_param_value_key *
        • ADD: param_value_key_value cut_param_value_key_value *
        • ADD: param_value_key_set param_value_key_set *
      • Save (PUT_PARAM)
        • ADD: param_key_set param_key_set *
        • ADD: param_value_key_set param_value_key_set *
    • Promo Blocks
      • Get (GET_ADVERT)
        • ADD: advert_key cut_advert_key *
        • ADD: advert_key_value cut_advert_key_value *
        • ADD: advert_key_set advert_key_set *
      • Save (PUT_ADVERT)
        • ADD: advert_key_set advert_key_set *
    • Filters
      • Get (GET_FILTER_TOPIC)
        • ADD: topic_filter_key cut_topic_filter_key *
        • ADD: topic_filter_key_value cut_topic_filter_key_value *
        • ADD: topic_filter_key_set topic_filter_key_set *
      • Save (PUT_FILTER_TOPIC)
        • ADD: topic_filter_key_set topic_filter_key_set *
  • Development
    • ADD: AI Tools
      • ADD: Get (GET_AGENT_OPTION)
        • ADD: agent_tool agent_tool *
        • ADD: agent_tool_command agent_tool_command *
        • ADD: agent_tool_param agent_tool_param *
        • ADD: agent_tool_right agent_tool_right *
        • ADD: oper cut_oper *
        • ADD: oper_right cut_oper_right *
        • ADD: user cut_user id,group_id,login,name,phone,email,add_group_id
        • ADD: user_group cut_user_group *
      • ADD: Save (PUT_AGENT_OPTION)
        • ADD: agent_tool agent_tool *
        • ADD: agent_tool_command agent_tool_command *
        • ADD: agent_tool_param agent_tool_param *
        • ADD: agent_tool_right agent_tool_right *
      • ADD: Export (TOOL_AGENT_EXPORT)
    • Settings Registry
      • Get (GET_KEY_VALUE)
        • ADD: param_key param_key *
        • ADD: param_key_value param_key_value *
        • ADD: param_value_key param_value_key *
        • ADD: param_value_key_value param_value_key_value *
        • ADD: user_key user_key *
        • ADD: user_key_value user_key_value *
        • ADD: user_group_key user_group_key *
        • ADD: user_group_key_value user_group_key_value *
        • ADD: advert_key advert_key *
        • ADD: advert_key_value advert_key_value *
        • ADD: topic_filter_key topic_filter_key *
        • ADD: topic_filter_key_value topic_filter_key_value *
        • ADD: provider_stock_key provider_stock_key *
        • ADD: provider_stock_key_value provider_stock_key_value *
        • ADD: tax_area_key tax_area_key *
        • ADD: tax_area_key_value tax_area_key_value *
        • ADD: user_filter_param user_filter_param *
      • Save (PUT_KEY_VALUE)
        • ADD: param_key param_key *
        • ADD: param_key_value param_key_value *
        • ADD: param_value_key param_value_key *
        • ADD: param_value_key_value param_value_key_value *
        • ADD: user_key user_key *
        • ADD: user_key_value user_key_value *
        • ADD: user_group_key user_group_key *
        • ADD: user_group_key_value user_group_key_value *
        • ADD: advert_key advert_key *
        • ADD: advert_key_value advert_key_value *
        • ADD: topic_filter_key topic_filter_key *
        • ADD: topic_filter_key_value topic_filter_key_value *
        • ADD: provider_stock_key provider_stock_key *
        • ADD: provider_stock_key_value provider_stock_key_value *
        • ADD: tax_area_key tax_area_key *
        • ADD: tax_area_key_value tax_area_key_value *
        • ADD: user_filter_param user_filter_param *
    • Workbench
      • MOVE: Update structural data => Get project structure (SCRIPTS_STRUCTURE_REFRESH), out of File operations to the Workbench root
      • File operations
        • Clear cache (RENAME: SCRIPTS_CAHCE_CLEAR => SCRIPTS_CACHE_CLEAR)
        • Images
          • ADD: Load (SCRIPTS_IMAGE_LOAD)
          • MOVE: Directory for images, out of File operations into Images
        • Statics
          • ADD: Directory
            • ADD: Add (SCRIPTS_FILE_DIR_ADD)
            • ADD: Rename (SCRIPTS_FILE_DIR_RENAME)
            • ADD: Delete (SCRIPTS_FILE_DIR_REMOVE)
      • Database
        • ADD: Lock tables (MANUAL_LOCK_TABLES)
        • ADD: Unlock tables (MANUAL_UNLOCK_TABLES)
        • ADD: Generate ID (MANUAL_GENERATE_ID)
  • ADD: AI Assistant
    • ADD: Memory
      • ADD: Get list (AGENT_MEMORY_LIST)
      • ADD: Load (AGENT_MEMORY_LOAD)
      • ADD: Save (AGENT_MEMORY_SAVE)
      • ADD: Delete (AGENT_MEMORY_REMOVE)
      • ADD: Full access (AGENT_MEMORY_FULL)
    • ADD: Tools
      • ADD: Get list (AGENT_TOOL_LIST)
      • ADD: Execute (AGENT_TOOL_RUN)
    • ADD: Direct access
      • ADD: Store files
        • ADD: Add (AGENT_ENGINE_FILES_ADD)
        • ADD: Delete (AGENT_ENGINE_FILES_REMOVE)
        • ADD: Load (AGENT_ENGINE_FILES_LOAD)
      • ADD: Database
        • ADD: Get data structure (AGENT_ENGINE_DB_TABLES)
        • ADD: Read data (AGENT_ENGINE_DB_SELECT)
        • ADD: Modify data (AGENT_ENGINE_DB_EXECUTE)
        • ADD: Get lock list (AGENT_ENGINE_DB_LOCKS)
        • ADD: Release table locks (AGENT_ENGINE_DB_UNLOCKS)
      • ADD: Development
        • ADD: Clear cache (AGENT_ENGINE_DEV_CACHE_CLEAR)
        • ADD: Get configuration (AGENT_ENGINE_DEV_CONFIG)
        • ADD: Read data (AGENT_ENGINE_DEV_READ)
        • ADD: Modify data (AGENT_ENGINE_DEV_WRITE)
    • ADD: Export
      • ADD: AI Tools (AGENT_TOOL_EXPORT)
      • ADD: Store (AGENT_SHOP_DOWNLOAD)
  • System
    • Users
      • Get (GET_USERS)
        • ADD: user_key cut_user_key *
        • ADD: user_key_value cut_user_key_value *
        • ADD: user_key_set user_key_set *
        • ADD: user_group_key cut_user_group_key *
        • ADD: user_group_key_value cut_user_group_key_value *
        • ADD: user_group_key_set user_group_key_set *
      • Save (PUT_USERS)
        • ADD: user_key_set user_key_set *
        • ADD: user_group_key_set user_group_key_set *

Settings Registry

Open Development -> Settings Registry, press Ctrl+S to switch into edit mode, and add the keys and values below.

  • Main directories
    • Parameters
      • Value
        • ADD: Type (PARAM_VALUE_KIND_KEY)
          • ADD: kDefault — Default
    • Suppliers
      • ADD: Stocks
        • ADD: Type (PROVIDER_STOCK_KIND_KEY)
          • ADD: kDefault — Default
    • ADD: Taxes
      • ADD: Area
        • ADD: Type (TAX_AREA_KIND_KEY)
          • ADD: kDefault — Default
        • ADD: Structure (TAX_AREA_TYPE_KEY)
          • ADD: kCountry — Country
          • ADD: kState — State
      • ADD: Rate
        • ADD: Type (TAX_RATE_KIND_KEY)
          • ADD: kDefault — Default
      • ADD: Rule
        • ADD: Type (TAX_RULE_KEY)
          • ADD: kDefault — Default
  • Components
    • Multilingual Support
      • Language
        • ADD: File groups (FILES_LANG)
          • ADD: kDefault — Default
  • Customers and orders
    • Customers
      • Registration
        • Field
          • ADD: File groups (FILES_FIELD)
            • ADD: kDefault — Default
    • Orders
      • Order Options
        • Option
          • ADD: File groups (FILES_ORDER_OPTION)
            • ADD: kDefault — Default
        • Option Value
          • ADD: File groups (FILES_ORDER_OPTION_VALUE)
            • ADD: kDefault — Default

7. Refactor the Development Environment

Changes below break existing modules — walk through your units and apply them. Details are in the developer guide shipped with the client.

Global variables: gVars is private now

The public MELBIS()->gVars array is gone. Modules that read or wrote it directly must switch to the accessor methods:

// v6.5.0
MELBIS()->gVars['MY_FLAG'] = 'on';
$flag = MELBIS()->gVars['MY_FLAG'] ?? '';

// v6.5.1
MELBIS()->GlobalAssign('MY_FLAG', 'on');
$flag = MELBIS()->GlobalFetch('MY_FLAG', '');

Also available: MELBIS()->GlobalAppend($mName, $mValue, $mReplace) to append to a list value and MELBIS()->GlobalClear($mName) to drop a key. Template tags ({MY_FLAG}) keep working unchanged.

Unit inclusion: Include() removed

// v6.5.0
MELBIS()->Include('unit_name');

// v6.5.1
MELBIS()->UnitInc('unit_name');

Related new methods: MELBIS()->UnitExists($mName) to test a unit before including it, and MELBIS()->UnitRun($mUnit, $mFunc, ...$mParams) to include a unit and call one of its functions in a single step.

CSRF: CsrfTokenCheck() removed

// v6.5.0
if ( !MELBIS()->CsrfTokenCheck($token) ) { ... }

// v6.5.1
if ( !MELBIS()->SessionCsrfCheck($token) ) { ... }

The token itself is issued by MELBIS()->SessionCsrfToken().

Terminating a unit: Stop() and Halt()

Interrupting a unit used to leave a half-written unit cache file behind. Terminate through the parser instead of calling the error handler or die() directly:

  • MELBIS()->Halt($mFile, $mError, $mInfo) — removes the unfinished unit cache file, then reports the error through the engine error handler.
  • MELBIS()->Stop() — only removes the unfinished unit cache file; use it right before a manual termination.