Статьи

От новичка до продвинутого в OpenCart: разработка модулей

В предыдущих статьях мы исследовали архитектуру MVC и создали наш первый контроллер, модель и представление в приложении OpenCart. Мы сделали это, чтобы помочь лучше понять основное приложение.

Чтобы продвинуться дальше, мы рассмотрим создание пользовательского модуля для OpenCart.

Модули OpenCart аналогичны надстройкам, плагинам или расширениям в других системах управления контентом. Именно благодаря модулям OpenCart дает нам возможность расширять свои функциональные возможности без необходимости редактировать файлы приложения.

Как и во многих других системах управления контентом, обычно считается, что рекомендуется расширять функциональность основного приложения с помощью предоставляемых API, и OpenCart ничем не отличается. Модули позволяют нам вводить, удалять или изменять функциональные возможности базового приложения, которые выполняются разделенным и обслуживаемым способом.

OpenCart имеет свой собственный рынок расширений, где уже доступно большое количество расширений. Или вы можете ознакомиться с широким спектром модулей и расширений OpenCart на Envato Market.

Модули и расширения OpenCart на Envato Market
Модули и расширения OpenCart на Envato Market

Если вам нужно выполнить определенную задачу в OpenCart и изо всех сил пытаетесь сделать это самостоятельно, попробуйте заказать один из наиболее ценных сервисов разработки OpenCart в Envato Studio.

Разработчики OpenCart на Envato Studio
Разработка OpenCart на Envato Studio

Чтобы акклиматизироваться с модульной системой OpenCart, мы можем написать обязательный модуль «Hello World». Это будет принимать входные данные из панели управления и отображать его на передней части сайта.

Обратите внимание, что в OpenCart есть несколько готовых модулей. Поэтому мы постараемся использовать их, когда это возможно, работая самостоятельно. Для начала выполните следующее:

  1. Создайте путь от контроллера к администратору: admin/controller/module/helloworld.php .
  2. Создайте языковой файл для пути администратора: admin/language/english/module/helloworld.php .
  3. Создайте путь к представлению администратора: admin/view/template/module/helloworld.tpl .

Как обсуждалось в наших предыдущих статьях, языковой файл содержит статический текст, который должен отображаться в нашем файле представления. Для языкового файла helloworld.php следующие переменные содержат возможные текстовые поля, которые нам необходимо отобразить в нашем модуле:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// Heading
$_[‘heading_title’] = ‘Hello World’;
 
// Text
$_[‘text_module’] = ‘Modules’;
$_[‘text_success’] = ‘Success: You have modified module Hello World!’;
$_[‘text_content_top’] = ‘Content Top’;
$_[‘text_content_bottom’] = ‘Content Bottom’;
$_[‘text_column_left’] = ‘Column Left’;
$_[‘text_column_right’] = ‘Column Right’;
 
// Entry
$_[‘entry_code’] = ‘Hello World Code:’;
$_[‘entry_layout’] = ‘Layout:’;
$_[‘entry_position’] = ‘Position:’;
$_[‘entry_status’] = ‘Status:’;
$_[‘entry_sort_order’] = ‘Sort Order:’;
 
// Error
$_[‘error_permission’] = ‘Warning: You do not have permission to modify module Hello World!’;
$_[‘error_code’] = ‘Code Required’;
?>

Откройте файл контроллера «Hello World», который мы только что создали, и добавьте класс class ControllerModuleHelloworld extends Controller {} соответствии с соглашением об именах классов . Затем поместите следующий код внутри класса.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
private $error = array();
 
public function index() { // Default function
    $this->language->load(‘module/helloworld’);
 
    $this->document->setTitle($this->language->get(‘heading_title’));
 
    $this->load->model(‘setting/setting’);
 
 
 
    if (($this->request->server[‘REQUEST_METHOD’] == ‘POST’) && $this->validate()) { // Start If: Validates and check if data is coming by save (POST) method
        $this->model_setting_setting->editSetting(‘helloworld’, $this->request->post);
 
        $this->session->data[‘success’] = $this->language->get(‘text_success’);
 
        $this->redirect($this->url->link(‘extension/module’, ‘token=’ . $this->session->data[‘token’], ‘SSL’));
    } // End If
 
    /*Assign the language data for parsing it to view*/
    $this->data[‘heading_title’] = $this->language->get(‘heading_title’);
 
    $this->data[‘text_enabled’] = $this->language->get(‘text_enabled’);
    $this->data[‘text_disabled’] = $this->language->get(‘text_disabled’);
    $this->data[‘text_content_top’] = $this->language->get(‘text_content_top’);
    $this->data[‘text_content_bottom’] = $this->language->get(‘text_content_bottom’);
    $this->data[‘text_column_left’] = $this->language->get(‘text_column_left’);
    $this->data[‘text_column_right’] = $this->language->get(‘text_column_right’);
 
    $this->data[‘entry_code’] = $this->language->get(‘entry_code’);
    $this->data[‘entry_layout’] = $this->language->get(‘entry_layout’);
    $this->data[‘entry_position’] = $this->language->get(‘entry_position’);
    $this->data[‘entry_status’] = $this->language->get(‘entry_status’);
    $this->data[‘entry_sort_order’] = $this->language->get(‘entry_sort_order’);
 
    $this->data[‘button_save’] = $this->language->get(‘button_save’);
    $this->data[‘button_cancel’] = $this->language->get(‘button_cancel’);
    $this->data[‘button_add_module’] = $this->language->get(‘button_add_module’);
    $this->data[‘button_remove’] = $this->language->get(‘button_remove’);
     
 
    /*This Block returns the warning if any*/
    if (isset($this->error[‘warning’])) {
        $this->data[‘error_warning’] = $this->error[‘warning’];
    } else {
        $this->data[‘error_warning’] = »;
    }
    /*End Block*/
 
    /*This Block returns the error code if any*/
    if (isset($this->error[‘code’])) {
        $this->data[‘error_code’] = $this->error[‘code’];
    } else {
        $this->data[‘error_code’] = »;
    }
    /*End Block*/
 
 
    /* Making of Breadcrumbs to be displayed on site*/
    $this->data[‘breadcrumbs’] = array();
 
    $this->data[‘breadcrumbs’][] = array(
        ‘text’ => $this->language->get(‘text_home’),
        ‘href’ => $this->url->link(‘common/home’, ‘token=’ . $this->session->data[‘token’], ‘SSL’),
        ‘separator’ => false
    );
 
    $this->data[‘breadcrumbs’][] = array(
        ‘text’ => $this->language->get(‘text_module’),
        ‘href’ => $this->url->link(‘extension/module’, ‘token=’ . $this->session->data[‘token’], ‘SSL’),
        ‘separator’ => ‘ :: ‘
    );
 
    $this->data[‘breadcrumbs’][] = array(
        ‘text’ => $this->language->get(‘heading_title’),
        ‘href’ => $this->url->link(‘module/helloworld’, ‘token=’ . $this->session->data[‘token’], ‘SSL’),
        ‘separator’ => ‘ :: ‘
    );
 
    /* End Breadcrumb Block*/
 
    $this->data[‘action’] = $this->url->link(‘module/helloworld’, ‘token=’ . $this->session->data[‘token’], ‘SSL’);
 
    $this->data[‘cancel’] = $this->url->link(‘extension/module’, ‘token=’ . $this->session->data[‘token’], ‘SSL’);
 
     
    /* This block checks, if the hello world text field is set it parses it to view otherwise get the default hello world text field from the database and parse it*/
 
    if (isset($this->request->post[‘helloworld_text_field’])) {
        $this->data[‘helloworld_text_field’] = $this->request->post[‘helloworld_text_field’];
    } else {
        $this->data[‘helloworld_text_field’] = $this->config->get(‘helloworld_text_field’);
    }
    /* End Block*/
 
    $this->data[‘modules’] = array();
 
    /* This block parses the Module Settings such as Layout, Position,Status & Order Status to the view*/
    if (isset($this->request->post[‘helloworld_module’])) {
        $this->data[‘modules’] = $this->request->post[‘helloworld_module’];
    } elseif ($this->config->get(‘helloworld_module’)) {
        $this->data[‘modules’] = $this->config->get(‘helloworld_module’);
    }
    /* End Block*/
 
    $this->load->model(‘design/layout’);
 
    $this->data[‘layouts’] = $this->model_design_layout->getLayouts();
 
    $this->template = ‘module/helloworld.tpl’;
    $this->children = array(
        ‘common/header’,
        ‘common/footer’
    );
 
    $this->response->setOutput($this->render());
}

Как мы пытались проверить данные о сохранении в функции по умолчанию. Итак, вот и метод проверки.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* Function that validates the data when Save Button is pressed */
   protected function validate() {
 
       /* Block to check the user permission to manipulate the module*/
       if (!$this->user->hasPermission(‘modify’, ‘module/helloworld’)) {
           $this->error[‘warning’] = $this->language->get(‘error_permission’);
       }
       /* End Block*/
 
       /* Block to check if the helloworld_text_field is properly set to save into database, otherwise the error is returned*/
       if (!$this->request->post[‘helloworld_text_field’]) {
           $this->error[‘code’] = $this->language->get(‘error_code’);
       }
       /* End Block*/
 
       /*Block returns true if no error is found, else false if any error detected*/
       if (!$this->error) {
           return true;
       } else {
           return false;
       }
       /* End Block*/
   }
   /* End Validation Function*/

Теперь сохраните файл и все готово с помощью контроллера администратора нашего модуля Hello World!

Как ранее было сделано в контроллере, вы должны создать HTML для представления. Для этого мы сделаем следующее:

form — это элемент, который будет содержать такие элементы, как элемент input текста, textarea и кнопки для сохранения или отмены ввода.

Чтобы создать подобную форму, просмотрите код ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php echo $header;
<div id=»content»>
  <div class=»breadcrumb»>
    <?php foreach ($breadcrumbs as $breadcrumb) { ?>
    <?php echo $breadcrumb[‘separator’];
    <?php } ?>
  </div>
  <?php if ($error_warning) { ?>
  <div class=»warning»><?php echo $error_warning;
  <?php } ?>
  <div class=»box»>
    <div class=»heading»>
      <h1><img src=»view/image/module.png» alt=»» /> <?php echo $heading_title;
      <div class=»buttons»><a onclick=»$(‘#form’).submit();»
    </div>
    <div class=»content»>
      <form action=»<?php echo $action; ?>» method=»post» enctype=»multipart/form-data» id=»form»>
        <table class=»form»>
          <tr>
            <td><span class=»required»>*
            <td><textarea name=»helloworld_text_field» cols=»40″ rows=»5″><?php echo $helloworld_text_field;
              <?php if ($error_code) { ?>
              <span class=»error»><?php echo $error_code;
              <?php } ?></td>
          </tr>
        </table>

Под form появится список table , где мы можем определить положение модуля и страницу, где должен отображаться модуль.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<table id=»module» class=»list»>
          <thead>
            <tr>
              <td class=»left»><?php echo $entry_layout;
              <td class=»left»><?php echo $entry_position;
              <td class=»left»><?php echo $entry_status;
              <td class=»right»><?php echo $entry_sort_order;
              <td></td>
            </tr>
          </thead>
          <?php $module_row = 0;
          <?php foreach ($modules as $module) { ?>
          <tbody id=»module-row<?php echo $module_row; ?>»>
            <tr>
              <td class=»left»><select name=»helloworld_module[<?php echo $module_row; ?>][layout_id]»>
                  <?php foreach ($layouts as $layout) { ?>
                  <?php if ($layout[‘layout_id’] == $module[‘layout_id’]) { ?>
                  <option value=»<?php echo $layout[‘layout_id’]; ?>» selected=»selected»><?php echo $layout[‘name’];
                  <?php } else { ?>
                  <option value=»<?php echo $layout[‘layout_id’]; ?>»><?php echo $layout[‘name’];
                  <?php } ?>
                  <?php } ?>
                </select></td>
              <td class=»left»><select name=»helloworld_module[<?php echo $module_row; ?>][position]»>
                  <?php if ($module[‘position’] == ‘content_top’) { ?>
                  <option value=»content_top» selected=»selected»><?php echo $text_content_top;
                  <?php } else { ?>
                  <option value=»content_top»><?php echo $text_content_top;
                  <?php } ?>
                  <?php if ($module[‘position’] == ‘content_bottom’) { ?>
                  <option value=»content_bottom» selected=»selected»><?php echo $text_content_bottom;
                  <?php } else { ?>
                  <option value=»content_bottom»><?php echo $text_content_bottom;
                  <?php } ?>
                  <?php if ($module[‘position’] == ‘column_left’) { ?>
                  <option value=»column_left» selected=»selected»><?php echo $text_column_left;
                  <?php } else { ?>
                  <option value=»column_left»><?php echo $text_column_left;
                  <?php } ?>
                  <?php if ($module[‘position’] == ‘column_right’) { ?>
                  <option value=»column_right» selected=»selected»><?php echo $text_column_right;
                  <?php } else { ?>
                  <option value=»column_right»><?php echo $text_column_right;
                  <?php } ?>
                </select></td>
              <td class=»left»><select name=»helloworld_module[<?php echo $module_row; ?>][status]»>
                  <?php if ($module[‘status’]) { ?>
                  <option value=»1″ selected=»selected»><?php echo $text_enabled;
                  <option value=»0″><?php echo $text_disabled;
                  <?php } else { ?>
                  <option value=»1″><?php echo $text_enabled;
                  <option value=»0″ selected=»selected»><?php echo $text_disabled;
                  <?php } ?>
                </select></td>
              <td class=»right»><input type=»text» name=»helloworld_module[<?php echo $module_row; ?>][sort_order]» value=»<?php echo $module[‘sort_order’]; ?>» size=»3″ /></td>
              <td class=»left»><a onclick=»$(‘#module-row<?php echo $module_row; ?>’).remove();»
            </tr>
          </tbody>
          <?php $module_row++;
          <?php } ?>
          <tfoot>
            <tr>
              <td colspan=»4″></td>
              <td class=»left»><a onclick=»addModule();»
            </tr>
          </tfoot>
        </table>
      </form>
    </div>
  </div>
</div>

Как вы можете видеть на предыдущем шаге, есть кнопка «Добавить модуль». В частности, у нас есть: <a onclick="addModule();" class="button"><?php echo $button_add_module; ?></a> <a onclick="addModule();" class="button"><?php echo $button_add_module; ?></a> <a onclick="addModule();" class="button"><?php echo $button_add_module; ?></a> где пользователь может добавить несколько строк, чтобы отобразить выходные данные модуля в разных макетах на разных позициях.

Для этого нам нужно написать JavaScript, который добавит строку в список таблиц. Это улучшит пользовательский интерфейс для тех, кто использует наш модуль:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script type=»text/javascript»><!—
var module_row = <?php echo $module_row;
 
function addModule() {
    html = ‘<tbody id=»module-row’ + module_row + ‘»>’;
    html += ‘ <tr>’;
    html += ‘ <td class=»left»><select name=»helloworld_module[‘ + module_row + ‘][layout_id]»>’;
    <?php foreach ($layouts as $layout) { ?>
    html += ‘ <option value=»<?php echo $layout[‘layout_id’]; ?>»><?php echo addslashes($layout[‘name’]);
    <?php } ?>
    html += ‘ </select></td>’;
    html += ‘ <td class=»left»><select name=»helloworld_module[‘ + module_row + ‘][position]»>’;
    html += ‘ <option value=»content_top»><?php echo $text_content_top;
    html += ‘ <option value=»content_bottom»><?php echo $text_content_bottom;
    html += ‘ <option value=»column_left»><?php echo $text_column_left;
    html += ‘ <option value=»column_right»><?php echo $text_column_right;
    html += ‘ </select></td>’;
    html += ‘ <td class=»left»><select name=»helloworld_module[‘ + module_row + ‘][status]»>’;
    html += ‘ <option value=»1″ selected=»selected»><?php echo $text_enabled;
    html += ‘ <option value=»0″><?php echo $text_disabled;
    html += ‘ </select></td>’;
    html += ‘ <td class=»right»><input type=»text» name=»helloworld_module[‘ + module_row + ‘][sort_order]» value=»» size=»3″ /></td>’;
    html += ‘ <td class=»left»><a onclick=»$(\’#module-row’ + module_row + ‘\’).remove();»
    html += ‘ </tr>’;
    html += ‘</tbody>’;
     
    $(‘#module tfoot’).before(html);
     
    module_row++;
}
//—></script>

Последнее, что нам нужно добавить нижний колонтитул в конце представления:

1
<?php echo $footer;

На этом мы закончили подготовку нашего первого модуля Hello World . На данный момент, пришло время проверить, работает ли наш модуль или нет.

Для этого войдите в панель управления и перейдите на страницу «Расширения> Модули», где вы увидите список модулей OpenCart System. Там также будет «Hello World» в списке с «Uninstalled» State, нажмите «Install» и попробуйте отредактировать модуль, и вы увидите на экране что-то вроде этого:

Вы можете ввести какое-то случайное значение и попытаться сохранить его. Теперь попробуйте снова отредактировать модуль, и вы увидите, что ввод введен по умолчанию.

В этой статье мы попытались построить базовый модуль OpenCart с использованием MVC. Модули OpenCart легко манипулировать, если вы знакомы с основными понятиями MVC. Эта статья дает базовую идею о том, как разработать простой модуль, выполнив несколько простых шагов.

В нашей следующей статье мы будем работать с внешним интерфейсом и попытаемся расширить его для внешнего интерфейса магазина. Пожалуйста, оставьте свой отзыв в комментариях ниже!