Web modules
One of the most important features of Melbis Shop 6 is the scalability of the system by integrating separate web modules into the local program. Today, the absolute majority of CMS, blogs and forums do not have client applications, and their management system (admin section) is built entirely on HTML-interface and accordingly managed only through the browser. However, many serious products working with more or less decent amount of data tend to develop an additional fast desktop interface.
When such an application is created by a rich company, for example, Google AdWords Editor, it spends enough time to maintain its functionality similar to that of a website. That is why, many CMS do not have two versions of admin part at once: web and desktop. Most developers chose the web version as the main one. Well it is correct, but it is not the best option from possible. Historically, we started the development of Melbis Shop with another solution - a desktop program, but then, soon we were able to make the integration of web modules into it, thus getting the name best version of CMS. We tried to make Melbis Shop as functional as possible, but from our practice we see that sooner or later the owner has a need to realize his own unique task. In addition to this, there are situations when development of individual controls or generation of instant reports will be more convenient via web-based admin. These web interfaces are easily accessible on any device like a smartphone or tablet and will not require the installation of a local program.
It is for these reasons that web modules are implemented in Melbis Shop 6 and we strongly recommend you to pay attention to them, as we consider it one of the key advantages of the system. By developing your own web module, you will be able to solve two problems at once: expand the functionality, plus add an alternative way to manage your store.
So, what are these web modules and where can we use them? To begin with, let's note that there are two types of web modules in the system: built-in and external. Built-in modules are those that are built directly into the Melbis Shop application interface and interact with it by receiving and transmitting data. External modules are those that will primarily work outside the Melbis Shop application. That is, you only need to know the address of the module to open it in any browser on any device. Before we start talking about them, it is recommended to familiarize yourself with the sections"Root Scripts" and"Modular Scripts", because a web module is nothing but a special, but still the same modular script.
Test web module
Open the"Prices","Customers" or"Orders" sections in the program and press the Ctrl-W key combination. As a result, a special "Built-in Web Module" window will appear in each of these windows. This embedded module is nothing more than a browser (based on Chromium) that has been integrated into each of these windows. The key point of this approach is that when you perform any actions in the window (navigate through products, orders, customers), certain parameters are passed to the embedded web module. For example, in the "Prices" section, the id of the item is passed to the web module, as well as information about who exactly performs the action (more about the principles of user authorization below). Thus, you can develop a web module that will extend any functionality of the store. These modules can be many, they can be switched, and to each of the modules can be set access rights for users. For example, for the "Prices" section, you can develop web modules such as: "View product information", "Product sales statistics", "Product warehouse accounting", etc. For sections "Orders" and/or "Customers" you can develop modules-reports: "Purchase History", "Sending SMS, E-mail", etc.
Now let's consider how to create your own built-in web-module. First of all, you should go to the "Design / Module Options" section, then go to the "Built-in web modules" tab and choose what exactly the web module will be created for. There are three groups to choose from: "Goods", "Customer", "Orders", "Scheduler" and "Invisible". After that, you can add a module and specify its parameters: name, module address and key - the symbolic code of the module. For example, by default, the basic store delivery contains a test module with the following parameters:
- Name: Test Module
- Module address: http://ms6.com/?mod=melbis_web_test
- Key: TEST
Please note that the"User identification required" option is specified for the module. This item is an additional (optional) flag, which indicates that when accessing this module, user attributes (login and password) must be added and checked to perform user authorization. For example, for a product module, in addition to the product id, the"login" and"password" fields will be sent additionally, which are specified in the connection parameters. Please note that the password is sent in encoded form (PHP function md5()). For example, for the test module, the following data will be passed:
array ( 'get' => array ( 'mod' => 'melbis_web_test', ), 'post' => array ( 'melbis' => '', 'login' => 'admin', 'pass_code' => '3240e96ca45f6e45b36f7b56a093ce0a', 'topic_id' => '4', 'store_id' => '1' ), ), )
So, you have learned where embedded web modules are defined and configured. Next, we'll cover how the basic test web module melbis_web_test.php is organized and works. But before we get to it, we should mention the index.php root script. In fact, we've already talked about it in detail in theRoot Scripts section. So, if you are not familiar with this section, read it to understand how the melbis_web_test.php module will be called.
Let's start with its input parameters, which are defined as standard for the module called by the root script index.php:
get: serial, post: serial
That is, at the input we will get an array with all the data passed by GET and POST methods.
/** * Function MELBIS_WEB_TEST **/ function MELBIS_WEB_TEST($mVars) { global $gParser; return MELBIS_INC_AUTH(__FUNCTION__, $mVars); }
And this is how the main function MELBIS_WEB_TEST looks like, which will be called automatically. Actually, it is quite simple and consists of calling the MELBIS_INC_AUTH function from the module-library melbis_inc_auth.php. This is a universal module that we have written specifically for web modules. It has a special function that we recommend you use to simplify your development. All you need to do is call the MELBIS_INC_AUTH function, passing it two parameters: the module name and an array of GET and POST input data. This function will automatically identify the user, determine the type of module and the permission to run it. After that, this function will automatically pass control back to the module by calling a function of type"module_name_default", with the following three parameters:
- $mUserId - the defined user ID(0 if not defined)
- $mResultAuth - authorization result code, can take the following values:
- accept - successful authorization and user access to the module
- denied - successful authorization, but the user's access to the module isdenied
- wrong - user authorization failed
- start - start of authorization process (no authorization attempt was made)
- $mVars - array of GET and POST input data with which the module was initially called.
/** * Function MELBIS_WEB_TEST_default **/ function MELBIS_WEB_TEST_default($mUserId, $mResultAuth, $mVars) { global $gParser; // Create $tpl = $gParser->TplCreate();
// Auth if ( $mResultAuth == 'accept' ) { // Prepare rights MELBIS_INC_AUTH_AUTH_web_key_prepare($mUserId);
// Show demo post vars $gParser->TplAssign($tpl, 'VARS', var_export($mVars, true)); // Order change back demo $order = ( isset($mVars['post']['order'] ) ) ? $mVars['post']['order'] : '{}'; $gParser->TplAssign($tpl, 'ORDER', $order); // Scripts $gParser->TplParse($tpl, 'SCRIPTS', 'scripts'); // Main $gParser->TplParse($tpl, 'MAIN', 'main'); } else { // Auth $gParser->TplParse($tpl, 'MAIN', 'auth'); } return $gParser->TplFree($tpl, 'MAIN'); }
This is how the default-function looks like for the module we are considering. If the authorization is successful, we prepare the necessary keys and templates and generate a response based on the main.htm template. Otherwise, if the authorization is unsuccessful, we output the auth.htm template. It is a call of a separate module authorization melbis_web_auth.php. In general, this is a kind of universal approach, in case the module will be called both as a built-in module in Melbis Shop, and as an external one through any browser (then it is required to ask for login and password to identify the user). If you know that it will be a web module for internal use only, then instead of the auth.htm template, you can add another one, in which you can simply write that access is denied.
Web module feedback
For a web module embedded in the order editing window, you will most likely need a feedback option. For example, if you want to calculate some data in the web module and then return it to the order. If we are talking about one field, it can be simply copied. But it is not uncommon to update entire arrays of order data at once. The most popular example is the integration of the store with PBX, when the script module performs a request to the PBX and having received the answer, should automatically identify and substitute the customer in the order.
For such situations, you will need to use JavaScript to prepare a response and send it to the console, along with a special code word. Let's return to our test module melbis_web_test.php and consider the whole way of working with data. So, since this module is built-in, inside the array $mVars['post']['order'], we'll get a JSON-formatted representation of the order, something like this:
{ "version":[ { "id": "1", "order_id": "44", "user_id":null, "client_id": "515", "date_time": "2019-06-23 20:02:43", "total_sum":"10" } ], "client_field":[ { "id": "1", "version_id": "1", "field_id": "1", "field_skey": "NAME", "field_name": "Name (full name)", "field_tindex":"0", "field_tlevel": "0", "field_absindex": "0", "field_folder": "0", "field_kind_key": "kRequired", "field_spec_key": "kDefault", "value_id":"null", "value_skey":""", "value_code":""", "value_kind_key":""", "value_txt": "Tester" }, { "id": "2", "version_id":"1", "field_id": "2", "field_skey": "COMPANY", "field_name": "Company", "field_tindex": "0", "field_tlevel": "0", "field_absindex":"1", "field_folder": "0", "field_kind_key": "kDefault", "field_spec_key": "kDefault", "value_id":null, "value_skey":""", "value_code":"", "value_kind_key":""", "value_txt": "test" }, { "id": "3", "version_id": "1", "field_id": "3", "field_skey": "EMAIL", "field_name":"Email", "field_tindex": "0", "field_tlevel": "0", "field_absindex": "2", "field_folder": "0", "field_kind_key":"kRequired", "field_spec_key": "kDefault", "value_id":null, "value_skey":""", "value_code":""", "value_kind_key":""", "value_txt":"test@mail.ru" }, { "id": "4", "version_id": "1", "field_id": "4", "field_skey": "PHONE", "field_name": "Phone", "field_tindex":"0", "field_tlevel": "0", "field_absindex": "3", "field_folder": "0", "field_kind_key": "kDefault", "field_spec_key": "kDefault", "value_id":"null", "value_skey":""", "value_code":""", "value_kind_key":""", "value_txt": "+380(50)111-11-11" } ], "store":[ { "id":"1", "version_id": "1", "store_id": "24", "store_provider_id": "2", "store_brand_id": "4", "store_pprice": "0", "store_price": "0", "store_price":"10", "store_price2": "0", "store_price3": "0", "store_how": "1", "store_code_shop": "AMATEUR_START", "store_code_prov":""", "store_code_made":"", "store_meas":""", "store_name": "Start Payment", "store_kind_key": "kLicenseDomain", "store_status_key": "kExist", "store_state_key":"kDefault", "store_min_order": "0", "store_step_order": "0", "recalc": "0", "out_price": "10", "amount": "1", "notice": "myshop.com", "auto_notice": "Calculated", "pos": "1" } ], "store_option":[ ], "option":[ { "id": "1", "version_id": "1", "option_id":"3", "option_skey": "CREATOR", "option_name": "Creator", "option_kind_key": "kDefault", "option_pos": "1", "value_id": "9", "value_skey":"USER", "value_name": "User", "value_kind_key": "kDefault", "value_modify_sum": "0", "value_oper_num": "0", "value_source_num": "0", "notice":"" }, { "id": "2", "version_id": "1", "option_id": "1", "option_skey": "STATUS", "option_name": "Status", "option_kind_key":"kDefault", "option_pos": "2", "value_id": "3", "value_skey": "ABORT", "value_name": "Canceled", "value_kind_key": "kDefault", "value_modify_sum":"0", "value_oper_num": "0", "value_source_num": "0", "notice":"" }, { "id": "3", "version_id": "1", "option_id":"2", "option_skey": "PAYMENT", "option_name": "Payment", "option_kind_key": "kDefault", "option_pos": "3", "value_id": "5", "value_skey":"CARD", "value_name": "LiqPay", "value_kind_key": "kDefault", "value_modify_sum": "0", "value_oper_num": "0", "value_source_num": "0", "notice": "0" } ] } ] }
These are the order tables represented as a JSON object, which we will pass further into the scripts.htm template under the {ORDER} key. Here is the code in the script:
// Order change back demo $order = ( isset($mVars['post']['order']) ) ? $mVars['post']['order'] : '{}'; $gParser->TplAssign($tpl, 'ORDER', $order);
And here is the code in scripts.htm where we define the melbis_order variable:
var melbis_order = {ORDER};
After the user selects the order data edit mode, we run the initiate data function to show the current values of the order table fields:
// Init change back function melbis_init_back() { for ( var table in melbis_order ) { var data = melbis_order[table]; var columns = []; for (var c in data[0]) { columns.push({field: c, title: c}); } $('.melbis_table_order[data-table="' + table + '"]').bootstrapTable({ columns: columns, data: data }); } } }
This generates Bootstrap tables that can be edited on the event of clicking on any cell. The following function is added for this purpose:
// Change field value $('.melbis_table_order').on('click-cell.bs.table', function (event, field, value, row) { var table = event.target.dataset.table; bootbox.prompt({ title: 'Edit value of "' + field +'''', value: value, callback: function (result) { var update = {}; update[table] = []; update[table].push({ id: row.id, [field]: result }); console.log('MELBIS_ORDER_UPDATE' + JSON.stringify(update)); } } }); } });
As you can see, here we are using the bootbox.js component, which creates a prompt request to edit a cell. And when the response is received, we form a JSON array update, which is simply output to the browser console with the console.log command, adding the code word MELBIS_ORDER_UPDATE at the very beginning:
var update = {}; update[table] = []; update[table].push({id: row.id, [field]: result }); console.log('MELBIS_ORDER_UPDATE' + JSON.stringify(update));
Note that it is mandatory to add the id field to uniquely identify how the table row needs to be updated. Therefore, you can easily update an unlimited number of tables and their rows at a time.
Here we can conclude the consideration of web modules. In conclusion, consider this idea. You can use as external web modules and any other sites. Your employees get a ready set of frequently used sites right in the Melbis Shop 6 client environment. For example, they can be sites of the postal service, transportation company, store forum, store group in social networks, etc.