Opencart 1.5.x - Создаем Модуль

Тема в разделе "Модули и дополнения", создана пользователем admin, 6 ноя 2016.

  1. TopicStarter Overlay
    Offline

    admin Команда форума Администратор

    Сообщения:
    2.054
    Симпатии:
    52.024
    Репутация:
    148
    В данном посте я дам вам минимум информации, которой хватит для создания своего модуля для системы OpenCart 1.5.x

    Ничего лишнего, итак приступим …

    Для того что бы создать свой первый модуль, нам необходимо как минимум 6 файлов. Пускайнаш новый модуль будет иметь название «myModul» и для его работы нам понадобятся следующие файлы:

    1. файл представления модуля:
      catalog\view\theme\default\template\module\myModul.tpl
    2. контроллер модуля:
      catalog\controller\module\myModul.php
    3. языковой файл:
      catalog\language\russian\module\myModul.php
    4. файл представления модуля для админ панели:
      admin\view\template\module\myModul.tpl
    5. контроллер модуля для админ панели:
      admin\controller\module\myModul.php
    6. языковой файл модуля для админ панели:
      admin\language\russian\module\myModul.php
    Создавать мы их будем в порядке нумерации.

    1. Файл представления

    Создадим catalog\view\theme\default\template\module\myModul.tpl, и наполним его следующим содержимым:

    Код:
    <div class="box">
    <div class="box-heading"><?phpecho$heading_title;?></div>
    <div class="box-content">
    код модуля
    </div>
    </div>
    Это базовая структура модулей для CMS OpenCart, вы можете написать любую свою.

    Если оставить данный код без изменений, то наш модуль будет выглядеть так:

    1.jpg

    2. Контроллер модуля


    Аналогично, создаем catalog\controller\module\myModul.php и наполняем его следующим минимум:



    Код:
    <?php
    classControllerModuleMyModulextendsController{
    protectedfunctionindex(){
    
    if(file_exists(DIR_TEMPLATE.$this->config->get('config_template').'/template/module/myModul.tpl')){
    $this->template=$this->config->get('config_template').'/template/module/myModul.tpl';
    }else{
    $this->template='default/template/module/myModul.tpl';
    }
    $this->render();
    }
    }
    ?>
    Заметьте название класса «ControllerModuleMyModul» это строка «ControllerModule» плюс «имя модуля с большой буквы». В контроллере мы как минимум должны, указать какой файл представления будет отвечать за вывод информации. Но данный контроллер не функционален, это всего лишь заготовка. Функционалом он будет заполняться в зависимости от потребностей модуля.

    Как пример, в нем вы можете подключать модель:

    Код:
    $this->load->model('директория_с_моделью/имя_модели');
    и далее вызывать ее методы.

    Также можно подключать языковой файл:

    Код:
    $this->language->load('module/имя_языкового_файла');
    и объявлять переменные:

    Код:
    $this->data['имя_переменной']=$this->language->get('имя_переменной_из_яз_файла');
    Данная переменная будет видна в шаблоне myModul.tpl.

    3. Языковой файл

    Создаем catalog\language\russian\module\myModul.php и наполняем его следующим содержимым:

    Код:
    <?php
    $_['имя_переменной']='значение переменной';
    ?>
    Мы можем работать с данной переменной, только в том случае если в контроллере объявим:

    Код:
    $this->language->load('module/myModul');
    обращаться к ней следует так

    Код:
    $this->language->get('имя_переменной');
    В общем наполняем языковой файл переменными, которые будут хранить текстовую информацию, необходимую для нашего модуля. Это может быть строка «Заголовок», например:

    2.jpg


    4. Файл представления модуля для админ панели

    Создаем admin\view\template\module\myModul.tpl и наполняем его следующим содержимым:

    Код:
    <?phpecho$header;?>[/B]
    [B]<div id="content">
    <div class="breadcrumb">
    <?phpforeach($breadcrumbsas$breadcrumb){?>
    <?phpecho$breadcrumb['separator'];?><a href="<?phpecho$breadcrumb['href'];?>"><?phpecho$breadcrumb['text'];?></a>
    <?php}?>
    </div>
    <?phpif($error_warning){?>
    <div class="warning"><?phpecho$error_warning;?></div>
    <?php}?>
    <div class="box">
    <div class="heading">
    <h1><img src="view/image/module.png"alt="" /> <?phpecho$heading_title;?></h1>
    <div class="buttons"><a onclick="$('#form').submit();"class="button"><?phpecho$button_save;?></a><a onclick="location = '<?phpecho$cancel;?>';"class="button"><?phpecho$button_cancel;?></a></div>
    </div>
    <div class="content">
    <form action="<?phpecho$action;?>"method="post"enctype="multipart/form-data"id="form">
    <table id="module"class="list">
    <thead>
    <tr>
    <td class="left"><?phpecho$entry_layout;?></td>
    <td class="left"><?phpecho$entry_position;?></td>
    <td class="left"><?phpecho$entry_status;?></td>
    <td class="right"><?phpecho$entry_sort_order;?></td>
    <td></td>
    </tr>
    </thead>
    <?php$module_row=0;?>
    <?phpforeach($modulesas$module){?>
    <tbody id="module-row<?phpecho$module_row;?>">
    <tr>
    <td class="left"><select name="myModul_module[<?phpecho$module_row;?>][layout_id]">
    <?phpforeach($layoutsas$layout){?>
    <?phpif($layout['layout_id']==$module['layout_id']){?>
    <option value="<?phpecho$layout['layout_id'];?>"selected="selected"><?phpecho$layout['name'];?></option>
    <?php}else{?>
    <option value="<?phpecho$layout['layout_id'];?>"><?phpecho$layout['name'];?></option>
    <?php}?>
    <?php}?>
    </select></td>
    <td class="left"><select name="myModul_module[<?phpecho$module_row;?>][position]">
    <?phpif($module['position']=='content_top'){?>
    <option value="content_top"selected="selected"><?phpecho$text_content_top;?></option>
    <?php}else{?>
    <option value="content_top"><?phpecho$text_content_top;?></option>
    <?php}?>
    <?phpif($module['position']=='content_bottom'){?>
    <option value="content_bottom"selected="selected"><?phpecho$text_content_bottom;?></option>
    <?php}else{?>
    <option value="content_bottom"><?phpecho$text_content_bottom;?></option>
    <?php}?>
    <?phpif($module['position']=='column_left'){?>
    <option value="column_left"selected="selected"><?phpecho$text_column_left;?></option>
    <?php}else{?>
    <option value="column_left"><?phpecho$text_column_left;?></option>
    <?php}?>
    <?phpif($module['position']=='column_right'){?>
    <option value="column_right"selected="selected"><?phpecho$text_column_right;?></option>
    <?php}else{?>
    <option value="column_right"><?phpecho$text_column_right;?></option>
    <?php}?>
    </select></td>
    <td class="left"><select name="myModul_module[<?phpecho$module_row;?>][status]">
    <?phpif($module['status']){?>
    <option value="1"selected="selected"><?phpecho$text_enabled;?></option>
    <option value="0"><?phpecho$text_disabled;?></option>
    <?php}else{?>
    <option value="1"><?phpecho$text_enabled;?></option>
    <option value="0"selected="selected"><?phpecho$text_disabled;?></option>
    <?php}?>
    </select></td>
    <td class="right"><input type="text"name="myModul_module[<?phpecho$module_row;?>][sort_order]"value="<?phpecho$module['sort_order'];?>"size="3" /></td>
    <td class="left"><a onclick="$('#module-row<?phpecho$module_row;?>').remove();"class="button"><?phpecho$button_remove;?></a></td>
    </tr>
    </tbody>
    <?php$module_row++;?>
    <?php}?>
    <tfoot>
    <tr>
    <td colspan="4"></td>
    <td class="left"><a onclick="addModule();"class="button"><?phpecho$button_add_module;?></a></td>
    </tr>
    </tfoot>
    </table>
    </form>
    </div>
    </div>
    </div>
    <script type="text/javascript"><!--
    varmodule_row=<?php echo$module_row;?>;
    
    functionaddModule(){
    html='<tbody id="module-row'+module_row+'">';
    html+=' <tr>';
    html+=' <td class="left"><select name="myModul_module['+module_row+'][layout_id]">';
    <?php foreach($layouts as$layout){?>
    html+=' <option value="<?php echo $layout['layout_id']; ?>"><?php echo addslashes($layout['name']); ?></option>';
    <?php}?>
    html+=' </select></td>';
    html+=' <td class="left"><select name="myModul_module['+module_row+'][position]">';
    html+=' <option value="content_top"><?php echo $text_content_top; ?></option>';
    html+=' <option value="content_bottom"><?php echo $text_content_bottom; ?></option>';
    html+=' <option value="column_left"><?php echo $text_column_left; ?></option>';
    html+=' <option value="column_right"><?php echo $text_column_right; ?></option>';
    html+=' </select></td>';
    html+=' <td class="left"><select name="myModul_module['+module_row+'][status]">';
    html+=' <option value="1" selected="selected"><?php echo $text_enabled; ?></option>';
    html+=' <option value="0"><?php echo $text_disabled; ?></option>';
    html+=' </select></td>';
    html+=' <td class="right"><input type="text" name="myModul_module['+module_row+'][sort_order]" value="" size="3" /></td>';
    html+=' <td class="left"><a onclick="$(\'#module-row'+module_row+'\').remove();" class="button"><?php echo $button_remove; ?></a></td>';
    html+=' </tr>';
    html+='</tbody>';
    
    $('#module tfoot').before(html);
    
    module_row++;
    }
    //--></script>
    <?phpecho$footer;?>


    Данный код был взят из файла представления для модуля «Информация» (admin\view\template\module\information.tpl), я заменил только «information» на «myModul».

    Данный код отображает следующие возможности в админпанели по настройки модуля:

    3.jpg

    Файл представления для админпанели, вы можете наполнить своим содержимым. Я представил этот пример только из-за того, что он хорошо предоставляет минимальные настройки для модуля (т.е. выбор схемы и положения модуля).

    5. Контролер модуля для админ панели


    Создаем admin\controller\module\myModul.php и наполняем его содержимым контроллера модуля которого мы брали в качестве образца.

    Например, наполним его содержимым контроллера модуля «Информация» (controller\module\information.php).

    Код:
    <?php[/B]
    [B]classControllerModuleMyModulextendsController{
    private$error=array();
    
    publicfunctionindex(){
    $this->load->language('module/myModul');
    $this->document->setTitle($this->language->get('heading_title'));
    $this->load->model('setting/setting');
    
    if(($this->request->server['REQUEST_METHOD']=='POST')&&$this->validate()){
    $this->model_setting_setting->editSetting('myModul',$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'));
    }
    
    $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_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');
    
    if(isset($this->error['warning'])){
    $this->data['error_warning']=$this->error['warning'];
    }else{
    $this->data['error_warning']='';
    }
    
         $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/myModul','token='.$this->session->data['token'],'SSL'),
         'separator'=>' :: '
      );
    
    $this->data['action']=$this->url->link('module/myModul','token='.$this->session->data['token'],'SSL');
    
    $this->data['cancel']=$this->url->link('extension/module','token='.$this->session->data['token'],'SSL');
    
    $this->data['modules']=array();
    
    if(isset($this->request->post['myModul_module'])){
    $this->data['modules']=$this->request->post['myModul_module'];
    }elseif($this->config->get('myModul_module')){
    $this->data['modules']=$this->config->get('myModul_module');
    }
    $this->load->model('design/layout');
    
    $this->data['layouts']=$this->model_design_layout->getLayouts();
    
    $this->template='module/myModul.tpl';
    $this->children=array(
    'common/header',
    'common/footer'
    );
    $this->response->setOutput($this->render());
    }
    
    privatefunctionvalidate(){
    if(!$this->user->hasPermission('modify','module/myModul')){
    $this->error['warning']=$this->language->get('error_permission');
    }
    
    if(!$this->error){
    returntrue;
    }else{
    returnfalse;
    }
    }
    }
    ?>


    Единственное что я здесь изменил по отношению к оригинальному файлу, так это то, что произвел замену в имени класса с «ControllerModuleInformation» на «ControllerModuleMyModul» и все упоминания слова «information» заменил на «myModul».

    Каков ваш контроллер, будет зависеть от предоставляемого функционала настроек, который предлагает ваш файл представления для админ панели (т.е. «admin\view\template\module\myModul.tpl»).

    6. Языковой файл модуля для админ панели


    Создаем admin\language\russian\module\myModul.php, наполняем его:

    Код:
    <?php[/B]
    [B]// Heading
    $_['heading_title']  ='myModul';
    
    // Text
    $_['text_module']  ='Модули';
    $_['text_success']='Настройки модуля обновлены!';
    $_['text_content_top']='Верх страницы';
    $_['text_content_bottom']='Низ страницы';
    $_['text_column_left']='Левая колонка';
    $_['text_column_right']  ='Правая колонка';
    
    // Entry
    $_['entry_layout']='Схема:';
    $_['entry_position']='Расположение:';
    $_['entry_status']='Статус:';
    $_['entry_sort_order']='Порядок сортировки:';
    
    // Error
    $_['error_permission']='У Вас нет прав для управления этим модулем!';
    ?>


    Содержимое данного файла, я опять таки взял из образца для модуля «Информация». Тут главное определиться с содержимым переменных, который использует ваш файл представления для админ панели (admin\view\template\module\myModul.tpl).

    Итог
    Теперь если вы зайдете в Дополнения->Модули вы обнаружите модуль «myModul», с ним можно работать как с любым другим модулем, его можно устанавливать/удалять, определять положение на странице и т.п.

    Добавлено позже

    Со временем у меня возник вопрос :

    — А как добавить в настройках моего модуля свои параметры?

    Например я хочу что-бы в настройках модуля был «мой параметр»

    module_my_options.jpg

    И он был виден в tpl файле модуля.

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

    Механизм работы

    Сначала, рассмотрим каков механизм работы

    Когда в настройках модуля вы нажимаете на «SAVE” или “Сохранить”, вы тем самым посылаете POSTзапрос в контролер модуля в админки (т. е. в файл www\admin\controller\module\имя_модуля.php). Он принимает его и записывает в БД, а точнее в таблицу «префикс_setting«. Где в отведенной строке для вашего модуля будут сохранены настройки в виде «ключа: значения«.

    Поподробнее..

    В tpl шаблоне админки модуля (т. е. в файле www\admin\view\template\module\filterattr.tpl) все настройки которые вы вводите, это значения тегов input, select и т. п., которые находятся в форме:

    Код:
    <form action="<?phpecho$action;?>"method="post"enctype="multipart/form-data"id="form">


    При нажатие на «Сохранить», вы просто посылаете POST запрос на <?php echo $action; ?> (адрес контроллера модуля в админке, т. е. на файл www\admin\controller\module\имя_модуля.php) с значениями из формы.

    Тем самым контроллер модуля в админке принимает этот запрос с помощью функции editSetting(‘имя_модуля’, $this->request->post) модели setting/setting‘.

    Кусок кода в контроллере модуля в админки отвечающий за прием POST запросов выглядит так

    Код:
    $this->load->model('setting/setting');[/B]
    [B]
    if(($this->request->server['REQUEST_METHOD']=='POST')&&$this->validate()){
    $this->model_setting_setting->editSetting('имя_модуля',$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'));
    }


    Функция «editSetting» принимает параметры из формы и записывает в БД, в таблицу с именем префикс_setting в строку с столбцом group с именем модуля.

    Например, для модуля «baner» в phpmyadmin строка с его параметрами будет выглядеть так

    module_my_options_example.jpg

    Параметры хранятся в столбце value данной строки, для модуля banner они следующие:
    Код:
    a:1:{[/B]
    [B]i:0;
    a:7:{
    s:9:"banner_id";
    s:1:"6";
    s:5:"width";
    s:3:"200";
    s:6:"height";
    s:3:"182";
    s:9:"layout_id";
    s:1:"3";
    s:8:"position";
    s:11:"column_left";
    s:6:"status";
    s:1:"1";
    s:10:"sort_order";
    s:1:"3";}
    }


    Здесь приведен список параметров с значениями, хотя выглядит немного не логичным.

    Сначала пишется параметр в кавычках, далее в кавычках его значение. Например параметр “width” имеем значение «200». Итак, где хранятся параметры и как они туда попадают разобрались.

    Теперь разберемся как модуль их получает при выводе своего шаблона на страницу

    В контроллере модуля (не админском контроллере модуля), т.е. в файле «www\catalog\controller\module\имя_файла.php» всегда присутствует функция

    Код:
    protectedfunctionindex(){[/B]
    [B]...
    }


    Она вызывается когда к модулю происходит запрос, т. е. в любом том случае когда его надо вывести.

    Когда нам нужно передать параметры из админки модуля в сам модуль, нам нужно указать в качестве аргумента данной функции переменную «$setting», т.е. должно быть:

    Код:
    protectedfunctionindex($setting){[/B]
    [B]…
    }


    $setting это массив с ключами, например если вам нужно получить значение параметра “width”, вы обращаетесь к массиву так
    $setting[‘width’]

    Решение по шагам

    1. Добавим в админский tpl шаблон (т. е. в файл www\admin\view\template\module\имя_модуля.tpl) нашего модуля в тело формы

    Код:
    <form action=»<?php echo $action; ?>» method=»post» enctype=»multipart/form-data» id=»form»>


    следующий тэг:

    Код:
    <td class="left">[/B]
    [B]<input type="text"name="имямодуля_module[0][param1]"value="123"size="3">
    </td>


    Где «имямодуля_module[0][param1]» обязательный формат, здесь “param1” — имя параметра.
    value – значение параметра по умолчанию (можно оставить пустым)

    Что бы не поехала шапка таблицы настроек в админке, можете добавить столбец в первый <tr>

    Например такой

    Код:
    <td class="left">Мой параметр</td>


    Теперь в админка модуля будет выглядеть так

    module_my_options (1).jpg

    Внизу tpl шаблона, есть JavaScript функция function addModule(), добавьте данную <td> в код, это нужно для того что-бы пользователь мог добавить новый модуль на другие страницы (схемы в терминологии OpenCart).

    2. В админском контроллере модуля (т. е. в файле www\admin\controller\module\имя_модуля.php) нужно обязательно добавить следующий код

    Код:
    $this->load->model('setting/setting');[/B]
    [B]
    if(($this->request->server['REQUEST_METHOD']=='POST')&&$this->validate()){
    $this->model_setting_setting->editSetting('имя_модуля',$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'));
    }


    Он означает что POST запросы для данного модуля нужно обрабатывать и заносить в БД.

    Данный код скорее всего уже есть в контроллере вашего модуля, поэтому идем дальше.

    3. В контролере модуля (т. е. в файле www\catalog\controller\module\имя_модуля.php)

    Добавить аргумент $setting в функцию

    Код:
    protectedfunctionindex(){[/B]
    [B]...
    }


    Т.е. должно стать так

    Код:
    protectedfunctionindex($setting){[/B]
    [B]...
    }


    Далее, в любом месте контроллера добавить

    Код:
    $this->data['param1']=$setting["param1"];


    Это позволит, шаблону tpl данного модуля использовать данный параметр, виден он будет под именем «param1».

    4. Теперь в tpl шаблоне модуля (т. е. в файле www\catalog\view\theme\default\template\module\filterattr.tpl) мы можем использовать данный параметр как нам нужно, например выведем его значение:

    Код:
    <?phpecho$param1;?>


    Результат будет:
    123
     
    Skyer нравится это.
  2. Offline

    Kostroma-Andrey Пользователь

    Сообщения:
    164
    Симпатии:
    61
    Репутация:
    1
    Спасибо админу за статью, только что то картинки не работают.
    Хотелось бы еще посмотреть материал для написания 2х версии.
     
    admin нравится это.