OpenCart Tutorial: Customizing Shipping Methods (Part 1)
While the core of OpenCart itself provides many useful shipping methods, there is always the possibility that you will need to create your own. On the other hand, as a web developer, you will always try to explore the framework of your choice to understand how to create your own custom content!
In this series, we will create a custom shipping method module in OpenCart. This will be a two-part series, in the first part we will create a backend configuration form for a custom shipping method.
To create a new custom shipping method in OpenCart, you need to implement files according to OpenCart's conventions. On the backend, you need to provide a configuration form that allows administrators to configure prices, geographical areas, and other parameters related to shipping methods. On the front end, you will implement the files needed to select your custom shipping method at checkout!
Today, we will complete the backend setup. I assume you are using the latest version of OpenCart. In the second part, we will explore the front-end counterpart, where we will see the front-end file setup and front-end demo.
Backend file settings overview
Let's start with the list of files required by the backend. We will use "custom" as the name of the custom shipping method.
-
admin/controller/shipping/custom.php
: This is a controller file where we will set everything we need to configure the form. -
admin/language/english/shipping/custom.php
: This is a language file where we will define the tags of the form. -
admin/view/template/shipping/custom.tpl
: This is a view template file that contains the HTML code for our configuration form.
This is what the backend setup looks like.
File settings
Let's start with the controller settings.
Create controller file
Create the file admin/controller/shipping/custom.php
and paste the following content into the file.
<?php class ControllerShippingCustom extends Controller { private $error = array(); public function index() { $this->load->language('shipping/custom'); $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('custom', $this->request->post); $this->session->data['success'] = $this->language->get('text_success'); $this->response->redirect($this->url->link('extension/shipping', 'token=' . $this->session->data['token'], 'SSL')); } $data['heading_title'] = $this->language->get('heading_title'); $data['text_edit'] = $this->language->get('text_edit'); $data['text_enabled'] = $this->language->get('text_enabled'); $data['text_disabled'] = $this->language->get('text_disabled'); $data['text_all_zones'] = $this->language->get('text_all_zones'); $data['text_none'] = $this->language->get('text_none'); $data['entry_cost'] = $this->language->get('entry_cost'); $data['entry_tax_class'] = $this->language->get('entry_tax_class'); $data['entry_geo_zone'] = $this->language->get('entry_geo_zone'); $data['entry_status'] = $this->language->get('entry_status'); $data['entry_sort_order'] = $this->language->get('entry_sort_order'); $data['button_save'] = $this->language->get('button_save'); $data['button_cancel'] = $this->language->get('button_cancel'); if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } $data['breadcrumbs'] = array(); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], 'SSL') ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_shipping'), 'href' => $this->url->link('extension/shipping', 'token=' . $this->session->data['token'], 'SSL') ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title'), 'href' => $this->url->link('shipping/custom', 'token=' . $this->session->data['token'], 'SSL') ); $data['action'] = $this->url->link('shipping/custom', 'token=' . $this->session->data['token'], 'SSL'); $data['cancel'] = $this->url->link('extension/shipping', 'token=' . $this->session->data['token'], 'SSL'); if (isset($this->request->post['custom_cost'])) { $data['custom_cost'] = $this->request->post['custom_cost']; } else { $data['custom_cost'] = $this->config->get('custom_cost'); } if (isset($this->request->post['custom_tax_class_id'])) { $data['custom_tax_class_id'] = $this->request->post['custom_tax_class_id']; } else { $data['custom_tax_class_id'] = $this->config->get('custom_tax_class_id'); } if (isset($this->request->post['custom_geo_zone_id'])) { $data['custom_geo_zone_id'] = $this->request->post['custom_geo_zone_id']; } else { $data['custom_geo_zone_id'] = $this->config->get('custom_geo_zone_id'); } if (isset($this->request->post['custom_status'])) { $data['custom_status'] = $this->request->post['custom_status']; } else { $data['custom_status'] = $this->config->get('custom_status'); } if (isset($this->request->post['custom_sort_order'])) { $data['custom_sort_order'] = $this->request->post['custom_sort_order']; } else { $data['custom_sort_order'] = $this->config->get('custom_sort_order'); } $this->load->model('localisation/tax_class'); $data['tax_classes'] = $this->model_localisation_tax_class->getTaxClasses(); $this->load->model('localisation/geo_zone'); $data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones(); $data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); $this->response->setOutput($this->load->view('shipping/custom.tpl', $data)); } protected function validate() { if (!$this->user->hasPermission('modify', 'shipping/custom')) { $this->error['warning'] = $this->language->get('error_permission'); } return !$this->error; } }
This is an important file that defines most of the logic of the backend configuration form. We'll go through the important snippets in the controller's index
method. By convention, you need to define the class name ControllerShippingCustom
.
In the index
method, we first load the language file and set the page title.
Next, we load the setting
model and save the settings to the database as POST data for the configuration form. Before saving the data, we validate the form using the validate
method defined in the file.
$this->load->model('setting/setting'); if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { $this->model_setting_setting->editSetting('custom', $this->request->post); $this->session->data['success'] = $this->language->get('text_success'); $this->response->redirect($this->url->link('extension/shipping', 'token=' . $this->session->data['token'], 'SSL')); }
After that, we assign the language tags into the $data
array so that we can access these tags in the view template file.
Next, there is a standard snippet to set up the correct breadcrumb link.
$data['breadcrumbs'] = array(); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], 'SSL') ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_shipping'), 'href' => $this->url->link('extension/shipping', 'token=' . $this->session->data['token'], 'SSL') ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title'), 'href' => $this->url->link('shipping/custom', 'token=' . $this->session->data['token'], 'SSL') );
Next, we set the action
variable to ensure the form is submitted to our index
method. Likewise, if the user clicks the Cancel
button, they will be returned to the list of shipping methods.
$data['action'] = $this->url->link('shipping/custom', 'token=' . $this->session->data['token'], 'SSL'); $data['cancel'] = $this->url->link('extension/shipping', 'token=' . $this->session->data['token'], 'SSL');
Additionally, there is code to populate default values for configuration form fields in add or edit mode.
if (isset($this->request->post['custom_cost'])) { $data['custom_cost'] = $this->request->post['custom_cost']; } else { $data['custom_cost'] = $this->config->get('custom_cost'); } if (isset($this->request->post['custom_tax_class_id'])) { $data['custom_tax_class_id'] = $this->request->post['custom_tax_class_id']; } else { $data['custom_tax_class_id'] = $this->config->get('custom_tax_class_id'); } if (isset($this->request->post['custom_geo_zone_id'])) { $data['custom_geo_zone_id'] = $this->request->post['custom_geo_zone_id']; } else { $data['custom_geo_zone_id'] = $this->config->get('custom_geo_zone_id'); } if (isset($this->request->post['custom_status'])) { $data['custom_status'] = $this->request->post['custom_status']; } else { $data['custom_status'] = $this->config->get('custom_status'); } if (isset($this->request->post['custom_sort_order'])) { $data['custom_sort_order'] = $this->request->post['custom_sort_order']; } else { $data['custom_sort_order'] = $this->config->get('custom_sort_order'); }
In the next section, we load tax classes and geographic areas from the database, which data will be used as drop-down options in the configuration form.
$this->load->model('localisation/tax_class'); $data['tax_classes'] = $this->model_localisation_tax_class->getTaxClasses(); $this->load->model('localisation/geo_zone'); $data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones();
Finally, we assign the view's subtemplate and main template.
$data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer'); $this->response->setOutput($this->load->view('shipping/custom.tpl', $data));
Create language file
Create the file admin/language/english/shipping/custom.php
and paste the following content into the file.
<?php // Heading $_['heading_title'] = 'Custom Rate'; // Text $_['text_shipping'] = 'Shipping'; $_['text_success'] = 'Success: You have modified custom rate shipping!'; $_['text_edit'] = 'Edit Custom Rate Shipping'; // Entry $_['entry_cost'] = 'Cost'; $_['entry_tax_class'] = 'Tax Class'; $_['entry_geo_zone'] = 'Geo Zone'; $_['entry_status'] = 'Status'; $_['entry_sort_order'] = 'Sort Order'; // Error $_['error_permission'] = 'Warning: You do not have permission to modify custom rate shipping!';
The contents of the file should be self-explanatory!
Create view file
Create the file admin/view/template/shipping/custom.
and paste the following content into the file.
<?php echo $header; ?><?php echo $column_left; ?> <div id="content"> <div class="page-header"> <div class="container-fluid"> <div class="pull-right"> <button type="submit" form="form-custom" data-toggle="tooltip" title="<?php echo $button_save; ?>" class="btn btn-primary"><i class="fa fa-save"></i></button> <a href="<?php echo $cancel; ?>" data-toggle="tooltip" title="<?php echo $button_cancel; ?>" class="btn btn-default"><i class="fa fa-reply"></i></a></div> <h1><?php echo $heading_title; ?></h1> <ul class="breadcrumb"> <?php foreach ($breadcrumbs as $breadcrumb) { ?> <li><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a></li> <?php } ?> </ul> </div> </div> <div class="container-fluid"> <?php if ($error_warning) { ?> <div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?> <button type="button" class="close" data-dismiss="alert">×</button> </div> <?php } ?> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title"><i class="fa fa-pencil"></i> <?php echo $text_edit; ?></h3> </div> <div class="panel-body"> <form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-custom" class="form-horizontal"> <div class="form-group"> <label class="col-sm-2 control-label" for="input-cost"><?php echo $entry_cost; ?></label> <div class="col-sm-10"> <input type="text" name="custom_cost" value="<?php echo $custom_cost; ?>" placeholder="<?php echo $entry_cost; ?>" id="input-cost" class="form-control" /> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label" for="input-tax-class"><?php echo $entry_tax_class; ?></label> <div class="col-sm-10"> <select name="custom_tax_class_id" id="input-tax-class" class="form-control"> <option value="0"><?php echo $text_none; ?></option> <?php foreach ($tax_classes as $tax_class) { ?> <?php if ($tax_class['tax_class_id'] == $custom_tax_class_id) { ?> <option value="<?php echo $tax_class['tax_class_id']; ?>" selected="selected"><?php echo $tax_class['title']; ?></option> <?php } else { ?> <option value="<?php echo $tax_class['tax_class_id']; ?>"><?php echo $tax_class['title']; ?></option> <?php } ?> <?php } ?> </select> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label" for="input-geo-zone"><?php echo $entry_geo_zone; ?></label> <div class="col-sm-10"> <select name="custom_geo_zone_id" id="input-geo-zone" class="form-control"> <option value="0"><?php echo $text_all_zones; ?></option> <?php foreach ($geo_zones as $geo_zone) { ?> <?php if ($geo_zone['geo_zone_id'] == $custom_geo_zone_id) { ?> <option value="<?php echo $geo_zone['geo_zone_id']; ?>" selected="selected"><?php echo $geo_zone['name']; ?></option> <?php } else { ?> <option value="<?php echo $geo_zone['geo_zone_id']; ?>"><?php echo $geo_zone['name']; ?></option> <?php } ?> <?php } ?> </select> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label" for="input-status"><?php echo $entry_status; ?></label> <div class="col-sm-10"> <select name="custom_status" id="input-status" class="form-control"> <?php if ($custom_status) { ?> <option value="1" selected="selected"><?php echo $text_enabled; ?></option> <option value="0"><?php echo $text_disabled; ?></option> <?php } else { ?> <option value="1"><?php echo $text_enabled; ?></option> <option value="0" selected="selected"><?php echo $text_disabled; ?></option> <?php } ?> </select> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label" for="input-sort-order"><?php echo $entry_sort_order; ?></label> <div class="col-sm-10"> <input type="text" name="custom_sort_order" value="<?php echo $custom_sort_order; ?>" placeholder="<?php echo $entry_sort_order; ?>" id="input-sort-order" class="form-control" /> </div> </div> </form> </div> </div> </div> </div> <?php echo $footer; ?>
Again, this should be easy to understand. The purpose of this template file is to provide the configuration form for our custom shipping method. It uses the variables we set earlier in the controller file.
So, as far as our custom shipping method is concerned, the backend file setup is like this. In the next section, we'll see how to enable custom shipping methods and customize the look of the configuration form!
Enable custom shipping methods
Go to the admin section, then Extensions > Shipping. You should see our custom shipping methods listed as Custom Rate. Click the symbol to install our custom shipping methods. After installation, you should be able to see the Edit link to open the configuration form. Click the Edit link and the form should look like the screenshot below.
The important fields in the above form are Tax Class and Geographical Area强>.
If you need to impose any additional taxes in addition to the amount defined in the Cost field, you can select the appropriate option via the Tax Level field. We now select taxable goods.
The Geographic Region field allows you to select the regions to which this method applies; for simplicity, select All Regions. Also, make sure to set the status to Enabled otherwise it won't be listed in the frontend checkout.
After filling in the necessary data, click the Save button. That’s it for today’s article, I’ll get back to you soon with the next part where I’ll explain the frontend file setup.
in conclusion
Today we begin a series on how to create custom shipping methods in OpenCart. In the first part, we looked at the backend part and looked at how to set up the configuration form. If you have any questions or suggestions, please leave a message!
The above is the detailed content of OpenCart Tutorial: Customizing Shipping Methods (Part 1). For more information, please follow other related articles on the PHP Chinese website!

To build a website with powerful functions and good user experience, HTML alone is not enough. The following technology is also required: JavaScript gives web page dynamic and interactiveness, and real-time changes are achieved by operating DOM. CSS is responsible for the style and layout of the web page to improve aesthetics and user experience. Modern frameworks and libraries such as React, Vue.js and Angular improve development efficiency and code organization structure.

Boolean attributes are special attributes in HTML that are activated without a value. 1. The Boolean attribute controls the behavior of the element by whether it exists or not, such as disabled disable the input box. 2.Their working principle is to change element behavior according to the existence of attributes when the browser parses. 3. The basic usage is to directly add attributes, and the advanced usage can be dynamically controlled through JavaScript. 4. Common mistakes are mistakenly thinking that values need to be set, and the correct writing method should be concise. 5. The best practice is to keep the code concise and use Boolean properties reasonably to optimize web page performance and user experience.

HTML code can be cleaner with online validators, integrated tools and automated processes. 1) Use W3CMarkupValidationService to verify HTML code online. 2) Install and configure HTMLHint extension in VisualStudioCode for real-time verification. 3) Use HTMLTidy to automatically verify and clean HTML files in the construction process.

HTML, CSS and JavaScript are the core technologies for building modern web pages: 1. HTML defines the web page structure, 2. CSS is responsible for the appearance of the web page, 3. JavaScript provides web page dynamics and interactivity, and they work together to create a website with a good user experience.

The function of HTML is to define the structure and content of a web page, and its purpose is to provide a standardized way to display information. 1) HTML organizes various parts of the web page through tags and attributes, such as titles and paragraphs. 2) It supports the separation of content and performance and improves maintenance efficiency. 3) HTML is extensible, allowing custom tags to enhance SEO.

The future trends of HTML are semantics and web components, the future trends of CSS are CSS-in-JS and CSSHoudini, and the future trends of JavaScript are WebAssembly and Serverless. 1. HTML semantics improve accessibility and SEO effects, and Web components improve development efficiency, but attention should be paid to browser compatibility. 2. CSS-in-JS enhances style management flexibility but may increase file size. CSSHoudini allows direct operation of CSS rendering. 3.WebAssembly optimizes browser application performance but has a steep learning curve, and Serverless simplifies development but requires optimization of cold start problems.

The roles of HTML, CSS and JavaScript in web development are: 1. HTML defines the web page structure, 2. CSS controls the web page style, and 3. JavaScript adds dynamic behavior. Together, they build the framework, aesthetics and interactivity of modern websites.

The future of HTML is full of infinite possibilities. 1) New features and standards will include more semantic tags and the popularity of WebComponents. 2) The web design trend will continue to develop towards responsive and accessible design. 3) Performance optimization will improve the user experience through responsive image loading and lazy loading technologies.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

Dreamweaver Mac version
Visual web development tools
