Implement full support for OpenCart 2.0 - 2.2 with unified folder structures and cross-version templates/views

This commit is contained in:
nertyog 2026-07-05 22:31:44 +03:00
parent 32fb50819d
commit 08fb912b9b
23 changed files with 2266 additions and 5 deletions

View File

@ -1,7 +1,7 @@
============================================================================= =============================================================================
Poll Widget [NAT] Poll Widget [NAT]
Version: 1.0.0 Version: 1.0.0
Compatibility: OpenCart 3.0.x / ocStore 3.0.x Compatibility: OpenCart 2.0.x - 2.2.x / ocStore 2.1.x - 2.2.x
Author: NAT Author: NAT
Contact: info@nat.od.ua Contact: info@nat.od.ua
============================================================================= =============================================================================
@ -18,7 +18,7 @@ Poll Widget [NAT] — это функциональный модуль для с
УСТАНОВКА: УСТАНОВКА:
1. Перейдите в панель управления OpenCart: "Модули / Расширения" -> "Установка расширений". 1. Перейдите в панель управления OpenCart: "Модули / Расширения" -> "Установка расширений".
2. Загрузите архив `poll_widget_nat.ocmod.zip`. 2. Загрузите архив poll_widget_nat_OC_20_22_1_0.ocmod.zip.
3. Перейдите в "Модули / Расширения" -> "Модификаторы" и нажмите синюю кнопку "Обновить" (Очистить кэш). 3. Перейдите в "Модули / Расширения" -> "Модификаторы" и нажмите синюю кнопку "Обновить" (Очистить кэш).
4. Перейдите в "Система" -> "Пользователи" -> "Группы пользователей", выберите вашу группу (Administrator), нажмите "Выделить все" в правах просмотра и изменения, затем сохраните. 4. Перейдите в "Система" -> "Пользователи" -> "Группы пользователей", выберите вашу группу (Administrator), нажмите "Выделить все" в правах просмотра и изменения, затем сохраните.
5. Перейдите в "Модули / Расширения" -> "Расширения" -> тип "Модули", найдите "Poll Widget [NAT]" и нажмите "Установить", а затем "Редактировать". 5. Перейдите в "Модули / Расширения" -> "Расширения" -> тип "Модули", найдите "Poll Widget [NAT]" и нажмите "Установить", а затем "Редактировать".
@ -52,7 +52,7 @@ Poll Widget [NAT] — це функціональний модуль для ст
ВСТАНОВЛЕННЯ: ВСТАНОВЛЕННЯ:
1. Перейдіть до панелі керування OpenCart: "Модулі / Розширення" -> "Встановлення розширень". 1. Перейдіть до панелі керування OpenCart: "Модулі / Розширення" -> "Встановлення розширень".
2. Завантажте архів `poll_widget_nat.ocmod.zip`. 2. Завантажте архів poll_widget_nat_OC_20_22_1_0.ocmod.zip.
3. Перейдіть до "Модулі / Розширення" -> "Модифікатори" і натисніть синю кнопку "Оновити". 3. Перейдіть до "Модулі / Розширення" -> "Модифікатори" і натисніть синю кнопку "Оновити".
4. Перейдіть до "Система" -> "Користувачі" -> "Групи користувачів", виберіть вашу групу (Administrator), натисніть "Виділити все" у правах перегляду та зміни, збережіть. 4. Перейдіть до "Система" -> "Користувачі" -> "Групи користувачів", виберіть вашу групу (Administrator), натисніть "Виділити все" у правах перегляду та зміни, збережіть.
5. Перейдіть до "Модулі / Розширення" -> "Розширення" -> тип "Модулі", знайдіть "Poll Widget [NAT]", натисніть "Встановити", а потім "Редагувати". 5. Перейдіть до "Модулі / Розширення" -> "Розширення" -> тип "Модулі", знайдіть "Poll Widget [NAT]", натисніть "Встановити", а потім "Редагувати".
@ -86,7 +86,7 @@ Poll Widget [NAT] is a powerful tool for creating responsive voting widgets and
INSTALLATION: INSTALLATION:
1. Go to OpenCart admin panel: "Extensions" -> "Installer". 1. Go to OpenCart admin panel: "Extensions" -> "Installer".
2. Upload the `poll_widget_nat.ocmod.zip` archive. 2. Upload the poll_widget_nat_OC_20_22_1_0.ocmod.zip archive.
3. Go to "Extensions" -> "Modifications" and click the blue "Refresh" button. 3. Go to "Extensions" -> "Modifications" and click the blue "Refresh" button.
4. Go to "System" -> "Users" -> "User Groups", edit your group (Top Administrator), click "Select All" for Access and Modify permissions, then Save. 4. Go to "System" -> "Users" -> "User Groups", edit your group (Top Administrator), click "Select All" for Access and Modify permissions, then Save.
5. Go to "Extensions" -> "Extensions" -> choose "Modules", find "Poll Widget [NAT]", click "Install" and then "Edit". 5. Go to "Extensions" -> "Extensions" -> choose "Modules", find "Poll Widget [NAT]", click "Install" and then "Edit".

95
install.xml Normal file
View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<modification>
<name>Poll Widget [NAT]</name>
<id>poll_widget_nat</id>
<code>poll_widget_nat_od_ua</code>
<version>1.0.0</version>
<author>NAT</author>
<link>mailto:info@nat.od.ua</link>
<file path="admin/controller/common/column_left.php">
<operation error="skip">
<search><![CDATA[if ($this->user->hasPermission('access', 'catalog/product')) {]]></search>
<add position="before"><![CDATA[
$this->load->model('setting/setting');
if ($this->config->get('module_poll_widget_nat_status')) {
$nat_pos = $this->config->get('module_poll_widget_nat_menu_position');
if ($nat_pos == 'sidebar' || $nat_pos == 'both') {
if ($this->user->hasPermission('access', 'module/poll_widget_nat')) {
$nat_item = array(
'name' => 'Poll Widget',
'href' => $this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true),
'children' => array()
);
$nat_menu_index = -1;
if (isset($data['menus'])) {
foreach ($data['menus'] as $k => $menu) {
if (isset($menu['id']) && $menu['id'] == 'menu-nat') {
$nat_menu_index = $k;
break;
}
}
}
if ($nat_menu_index > -1) {
$data['menus'][$nat_menu_index]['children'][] = $nat_item;
} else {
$data['menus'][] = array(
'id' => 'menu-nat',
'icon' => 'fa-rocket fw',
'name' => '[NAT] Modules',
'href' => '',
'children' => array($nat_item)
);
}
}
}
}
]]></add>
</operation>
</file>
<file path="admin/controller/common/header.php">
<operation error="skip">
<search><![CDATA[$data['logout'] = $this->url->link('common/logout']]></search>
<add position="before"><![CDATA[
if (!isset($data['nat_menus'])) {
$data['nat_menus'] = array();
}
$this->load->model('setting/setting');
if ($this->config->get('module_poll_widget_nat_status')) {
$nat_pos = $this->config->get('module_poll_widget_nat_menu_position');
if ($nat_pos == 'header' || $nat_pos == 'both') {
if ($this->user->hasPermission('access', 'module/poll_widget_nat')) {
$data['nat_menus'][] = array(
'name' => 'Poll Widget',
'href' => $this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true)
);
}
}
}
]]></add>
</operation>
</file>
<file path="admin/view/template/common/header.tpl">
<operation error="skip">
<search><![CDATA[<li><a href="<?php echo $logout; ?>"]]></search>
<add position="before"><![CDATA[
<?php if (isset($nat_menus) && $nat_menus && empty($nat_menu_rendered)) { ?>
<?php $nat_menu_rendered = true; ?>
<li class="dropdown" id="nat-ecosystem-menu">
<a class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-rocket fa-lg" style="color:#e74c3c;"></i> <span class="hidden-xs hidden-sm hidden-md">[NAT]</span> <span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-right" id="nat-ecosystem-list">
<li class="dropdown-header">Ecosystem [NAT]</li>
<?php foreach ($nat_menus as $n_menu) { ?>
<li><a href="<?php echo $n_menu['href']; ?>"><i class="fa fa-angle-right"></i> <?php echo $n_menu['name']; ?></a></li>
<?php } ?>
</ul>
</li>
<?php } ?>
]]></add>
</operation>
</file>
</modification>

Binary file not shown.

View File

@ -24,7 +24,7 @@ Poll Widget [NAT] is a powerful tool for creating responsive voting widgets and
INSTALLATION: INSTALLATION:
1. Go to OpenCart admin panel: "Extensions" -> "Installer". 1. Go to OpenCart admin panel: "Extensions" -> "Installer".
2. Upload the `poll_widget_nat_OC_30_1_0.ocmod.zip` archive. 2. Upload the `poll_widget_nat_OC_20_22_1_0.ocmod.zip` archive.
3. Go to "Extensions" -> "Modifications" and click the blue "Refresh" button. 3. Go to "Extensions" -> "Modifications" and click the blue "Refresh" button.
4. Go to "System" -> "Users" -> "User Groups", edit your group (Top Administrator), click "Select All" for Access and Modify permissions, then Save. 4. Go to "System" -> "Users" -> "User Groups", edit your group (Top Administrator), click "Select All" for Access and Modify permissions, then Save.
5. Go to "Extensions" -> "Extensions" -> choose "Modules", find "Poll Widget [NAT]", click "Install" and then "Edit". 5. Go to "Extensions" -> "Extensions" -> choose "Modules", find "Poll Widget [NAT]", click "Install" and then "Edit".

View File

@ -0,0 +1,370 @@
<?php
if (!defined('VERSION')) exit;
class ControllerModulePollWidgetNat extends Controller {
private $error = array();
public function install() {
$this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "poll_widget_nat` (
`poll_id` int(11) NOT NULL AUTO_INCREMENT,
`status` tinyint(1) NOT NULL DEFAULT '1',
`config` text NOT NULL,
`colors` text NOT NULL,
`custom_stats` text NOT NULL,
`date_added` datetime NOT NULL,
PRIMARY KEY (`poll_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
$this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "poll_widget_nat_description` (
`poll_id` int(11) NOT NULL,
`language_id` int(11) NOT NULL,
`question` varchar(255) NOT NULL,
`answers` text NOT NULL,
`thanks_text` text NOT NULL,
PRIMARY KEY (`poll_id`,`language_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
$this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "poll_widget_nat_vote` (
`vote_id` int(11) NOT NULL AUTO_INCREMENT,
`poll_id` int(11) NOT NULL,
`answer_index` int(11) NOT NULL,
`customer_id` int(11) NOT NULL DEFAULT '0',
`ip` varchar(40) NOT NULL,
`user_agent` varchar(255) NOT NULL,
`page_url` text NOT NULL,
`date_added` datetime NOT NULL,
PRIMARY KEY (`vote_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
$this->load->model('setting/setting');
$this->model_setting_setting->editSetting('module_poll_widget_nat', array(
'module_poll_widget_nat_status' => 1,
'module_poll_widget_nat_menu_position' => 'both'
));
}
public function uninstall() {
$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "poll_widget_nat`;");
$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "poll_widget_nat_description`;");
$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "poll_widget_nat_vote`;");
}
private function checkLicense($key) {
if (empty($key)) return false;
$host = explode(':', str_replace(array('http://', 'https://', 'www.'), '', strtolower($this->request->server['HTTP_HOST'])))[0];
$parts = explode('.', $host);
$v_core = '_redis';
$v_end = 'aet_';
$v_bit = '_lom';
$v_to = 'to';
$v_k = 'k';
$v_mid = 'tot';
$v_sfx = 'ka';
$salt = ($v_k . $v_to . $v_bit) . ($v_end . $v_mid) . ($v_core . $v_sfx);
while(count($parts) >= 2) {
$domain = implode('.', $parts);
if ($key === strtoupper(implode('-', str_split(substr(md5($domain . $salt), 0, 16), 4)))) return true;
array_shift($parts);
}
return false;
}
public function index() {
$this->load->language('module/poll_widget_nat');
$this->document->setTitle($this->language->get('heading_title_raw'));
$this->load->model('module/poll_widget_nat');
$this->load->model('setting/setting');
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
$this->model_setting_setting->editSetting('module_poll_widget_nat', $this->request->post);
$this->session->data['success'] = $this->language->get('text_success');
$this->response->redirect($this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true));
}
$this->getList();
}
protected function getList() {
$data = array_merge(array(), $this->language->all());
$data['breadcrumbs'] = array();
$data['breadcrumbs'][] = array(
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], true)
);
$data['breadcrumbs'][] = array(
'text' => $this->language->get('text_extension'),
'href' => $this->url->link('extension/module', 'token=' . $this->session->data['token'], true)
);
$data['breadcrumbs'][] = array(
'text' => $this->language->get('heading_title_raw'),
'href' => $this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true)
);
$data['action'] = $this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true);
$data['add'] = $this->url->link('module/poll_widget_nat/add', 'token=' . $this->session->data['token'], true);
$data['cancel'] = $this->url->link('extension/module', 'token=' . $this->session->data['token'], true);
if (isset($this->request->post['module_poll_widget_nat_status'])) {
$data['module_poll_widget_nat_status'] = $this->request->post['module_poll_widget_nat_status'];
} else {
$data['module_poll_widget_nat_status'] = $this->config->get('module_poll_widget_nat_status');
}
if (isset($this->request->post['module_poll_widget_nat_license'])) {
$data['module_poll_widget_nat_license'] = $this->request->post['module_poll_widget_nat_license'];
} else {
$data['module_poll_widget_nat_license'] = $this->config->get('module_poll_widget_nat_license');
}
if (isset($this->request->post['module_poll_widget_nat_menu_position'])) {
$data['module_poll_widget_nat_menu_position'] = $this->request->post['module_poll_widget_nat_menu_position'];
} else {
$data['module_poll_widget_nat_menu_position'] = $this->config->get('module_poll_widget_nat_menu_position');
}
$data['is_licensed'] = $this->checkLicense($data['module_poll_widget_nat_license']);
$data['polls'] = array();
$results = $this->model_module_poll_widget_nat->getPolls();
foreach ($results as $result) {
$data['polls'][] = array(
'poll_id' => (int)$result['poll_id'],
'question'=> (string)$result['question'],
'status' => ($result['status'] ? $this->language->get('text_enabled') : $this->language->get('text_disabled')),
'edit' => $this->url->link('module/poll_widget_nat/edit', 'token=' . $this->session->data['token'] . '&poll_id=' . (int)$result['poll_id'], true),
'delete' => $this->url->link('module/poll_widget_nat/delete', 'token=' . $this->session->data['token'] . '&poll_id=' . (int)$result['poll_id'], true)
);
}
if (isset($this->session->data['success'])) {
$data['success'] = $this->session->data['success'];
unset($this->session->data['success']);
} else {
$data['success'] = '';
}
if (isset($this->error['warning'])) {
$data['error_warning'] = $this->error['warning'];
} else {
$data['error_warning'] = '';
}
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
if (version_compare(VERSION, '2.2.0.0', '<')) {
$this->response->setOutput($this->load->view('module/poll_widget_nat_list.tpl', $data));
} else {
$this->response->setOutput($this->load->view('module/poll_widget_nat_list', $data));
}
}
public function add() {
$this->load->language('module/poll_widget_nat');
$this->document->setTitle($this->language->get('heading_title_raw'));
$this->load->model('module/poll_widget_nat');
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateForm()) {
$this->model_module_poll_widget_nat->addPoll($this->request->post);
$this->session->data['success'] = $this->language->get('text_success');
$this->response->redirect($this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true));
}
$this->getForm();
}
public function edit() {
$this->load->language('module/poll_widget_nat');
$this->document->setTitle($this->language->get('heading_title_raw'));
$this->load->model('module/poll_widget_nat');
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateForm()) {
$this->model_module_poll_widget_nat->editPoll((int)$this->request->get['poll_id'], $this->request->post);
$this->session->data['success'] = $this->language->get('text_success');
$this->response->redirect($this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true));
}
$this->getForm();
}
public function delete() {
$this->load->language('module/poll_widget_nat');
$this->load->model('module/poll_widget_nat');
if (isset($this->request->get['poll_id']) && $this->validate()) {
$this->model_module_poll_widget_nat->deletePoll((int)$this->request->get['poll_id']);
$this->session->data['success'] = $this->language->get('text_success');
}
$this->response->redirect($this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true));
}
protected function getForm() {
$data = array_merge(array(), $this->language->all());
if (isset($this->error['warning'])) {
$data['error_warning'] = $this->error['warning'];
} else {
$data['error_warning'] = '';
}
if (isset($this->error['question'])) {
$data['error_question'] = $this->error['question'];
} else {
$data['error_question'] = array();
}
$data['breadcrumbs'] = array();
$data['breadcrumbs'][] = array(
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], true)
);
$data['breadcrumbs'][] = array(
'text' => $this->language->get('heading_title_raw'),
'href' => $this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true)
);
if (!isset($this->request->get['poll_id'])) {
$poll_id = 0;
$data['action'] = $this->url->link('module/poll_widget_nat/add', 'token=' . $this->session->data['token'], true);
} else {
$poll_id = (int)$this->request->get['poll_id'];
$data['action'] = $this->url->link('module/poll_widget_nat/edit', 'token=' . $this->session->data['token'] . '&poll_id=' . $poll_id, true);
}
$data['cancel'] = $this->url->link('module/poll_widget_nat', 'token=' . $this->session->data['token'], true);
$poll_info = array();
if ($poll_id && ($this->request->server['REQUEST_METHOD'] != 'POST')) {
$poll_info = $this->model_module_poll_widget_nat->getPoll($poll_id);
if ($poll_info) {
$poll_info['config'] = json_decode($poll_info['config'], true);
$poll_info['colors'] = json_decode($poll_info['colors'], true);
$poll_info['custom_stats'] = json_decode($poll_info['custom_stats'], true);
}
}
$this->load->model('localisation/language');
$data['languages'] = $this->model_localisation_language->getLanguages();
if (isset($this->request->post['poll_description'])) {
$data['poll_description'] = $this->request->post['poll_description'];
} elseif ($poll_id) {
$data['poll_description'] = $this->model_module_poll_widget_nat->getPollDescriptions($poll_id);
} else {
$data['poll_description'] = array();
}
$data['status'] = isset($this->request->post['status']) ? (int)$this->request->post['status'] : (!empty($poll_info) ? (int)$poll_info['status'] : 1);
$data['config'] = isset($this->request->post['config']) ? $this->request->post['config'] : (!empty($poll_info['config']) ? $poll_info['config'] : array());
$data['custom_stats'] = isset($this->request->post['custom_stats']) ? $this->request->post['custom_stats'] : (!empty($poll_info['custom_stats']) ? $poll_info['custom_stats'] : array());
$default_colors = array(
'bg' => '#ffffff',
'text' => '#333333',
'border' => '#e5e5e5',
'btn_bg' => '#2980b9',
'btn_color' => '#ffffff',
'bar_bg' => '#eeeeee',
'bar_fill' => '#2980b9'
);
if (isset($this->request->post['colors'])) {
$data['colors'] = $this->request->post['colors'];
} elseif (!empty($poll_info['colors'])) {
$data['colors'] = array_merge($default_colors, (array)$poll_info['colors']);
} else {
$data['colors'] = $default_colors;
}
$answers_map = array();
$current_lang_id = (int)$this->config->get('config_language_id');
if (isset($data['poll_description'][$current_lang_id])) {
$raw_answers = explode("\n", str_replace("\r", "", $data['poll_description'][$current_lang_id]['answers']));
foreach ($raw_answers as $i => $text) {
if (trim($text)) {
$answers_map[$i] = trim($text);
}
}
}
$data['answers_map'] = $answers_map;
if (isset($this->request->get['page'])) {
$page = (int)$this->request->get['page'];
} else {
$page = 1;
}
$limit = 15;
$data['voted_total'] = array();
$data['latest_votes'] = array();
$data['total_votes_count'] = 0;
if ($poll_id) {
$data['voted_total'] = $this->model_module_poll_widget_nat->getVotesCountByIndex($poll_id);
$data['total_votes_count'] = $this->model_module_poll_widget_nat->getTotalVotes($poll_id);
$results = $this->model_module_poll_widget_nat->getVotes($poll_id, ($page - 1) * $limit, $limit);
foreach ($results as $result) {
$user_info = $result['customer_id'] ? $result['firstname'] . ' ' . $result['lastname'] . ' (' . $result['email'] . ')' : $this->language->get('text_guest');
$answer_text = isset($answers_map[$result['answer_index']]) ? $answers_map[$result['answer_index']] : $this->language->get('text_answer_index') . ' ' . (int)$result['answer_index'];
$data['latest_votes'][] = array(
'answer' => $answer_text,
'user' => $user_info,
'ip' => $result['ip'],
'page_url' => isset($result['page_url']) ? $result['page_url'] : '',
'date' => date('d.m.Y H:i', strtotime($result['date_added']))
);
}
}
$pagination = new Pagination();
$pagination->total = $data['total_votes_count'];
$pagination->page = $page;
$pagination->limit = $limit;
$pagination->url = $this->url->link('module/poll_widget_nat/edit', 'token=' . $this->session->data['token'] . '&poll_id=' . $poll_id . '&page={page}', true);
$data['pagination'] = $pagination->render();
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
if (version_compare(VERSION, '2.2.0.0', '<')) {
$this->response->setOutput($this->load->view('module/poll_widget_nat_form.tpl', $data));
} else {
$this->response->setOutput($this->load->view('module/poll_widget_nat_form', $data));
}
}
protected function validate() {
if (!$this->user->hasPermission('modify', 'module/poll_widget_nat')) {
$this->error['warning'] = $this->language->get('error_permission');
}
return !$this->error;
}
protected function validateForm() {
if (!$this->user->hasPermission('modify', 'module/poll_widget_nat')) {
$this->error['warning'] = $this->language->get('error_permission');
}
if (isset($this->request->post['poll_description']) && is_array($this->request->post['poll_description'])) {
foreach ($this->request->post['poll_description'] as $language_id => $value) {
if ((utf8_strlen($value['question']) < 3) || (utf8_strlen($value['question']) > 255)) {
$this->error['question'][$language_id] = $this->language->get('error_question');
}
}
} else {
$this->error['warning'] = $this->language->get('error_form');
}
return !$this->error;
}
}

View File

@ -0,0 +1,93 @@
<?php
$_['heading_title'] = '<b>Poll Widget [NAT]:</b> Polls and Voting';
$_['heading_title_raw'] = 'Poll Widget [NAT]: Polls and Voting';
$_['text_extension'] = 'Extensions';
$_['text_success'] = 'Module settings successfully updated!';
$_['text_edit'] = 'Edit Poll';
$_['text_add'] = 'Create Poll';
$_['text_list'] = 'Poll List';
$_['tab_general'] = 'General Settings';
$_['tab_visual'] = 'Design & Colors';
$_['tab_stats'] = 'Statistics';
$_['tab_info'] = 'Info';
$_['tab_polls'] = 'Polls';
$_['entry_status'] = 'Status';
$_['entry_question'] = 'Question';
$_['entry_answers'] = 'Answers';
$_['help_answers'] = 'Each answer on a new line.';
$_['entry_thanks_text'] = 'Thank you text';
$_['entry_guest'] = 'Guest voting';
$_['entry_limit'] = 'Vote limit';
$_['help_limit'] = 'How many times one user/IP can vote (0 - unlimited)';
$_['entry_result_type'] = 'Results format';
$_['text_res_percent'] = 'Percents (%)';
$_['text_res_count'] = 'Vote count';
$_['text_res_both'] = 'Both ( % / Count )';
$_['text_res_none'] = 'Hide (thanks text only)';
$_['entry_bg_color'] = 'Background';
$_['entry_text_color'] = 'Text Color';
$_['entry_border_color'] = 'Border Color';
$_['entry_btn_bg'] = 'Button Background';
$_['entry_btn_color'] = 'Button Text';
$_['entry_bar_bg'] = 'Progress Bar BG';
$_['entry_bar_fill'] = 'Progress Bar Fill';
$_['column_question'] = 'Question';
$_['column_status'] = 'Status';
$_['column_action'] = 'Action';
$_['text_stats_info'] = 'Statistics management: real data and manual adjustments.';
$_['column_answer'] = 'Answer';
$_['column_real'] = 'Real Votes';
$_['column_custom'] = 'Adjust Stats (+/-)';
$_['text_no_answers_yet'] = 'Fill in the answers and save the poll first!';
$_['text_log_title'] = 'Vote Log (Total: %s)';
$_['column_who'] = 'Who';
$_['column_ip'] = 'IP';
$_['column_page'] = 'Page';
$_['column_date'] = 'Date';
$_['text_answer_prefix'] = 'Answer:';
$_['text_guest'] = 'Guest';
$_['text_no_results'] = 'No data to display';
$_['text_ecosystem'] = 'Ecosystem [NAT]';
$_['text_catalog_opt_desc'] = 'Hide empty categories/brands + SEO sorting + DB cleanup.';
$_['text_img_opt_desc'] = 'Compress originals to WebP + Mass cleanup of unused images.';
$_['text_domain_scan_desc'] = 'Find and clean external links in DB (perfect for HTTPS transition).';
$_['text_support_info'] = 'Support and suggestions:';
$_['button_all_modules'] = 'View all [NAT] modules';
$_['error_permission'] = 'You do not have permission to modify this module!';
$_['error_question'] = 'Question must be between 3 and 255 characters!';
$_['entry_license'] = 'License Key';
$_['entry_show_total'] = 'Show "Total Votes"';
$_['entry_total_access'] = 'Who can see total votes';
$_['text_access_all'] = 'All visitors';
$_['text_access_reg'] = 'Registered only';
$_['text_footer_ecosystem'] = 'Developed for the <strong>[NAT]</strong> ecosystem. Support: <a href="mailto:info@nat.od.ua">info@nat.od.ua</a>';
$_['text_other_modules'] = 'Other modules in the [NAT] series:';
$_['text_new_arrivals_title'] = 'New Arrivals [NAT]: True Sort by Date';
$_['text_new_arrivals_desc'] = 'Automatic SEO page for new arrivals. Displays items strictly by actual added date. Sliders, grids, and smart date archive sidebar.';
$_['text_catalog_opt_title'] = 'Catalog Optimizer [NAT]';
$_['text_catalog_opt_desc'] = 'Hide empty categories/brands + SEO sorting (in-stock first) + DB garbage cleanup.';
$_['text_img_opt_title'] = 'Image Optimizer [NAT]';
$_['text_img_opt_desc'] = 'Original image compression to WebP + Mass cleanup of unused images on the server.';
$_['text_domain_scan_title'] = 'Domain Scanner [NAT]';
$_['text_domain_scan_desc'] = 'Search and clean external links and HTTP images in DB and theme files. Perfect for HTTPS migration or parsing cleanup.';
$_['text_confirm_delete'] = 'Delete this poll? All votes will be permanently erased!';
$_['text_license_warning'] = 'Enter a valid license key to activate the module.';
$_['entry_menu_position'] = 'Admin Menu Position';
$_['text_menu_module'] = 'Only in modules list';
$_['text_menu_header'] = 'In Header (top panel)';
$_['text_menu_sidebar'] = 'In Sidebar (left menu)';
$_['text_menu_both'] = 'Both (Header + Sidebar)';
$_['error_form'] = 'Please check the form carefully for errors!';
$_['text_database_opt_title'] = 'Database Optimizer [NAT]';
$_['text_database_opt_desc'] = 'Intelligent database garbage collection, system log management, and adding critical indexes for site speedup.';
$_['text_admin_tools_title'] = 'Admin Tools [NAT]';
$_['text_admin_tools_desc'] = 'Handy administrator tools: login as customer, admin customization, user permissions management, and hiding unnecessary menu items.';
$_['text_easy_import_title'] = 'Easy Import/Export [NAT]';
$_['text_easy_import_desc'] = 'Fast import/export of prices, stocks and products from XLS/XLSX/CSV/XML/JSON. Field mapping, Cron jobs and URL support.';
$_['text_utm_tracker_title'] = 'Order UTM Tracker [NAT]';
$_['text_utm_tracker_desc'] = 'Automatic tracking of UTM tags during checkout. Saves the traffic source, campaign, keywords, and displays this data in order details to analyze advertising effectiveness.';
$_['text_poll_widget_title'] = 'Poll Widget [NAT]';
$_['text_poll_widget_desc'] = 'Create polls and voting widgets with a visual design builder, detailed statistics, and fraud protection.';
$_['text_current_module'] = 'Current module';
$_['text_info_title_promo_top_bar'] = 'Promo Top Bar [NAT]: Upper promotional info-banner, information bar above header, marquee and top-banner';
$_['text_info_desc_promo_top_bar'] = 'Create interactive promo bars and header slideshows with a block builder, countdown timers, subscription forms, and flexible targeting.';

View File

@ -0,0 +1,93 @@
<?php
$_['heading_title'] = '<b>Poll Widget [NAT]:</b> Polls and Voting';
$_['heading_title_raw'] = 'Poll Widget [NAT]: Polls and Voting';
$_['text_extension'] = 'Extensions';
$_['text_success'] = 'Module settings successfully updated!';
$_['text_edit'] = 'Edit Poll';
$_['text_add'] = 'Create Poll';
$_['text_list'] = 'Poll List';
$_['tab_general'] = 'General Settings';
$_['tab_visual'] = 'Design & Colors';
$_['tab_stats'] = 'Statistics';
$_['tab_info'] = 'Info';
$_['tab_polls'] = 'Polls';
$_['entry_status'] = 'Status';
$_['entry_question'] = 'Question';
$_['entry_answers'] = 'Answers';
$_['help_answers'] = 'Each answer on a new line.';
$_['entry_thanks_text'] = 'Thank you text';
$_['entry_guest'] = 'Guest voting';
$_['entry_limit'] = 'Vote limit';
$_['help_limit'] = 'How many times one user/IP can vote (0 - unlimited)';
$_['entry_result_type'] = 'Results format';
$_['text_res_percent'] = 'Percents (%)';
$_['text_res_count'] = 'Vote count';
$_['text_res_both'] = 'Both ( % / Count )';
$_['text_res_none'] = 'Hide (thanks text only)';
$_['entry_bg_color'] = 'Background';
$_['entry_text_color'] = 'Text Color';
$_['entry_border_color'] = 'Border Color';
$_['entry_btn_bg'] = 'Button Background';
$_['entry_btn_color'] = 'Button Text';
$_['entry_bar_bg'] = 'Progress Bar BG';
$_['entry_bar_fill'] = 'Progress Bar Fill';
$_['column_question'] = 'Question';
$_['column_status'] = 'Status';
$_['column_action'] = 'Action';
$_['text_stats_info'] = 'Statistics management: real data and manual adjustments.';
$_['column_answer'] = 'Answer';
$_['column_real'] = 'Real Votes';
$_['column_custom'] = 'Adjust Stats (+/-)';
$_['text_no_answers_yet'] = 'Fill in the answers and save the poll first!';
$_['text_log_title'] = 'Vote Log (Total: %s)';
$_['column_who'] = 'Who';
$_['column_ip'] = 'IP';
$_['column_page'] = 'Page';
$_['column_date'] = 'Date';
$_['text_answer_prefix'] = 'Answer:';
$_['text_guest'] = 'Guest';
$_['text_no_results'] = 'No data to display';
$_['text_ecosystem'] = 'Ecosystem [NAT]';
$_['text_catalog_opt_desc'] = 'Hide empty categories/brands + SEO sorting + DB cleanup.';
$_['text_img_opt_desc'] = 'Compress originals to WebP + Mass cleanup of unused images.';
$_['text_domain_scan_desc'] = 'Find and clean external links in DB (perfect for HTTPS transition).';
$_['text_support_info'] = 'Support and suggestions:';
$_['button_all_modules'] = 'View all [NAT] modules';
$_['error_permission'] = 'You do not have permission to modify this module!';
$_['error_question'] = 'Question must be between 3 and 255 characters!';
$_['entry_license'] = 'License Key';
$_['entry_show_total'] = 'Show "Total Votes"';
$_['entry_total_access'] = 'Who can see total votes';
$_['text_access_all'] = 'All visitors';
$_['text_access_reg'] = 'Registered only';
$_['text_footer_ecosystem'] = 'Developed for the <strong>[NAT]</strong> ecosystem. Support: <a href="mailto:info@nat.od.ua">info@nat.od.ua</a>';
$_['text_other_modules'] = 'Other modules in the [NAT] series:';
$_['text_new_arrivals_title'] = 'New Arrivals [NAT]: True Sort by Date';
$_['text_new_arrivals_desc'] = 'Automatic SEO page for new arrivals. Displays items strictly by actual added date. Sliders, grids, and smart date archive sidebar.';
$_['text_catalog_opt_title'] = 'Catalog Optimizer [NAT]';
$_['text_catalog_opt_desc'] = 'Hide empty categories/brands + SEO sorting (in-stock first) + DB garbage cleanup.';
$_['text_img_opt_title'] = 'Image Optimizer [NAT]';
$_['text_img_opt_desc'] = 'Original image compression to WebP + Mass cleanup of unused images on the server.';
$_['text_domain_scan_title'] = 'Domain Scanner [NAT]';
$_['text_domain_scan_desc'] = 'Search and clean external links and HTTP images in DB and theme files. Perfect for HTTPS migration or parsing cleanup.';
$_['text_confirm_delete'] = 'Delete this poll? All votes will be permanently erased!';
$_['text_license_warning'] = 'Enter a valid license key to activate the module.';
$_['entry_menu_position'] = 'Admin Menu Position';
$_['text_menu_module'] = 'Only in modules list';
$_['text_menu_header'] = 'In Header (top panel)';
$_['text_menu_sidebar'] = 'In Sidebar (left menu)';
$_['text_menu_both'] = 'Both (Header + Sidebar)';
$_['error_form'] = 'Please check the form carefully for errors!';
$_['text_database_opt_title'] = 'Database Optimizer [NAT]';
$_['text_database_opt_desc'] = 'Intelligent database garbage collection, system log management, and adding critical indexes for site speedup.';
$_['text_admin_tools_title'] = 'Admin Tools [NAT]';
$_['text_admin_tools_desc'] = 'Handy administrator tools: login as customer, admin customization, user permissions management, and hiding unnecessary menu items.';
$_['text_easy_import_title'] = 'Easy Import/Export [NAT]';
$_['text_easy_import_desc'] = 'Fast import/export of prices, stocks and products from XLS/XLSX/CSV/XML/JSON. Field mapping, Cron jobs and URL support.';
$_['text_utm_tracker_title'] = 'Order UTM Tracker [NAT]';
$_['text_utm_tracker_desc'] = 'Automatic tracking of UTM tags during checkout. Saves the traffic source, campaign, keywords, and displays this data in order details to analyze advertising effectiveness.';
$_['text_poll_widget_title'] = 'Poll Widget [NAT]';
$_['text_poll_widget_desc'] = 'Create polls and voting widgets with a visual design builder, detailed statistics, and fraud protection.';
$_['text_current_module'] = 'Current module';
$_['text_info_title_promo_top_bar'] = 'Promo Top Bar [NAT]: Upper promotional info-banner, information bar above header, marquee and top-banner';
$_['text_info_desc_promo_top_bar'] = 'Create interactive promo bars and header slideshows with a block builder, countdown timers, subscription forms, and flexible targeting.';

View File

@ -0,0 +1,93 @@
<?php
$_['heading_title'] = '<b>Poll Widget [NAT]:</b> Опросы и голосования';
$_['heading_title_raw'] = 'Poll Widget [NAT]: Опросы и голосования';
$_['text_extension'] = 'Расширения';
$_['text_success'] = 'Настройки модуля успешно обновлены!';
$_['text_edit'] = 'Редактирование опроса';
$_['text_add'] = 'Создать опрос';
$_['text_list'] = 'Список опросов';
$_['tab_general'] = 'Основные настройки';
$_['tab_visual'] = 'Дизайн и цвета';
$_['tab_stats'] = 'Статистика и накрутка';
$_['tab_info'] = 'Инфо';
$_['tab_polls'] = 'Опросы';
$_['entry_status'] = 'Статус';
$_['entry_question'] = 'Вопрос';
$_['entry_answers'] = 'Варианты ответов';
$_['help_answers'] = 'Каждый вариант с новой строки.';
$_['entry_thanks_text'] = 'Текст благодарности';
$_['entry_guest'] = 'Голосование гостей';
$_['entry_limit'] = 'Лимит голосов';
$_['help_limit'] = 'Сколько раз может проголосовать один пользователь/IP (0 - без лимита)';
$_['entry_result_type'] = 'Формат результатов';
$_['text_res_percent'] = 'Проценты (%)';
$_['text_res_count'] = 'Количество голосов';
$_['text_res_both'] = 'Всё вместе ( % / Кол-во )';
$_['text_res_none'] = 'Скрыть (только благодарность)';
$_['entry_bg_color'] = 'Фон блока';
$_['entry_text_color'] = 'Цвет текста';
$_['entry_border_color'] = 'Цвет рамок';
$_['entry_btn_bg'] = 'Цвет кнопки';
$_['entry_btn_color'] = 'Текст кнопки';
$_['entry_bar_bg'] = 'Фон полосы прогресса';
$_['entry_bar_fill'] = 'Заливка полосы прогресса';
$_['column_question'] = 'Вопрос';
$_['column_status'] = 'Статус';
$_['column_action'] = 'Действие';
$_['text_stats_info'] = 'Управление статистикой: здесь отображаются реальные данные и возможность их корректировки.';
$_['column_answer'] = 'Вариант ответа';
$_['column_real'] = 'Реально';
$_['column_custom'] = 'Управление статистикой (+/-)';
$_['text_no_answers_yet'] = 'Сначала заполните варианты ответов и сохраните опрос!';
$_['text_log_title'] = 'Журнал голосов (Всего: %s)';
$_['column_who'] = 'Кто';
$_['column_ip'] = 'IP';
$_['column_page'] = 'Страница';
$_['column_date'] = 'Дата';
$_['text_answer_prefix'] = 'Ответ:';
$_['text_guest'] = 'Guest';
$_['text_no_results'] = 'Нет данных для отображения';
$_['text_ecosystem'] = 'Экосистема [NAT]';
$_['text_catalog_opt_desc'] = 'Скрытие пустых категорий и брендов + SEO сортировка товаров (в наличии сверху) + Очистка мусора БД.';
$_['text_img_opt_desc'] = 'Сжатие оригиналов (image/catalog) в WebP + Массовая очистка хостинга от лишних картинок.';
$_['text_domain_scan_desc'] = 'Поиск и чистка внешних ссылок и HTTP-картинок в описаниях БД (идеально для перехода на HTTPS).';
$_['text_support_info'] = 'Техническая поддержка и пожелания:';
$_['button_all_modules'] = 'Смотреть все модули [NAT]';
$_['error_permission'] = 'У вас нет прав для управления этим модулем!';
$_['error_question'] = 'Вопрос должен быть от 3 до 255 символов!';
$_['entry_license'] = 'Лицензионный ключ';
$_['entry_show_total'] = 'Показывать "Всего проголосовало"';
$_['entry_total_access'] = 'Кто видит счетчик';
$_['text_access_all'] = 'Все посетители';
$_['text_access_reg'] = 'Только авторизованные';
$_['text_footer_ecosystem'] = 'Разработано для экосистемы <strong>[NAT]</strong>. Поддержка: <a href="mailto:info@nat.od.ua">info@nat.od.ua</a>';
$_['text_other_modules'] = 'Другие модули серии [NAT]:';
$_['text_new_arrivals_title'] = 'New Arrivals [NAT]: True Sort by Date';
$_['text_new_arrivals_desc'] = 'Автоматическая SEO-страница новинок. Отображение товаров строго по реальной дате добавления. Слайдеры, сетки и умный сайдбар архива дат.';
$_['text_catalog_opt_title'] = 'Catalog Optimizer [NAT]';
$_['text_catalog_opt_desc'] = 'Скрытие пустых категорий и брендов + SEO сортировка товаров (в наличии сверху) + очистка мусора БД.';
$_['text_img_opt_title'] = 'Image Optimizer [NAT]';
$_['text_img_opt_desc'] = 'Сжатие оригинальных изображений в WebP + массовая очистка неиспользуемых изображений на сервере.';
$_['text_domain_scan_title'] = 'Domain Scanner [NAT]';
$_['text_domain_scan_desc'] = 'Поиск и очистка внешних ссылок и HTTP-изображений в БД и файлах темы. Идеально для перехода на HTTPS или очистки после парсинга.';
$_['text_confirm_delete'] = 'Удалить этот опрос? Все голоса будут стерты!';
$_['text_license_warning'] = 'Введите валидный лицензионный ключ для активации модуля и начала работы.';
$_['entry_menu_position'] = 'Позиция в меню админки';
$_['text_menu_module'] = 'Только в модулях';
$_['text_menu_header'] = 'В шапке (верхняя панель)';
$_['text_menu_sidebar'] = 'В боковом меню (слева)';
$_['text_menu_both'] = 'Везде (Шапка + Сайдбар)';
$_['error_form'] = 'Внимательно проверьте форму на наличие ошибок!';
$_['text_database_opt_title'] = 'Database Optimizer [NAT]';
$_['text_database_opt_desc'] = 'Интеллектуальная очистка мусора БД, управление системными логами и добавление критических индексов для ускорения сайта.';
$_['text_admin_tools_title'] = 'Admin Tools [NAT]';
$_['text_admin_tools_desc'] = 'Удобные инструменты администратора: вход под клиентом, кастомизация админки, управление правами и скрытие ненужных пунктов меню.';
$_['text_easy_import_title'] = 'Easy Import/Export [NAT]';
$_['text_easy_import_desc'] = 'Быстрый импорт/экспорт цен, остатков и товаров из XLS/XLSX/CSV/XML/JSON. Сопоставление полей, Cron и поддержка ссылок.';
$_['text_utm_tracker_title'] = 'Order UTM Tracker [NAT]';
$_['text_utm_tracker_desc'] = 'Автоматическое отслеживание UTM-меток при оформлении заказа. Сохраняет источник трафика, кампанию, ключевые слова и выводит эти данные в деталях заказа для анализа эффективности рекламы.';
$_['text_poll_widget_title'] = 'Poll Widget [NAT]';
$_['text_poll_widget_desc'] = 'Создание опросов и виджетов голосования с визуальным конструктором дизайна, детальной статистикой и защитой от накрутки.';
$_['text_current_module'] = 'Текущий модуль';
$_['text_info_title_promo_top_bar'] = 'Promo Top Bar [NAT]: Верхний рекламный инфо-баннер, информационная полоса над шапкой, бегущая строка и топ-баннер';
$_['text_info_desc_promo_top_bar'] = 'Создание интерактивных промо-панелей и слайд-шоу в шапке сайта с конструктором блоков, таймерами, формой подписки и гибким таргетингом.';

View File

@ -0,0 +1,93 @@
<?php
$_['heading_title'] = '<b>Poll Widget [NAT]:</b> Опросы и голосования';
$_['heading_title_raw'] = 'Poll Widget [NAT]: Опросы и голосования';
$_['text_extension'] = 'Расширения';
$_['text_success'] = 'Настройки модуля успешно обновлены!';
$_['text_edit'] = 'Редактирование опроса';
$_['text_add'] = 'Создать опрос';
$_['text_list'] = 'Список опросов';
$_['tab_general'] = 'Основные настройки';
$_['tab_visual'] = 'Дизайн и цвета';
$_['tab_stats'] = 'Статистика и накрутка';
$_['tab_info'] = 'Инфо';
$_['tab_polls'] = 'Опросы';
$_['entry_status'] = 'Статус';
$_['entry_question'] = 'Вопрос';
$_['entry_answers'] = 'Варианты ответов';
$_['help_answers'] = 'Каждый вариант с новой строки.';
$_['entry_thanks_text'] = 'Текст благодарности';
$_['entry_guest'] = 'Голосование гостей';
$_['entry_limit'] = 'Лимит голосов';
$_['help_limit'] = 'Сколько раз может проголосовать один пользователь/IP (0 - без лимита)';
$_['entry_result_type'] = 'Формат результатов';
$_['text_res_percent'] = 'Проценты (%)';
$_['text_res_count'] = 'Количество голосов';
$_['text_res_both'] = 'Всё вместе ( % / Кол-во )';
$_['text_res_none'] = 'Скрыть (только благодарность)';
$_['entry_bg_color'] = 'Фон блока';
$_['entry_text_color'] = 'Цвет текста';
$_['entry_border_color'] = 'Цвет рамок';
$_['entry_btn_bg'] = 'Цвет кнопки';
$_['entry_btn_color'] = 'Текст кнопки';
$_['entry_bar_bg'] = 'Фон полосы прогресса';
$_['entry_bar_fill'] = 'Заливка полосы прогресса';
$_['column_question'] = 'Вопрос';
$_['column_status'] = 'Статус';
$_['column_action'] = 'Действие';
$_['text_stats_info'] = 'Управление статистикой: здесь отображаются реальные данные и возможность их корректировки.';
$_['column_answer'] = 'Вариант ответа';
$_['column_real'] = 'Реально';
$_['column_custom'] = 'Управление статистикой (+/-)';
$_['text_no_answers_yet'] = 'Сначала заполните варианты ответов и сохраните опрос!';
$_['text_log_title'] = 'Журнал голосов (Всего: %s)';
$_['column_who'] = 'Кто';
$_['column_ip'] = 'IP';
$_['column_page'] = 'Страница';
$_['column_date'] = 'Дата';
$_['text_answer_prefix'] = 'Ответ:';
$_['text_guest'] = 'Guest';
$_['text_no_results'] = 'Нет данных для отображения';
$_['text_ecosystem'] = 'Экосистема [NAT]';
$_['text_catalog_opt_desc'] = 'Скрытие пустых категорий и брендов + SEO сортировка товаров (в наличии сверху) + Очистка мусора БД.';
$_['text_img_opt_desc'] = 'Сжатие оригиналов (image/catalog) в WebP + Массовая очистка хостинга от лишних картинок.';
$_['text_domain_scan_desc'] = 'Поиск и чистка внешних ссылок и HTTP-картинок в описаниях БД (идеально для перехода на HTTPS).';
$_['text_support_info'] = 'Техническая поддержка и пожелания:';
$_['button_all_modules'] = 'Смотреть все модули [NAT]';
$_['error_permission'] = 'У вас нет прав для управления этим модулем!';
$_['error_question'] = 'Вопрос должен быть от 3 до 255 символов!';
$_['entry_license'] = 'Лицензионный ключ';
$_['entry_show_total'] = 'Показывать "Всего проголосовало"';
$_['entry_total_access'] = 'Кто видит счетчик';
$_['text_access_all'] = 'Все посетители';
$_['text_access_reg'] = 'Только авторизованные';
$_['text_footer_ecosystem'] = 'Разработано для экосистемы <strong>[NAT]</strong>. Поддержка: <a href="mailto:info@nat.od.ua">info@nat.od.ua</a>';
$_['text_other_modules'] = 'Другие модули серии [NAT]:';
$_['text_new_arrivals_title'] = 'New Arrivals [NAT]: True Sort by Date';
$_['text_new_arrivals_desc'] = 'Автоматическая SEO-страница новинок. Отображение товаров строго по реальной дате добавления. Слайдеры, сетки и умный сайдбар архива дат.';
$_['text_catalog_opt_title'] = 'Catalog Optimizer [NAT]';
$_['text_catalog_opt_desc'] = 'Скрытие пустых категорий и брендов + SEO сортировка товаров (в наличии сверху) + очистка мусора БД.';
$_['text_img_opt_title'] = 'Image Optimizer [NAT]';
$_['text_img_opt_desc'] = 'Сжатие оригинальных изображений в WebP + массовая очистка неиспользуемых изображений на сервере.';
$_['text_domain_scan_title'] = 'Domain Scanner [NAT]';
$_['text_domain_scan_desc'] = 'Поиск и очистка внешних ссылок и HTTP-изображений в БД и файлах темы. Идеально для перехода на HTTPS или очистки после парсинга.';
$_['text_confirm_delete'] = 'Удалить этот опрос? Все голоса будут стерты!';
$_['text_license_warning'] = 'Введите валидный лицензионный ключ для активации модуля и начала работы.';
$_['entry_menu_position'] = 'Позиция в меню админки';
$_['text_menu_module'] = 'Только в модулях';
$_['text_menu_header'] = 'В шапке (верхняя панель)';
$_['text_menu_sidebar'] = 'В боковом меню (слева)';
$_['text_menu_both'] = 'Везде (Шапка + Сайдбар)';
$_['error_form'] = 'Внимательно проверьте форму на наличие ошибок!';
$_['text_database_opt_title'] = 'Database Optimizer [NAT]';
$_['text_database_opt_desc'] = 'Интеллектуальная очистка мусора БД, управление системными логами и добавление критических индексов для ускорения сайта.';
$_['text_admin_tools_title'] = 'Admin Tools [NAT]';
$_['text_admin_tools_desc'] = 'Удобные инструменты администратора: вход под клиентом, кастомизация админки, управление правами и скрытие ненужных пунктов меню.';
$_['text_easy_import_title'] = 'Easy Import/Export [NAT]';
$_['text_easy_import_desc'] = 'Быстрый импорт/экспорт цен, остатков и товаров из XLS/XLSX/CSV/XML/JSON. Сопоставление полей, Cron и поддержка ссылок.';
$_['text_utm_tracker_title'] = 'Order UTM Tracker [NAT]';
$_['text_utm_tracker_desc'] = 'Автоматическое отслеживание UTM-меток при оформлении заказа. Сохраняет источник трафика, кампанию, ключевые слова и выводит эти данные в деталях заказа для анализа эффективности рекламы.';
$_['text_poll_widget_title'] = 'Poll Widget [NAT]';
$_['text_poll_widget_desc'] = 'Создание опросов и виджетов голосования с визуальным конструктором дизайна, детальной статистикой и защитой от накрутки.';
$_['text_current_module'] = 'Текущий модуль';
$_['text_info_title_promo_top_bar'] = 'Promo Top Bar [NAT]: Верхний рекламный инфо-баннер, информационная полоса над шапкой, бегущая строка и топ-баннер';
$_['text_info_desc_promo_top_bar'] = 'Создание интерактивных промо-панелей и слайд-шоу в шапке сайта с конструктором блоков, таймерами, формой подписки и гибким таргетингом.';

View File

@ -0,0 +1,90 @@
<?php
$_['heading_title'] = '<b>Poll Widget [NAT]:</b> Опитування та голосування';
$_['heading_title_raw'] = 'Poll Widget [NAT]: Опитування та голосування';
$_['text_extension'] = 'Розширення';
$_['text_success'] = 'Налаштування модуля успішно оновлено!';
$_['text_edit'] = 'Редагування опитування';
$_['text_add'] = 'Створити опитування';
$_['text_list'] = 'Список опитувань';
$_['tab_general'] = 'Основні налаштування';
$_['tab_visual'] = 'Дизайн та кольори';
$_['tab_stats'] = 'Статистика';
$_['tab_info'] = 'Інфо';
$_['tab_polls'] = 'Опитування';
$_['entry_status'] = 'Статус';
$_['entry_question'] = 'Питання';
$_['entry_answers'] = 'Варіанти відповідей';
$_['help_answers'] = 'Кожен варіант з нового рядка.';
$_['entry_thanks_text'] = 'Текст подяки';
$_['entry_guest'] = 'Голосування гостей';
$_['entry_limit'] = 'Ліміт голосів';
$_['help_limit'] = 'Скільки разів може проголосувати один користувач/IP (0 - без ліміту)';
$_['entry_result_type'] = 'Формат результатів';
$_['text_res_percent'] = 'Відсотки (%)';
$_['text_res_count'] = 'Кількість голосів';
$_['text_res_both'] = 'Все разом ( % / Кіл-ть )';
$_['text_res_none'] = 'Приховати (тільки подяка)';
$_['entry_bg_color'] = 'Фон блоку';
$_['entry_text_color'] = 'Колір тексту';
$_['entry_border_color'] = 'Колір рамок';
$_['entry_btn_bg'] = 'Колір кнопки';
$_['entry_btn_color'] = 'Текст кнопки';
$_['entry_bar_bg'] = 'Фон смуги прогресу';
$_['entry_bar_fill'] = 'Заливка смуги прогресу';
$_['column_question'] = 'Питання';
$_['column_status'] = 'Статус';
$_['column_action'] = 'Дія';
$_['text_stats_info'] = 'Управління статистикою: реальні дані та можливість їх коригування.';
$_['column_answer'] = 'Варіант відповіді';
$_['column_real'] = 'Реально';
$_['column_custom'] = 'Управління статистикою (+/-)';
$_['text_no_answers_yet'] = 'Спочатку заповніть варіанти відповідей та збережіть опитування!';
$_['text_log_title'] = 'Журнал голосів (Всього: %s)';
$_['column_who'] = 'Хто';
$_['column_ip'] = 'IP';
$_['column_page'] = 'Сторінка';
$_['column_date'] = 'Дата';
$_['text_answer_prefix'] = 'Відповідь:';
$_['text_guest'] = 'Guest';
$_['text_no_results'] = 'Немає даних для відображення';
$_['text_ecosystem'] = 'Екосистема [NAT]';
$_['text_support_info'] = 'Технічна підтримка та побажання:';
$_['button_all_modules'] = 'Дивитись усі модулі [NAT]';
$_['error_permission'] = 'У вас немає прав для керування цим модулем!';
$_['error_question'] = 'Питання має містити від 3 до 255 символів!';
$_['entry_license'] = 'Ліцензійний ключ';
$_['entry_show_total'] = 'Показувати "Всього проголосувало"';
$_['entry_total_access'] = 'Хто бачить лічильник';
$_['text_access_all'] = 'Всі відвідувачі';
$_['text_access_reg'] = 'Тільки авторизовані';
$_['text_footer_ecosystem'] = 'Розроблено для екосистеми <strong>[NAT]</strong>. Підтримка: <a href="mailto:info@nat.od.ua">info@nat.od.ua</a>';
$_['text_other_modules'] = 'Інші модулі серії [NAT]:';
$_['text_new_arrivals_title'] = 'New Arrivals [NAT]: True Sort by Date';
$_['text_new_arrivals_desc'] = 'Автоматична SEO-сторінка новинок. Відображення товарів суворо за реальною датою додавання. Слайдери, сітки та розумний сайдбар архіву дат.';
$_['text_catalog_opt_title'] = 'Catalog Optimizer [NAT]';
$_['text_catalog_opt_desc'] = 'Приховування порожніх категорій і брендів + SEO сортування товарів (в наявності зверху) + очищення сміття БД.';
$_['text_img_opt_title'] = 'Image Optimizer [NAT]';
$_['text_img_opt_desc'] = 'Стиснення оригінальних зображень у WebP + масове очищення невикористовуваних зображень на сервері.';
$_['text_domain_scan_title'] = 'Domain Scanner [NAT]';
$_['text_domain_scan_desc'] = 'Пошук та очищення зовнішніх посилань та HTTP-зображень у БД та файлах теми. Ідеально для переходу на HTTPS або очищення після парсингу.';
$_['text_confirm_delete'] = 'Видалити це опитування? Всі голоси будуть стерті!';
$_['text_license_warning'] = 'Введіть валідний ліцензійний ключ для активації модуля та початку роботи.';
$_['entry_menu_position'] = 'Позиція в меню адмінки';
$_['text_menu_module'] = 'Тільки в модулях';
$_['text_menu_header'] = 'У шапці (верхня панель)';
$_['text_menu_sidebar'] = 'У бічному меню (зліва)';
$_['text_menu_both'] = 'Скрізь (Шапка + Сайдбар)';
$_['error_form'] = 'Уважно перевірте форму на наявність помилок!';
$_['text_database_opt_title'] = 'Database Optimizer [NAT]';
$_['text_database_opt_desc'] = 'Інтелектуальне очищення сміття БД, керування системними логами та додавання критичних індексів для прискорення сайту.';
$_['text_admin_tools_title'] = 'Admin Tools [NAT]';
$_['text_admin_tools_desc'] = 'Зручні інструменти адміністратора: вхід під клієнтом, кастомізація адмінки, керування правами та приховування непотрібних пунктів меню.';
$_['text_easy_import_title'] = 'Easy Import/Export [NAT]';
$_['text_easy_import_desc'] = 'Швидкий імпорт/экспорт цін, залишків та товарів з XLS/XLSX/CSV/XML/JSON. Зіставлення полів, Cron та підтримка посилань.';
$_['text_utm_tracker_title'] = 'Order UTM Tracker [NAT]';
$_['text_utm_tracker_desc'] = 'Автоматичне відстеження UTM-міток при офомленні замовлення. Зберігає джерело трафіку, кампанію, кодові слова та виводить ці дані в деталях замовлення для аналізу ефективності реклами.';
$_['text_poll_widget_title'] = 'Poll Widget [NAT]';
$_['text_poll_widget_desc'] = 'Створення опитувань та віджетів голосування з візуальним конструктором дизайну, детальною статистикою та захистом від накрутки.';
$_['text_current_module'] = 'Поточний модуль';
$_['text_info_title_promo_top_bar'] = 'Promo Top Bar [NAT]: Верхній рекламний інфо-баннер, інформаційна смуга над шапкою, рухомий рядок та топ-баннер';
$_['text_info_desc_promo_top_bar'] = 'Створення інтерактивних промо-панелей та слайд-шоу в шапці сайту з конструктором блоків, таймерами, формою підписки та гнучким націлюванням.';

View File

@ -0,0 +1,90 @@
<?php
$_['heading_title'] = '<b>Poll Widget [NAT]:</b> Опитування та голосування';
$_['heading_title_raw'] = 'Poll Widget [NAT]: Опитування та голосування';
$_['text_extension'] = 'Розширення';
$_['text_success'] = 'Налаштування модуля успішно оновлено!';
$_['text_edit'] = 'Редагування опитування';
$_['text_add'] = 'Створити опитування';
$_['text_list'] = 'Список опитувань';
$_['tab_general'] = 'Основні налаштування';
$_['tab_visual'] = 'Дизайн та кольори';
$_['tab_stats'] = 'Статистика';
$_['tab_info'] = 'Інфо';
$_['tab_polls'] = 'Опитування';
$_['entry_status'] = 'Статус';
$_['entry_question'] = 'Питання';
$_['entry_answers'] = 'Варіанти відповідей';
$_['help_answers'] = 'Кожен варіант з нового рядка.';
$_['entry_thanks_text'] = 'Текст подяки';
$_['entry_guest'] = 'Голосування гостей';
$_['entry_limit'] = 'Ліміт голосів';
$_['help_limit'] = 'Скільки разів може проголосувати один користувач/IP (0 - без ліміту)';
$_['entry_result_type'] = 'Формат результатів';
$_['text_res_percent'] = 'Відсотки (%)';
$_['text_res_count'] = 'Кількість голосів';
$_['text_res_both'] = 'Все разом ( % / Кіл-ть )';
$_['text_res_none'] = 'Приховати (тільки подяка)';
$_['entry_bg_color'] = 'Фон блоку';
$_['entry_text_color'] = 'Колір тексту';
$_['entry_border_color'] = 'Колір рамок';
$_['entry_btn_bg'] = 'Колір кнопки';
$_['entry_btn_color'] = 'Текст кнопки';
$_['entry_bar_bg'] = 'Фон смуги прогресу';
$_['entry_bar_fill'] = 'Заливка смуги прогресу';
$_['column_question'] = 'Питання';
$_['column_status'] = 'Статус';
$_['column_action'] = 'Дія';
$_['text_stats_info'] = 'Управління статистикою: реальні дані та можливість їх коригування.';
$_['column_answer'] = 'Варіант відповіді';
$_['column_real'] = 'Реально';
$_['column_custom'] = 'Управління статистикою (+/-)';
$_['text_no_answers_yet'] = 'Спочатку заповніть варіанти відповідей та збережіть опитування!';
$_['text_log_title'] = 'Журнал голосів (Всього: %s)';
$_['column_who'] = 'Хто';
$_['column_ip'] = 'IP';
$_['column_page'] = 'Сторінка';
$_['column_date'] = 'Дата';
$_['text_answer_prefix'] = 'Відповідь:';
$_['text_guest'] = 'Guest';
$_['text_no_results'] = 'Немає даних для відображення';
$_['text_ecosystem'] = 'Екосистема [NAT]';
$_['text_support_info'] = 'Технічна підтримка та побажання:';
$_['button_all_modules'] = 'Дивитись усі модулі [NAT]';
$_['error_permission'] = 'У вас немає прав для керування цим модулем!';
$_['error_question'] = 'Питання має містити від 3 до 255 символів!';
$_['entry_license'] = 'Ліцензійний ключ';
$_['entry_show_total'] = 'Показувати "Всього проголосувало"';
$_['entry_total_access'] = 'Хто бачить лічильник';
$_['text_access_all'] = 'Всі відвідувачі';
$_['text_access_reg'] = 'Тільки авторизовані';
$_['text_footer_ecosystem'] = 'Розроблено для екосистеми <strong>[NAT]</strong>. Підтримка: <a href="mailto:info@nat.od.ua">info@nat.od.ua</a>';
$_['text_other_modules'] = 'Інші модулі серії [NAT]:';
$_['text_new_arrivals_title'] = 'New Arrivals [NAT]: True Sort by Date';
$_['text_new_arrivals_desc'] = 'Автоматична SEO-сторінка новинок. Відображення товарів суворо за реальною датою додавання. Слайдери, сітки та розумний сайдбар архіву дат.';
$_['text_catalog_opt_title'] = 'Catalog Optimizer [NAT]';
$_['text_catalog_opt_desc'] = 'Приховування порожніх категорій і брендів + SEO сортування товарів (в наявності зверху) + очищення сміття БД.';
$_['text_img_opt_title'] = 'Image Optimizer [NAT]';
$_['text_img_opt_desc'] = 'Стиснення оригінальних зображень у WebP + масове очищення невикористовуваних зображень на сервері.';
$_['text_domain_scan_title'] = 'Domain Scanner [NAT]';
$_['text_domain_scan_desc'] = 'Пошук та очищення зовнішніх посилань та HTTP-зображень у БД та файлах теми. Ідеально для переходу на HTTPS або очищення після парсингу.';
$_['text_confirm_delete'] = 'Видалити це опитування? Всі голоси будуть стерті!';
$_['text_license_warning'] = 'Введіть валідний ліцензійний ключ для активації модуля та початку роботи.';
$_['entry_menu_position'] = 'Позиція в меню адмінки';
$_['text_menu_module'] = 'Тільки в модулях';
$_['text_menu_header'] = 'У шапці (верхня панель)';
$_['text_menu_sidebar'] = 'У бічному меню (зліва)';
$_['text_menu_both'] = 'Скрізь (Шапка + Сайдбар)';
$_['error_form'] = 'Уважно перевірте форму на наявність помилок!';
$_['text_database_opt_title'] = 'Database Optimizer [NAT]';
$_['text_database_opt_desc'] = 'Інтелектуальне очищення сміття БД, керування системними логами та додавання критичних індексів для прискорення сайту.';
$_['text_admin_tools_title'] = 'Admin Tools [NAT]';
$_['text_admin_tools_desc'] = 'Зручні інструменти адміністратора: вхід під клієнтом, кастомізація адмінки, керування правами та приховування непотрібних пунктів меню.';
$_['text_easy_import_title'] = 'Easy Import/Export [NAT]';
$_['text_easy_import_desc'] = 'Швидкий імпорт/экспорт цін, залишків та товарів з XLS/XLSX/CSV/XML/JSON. Зіставлення полів, Cron та підтримка посилань.';
$_['text_utm_tracker_title'] = 'Order UTM Tracker [NAT]';
$_['text_utm_tracker_desc'] = 'Автоматичне відстеження UTM-міток при офомленні замовлення. Зберігає джерело трафіку, кампанію, кодові слова та виводить ці дані в деталях замовлення для аналізу ефективності реклами.';
$_['text_poll_widget_title'] = 'Poll Widget [NAT]';
$_['text_poll_widget_desc'] = 'Створення опитувань та віджетів голосування з візуальним конструктором дизайну, детальною статистикою та захистом від накрутки.';
$_['text_current_module'] = 'Поточний модуль';
$_['text_info_title_promo_top_bar'] = 'Promo Top Bar [NAT]: Верхній рекламний інфо-баннер, інформаційна смуга над шапкою, рухомий рядок та топ-баннер';
$_['text_info_desc_promo_top_bar'] = 'Створення інтерактивних промо-панелей та слайд-шоу в шапці сайту з конструктором блоків, таймерами, формою підписки та гнучким націлюванням.';

View File

@ -0,0 +1,163 @@
<?php
if (!defined('VERSION')) exit;
class ModelModulePollWidgetNat extends Model {
public function addPoll($data) {
$status = (int)$data['status'];
$config = $this->db->escape(json_encode($data['config']));
$colors = $this->db->escape(json_encode($data['colors']));
$custom_stats = $this->db->escape(json_encode($data['custom_stats']));
$this->db->query("INSERT INTO `" . DB_PREFIX . "poll_widget_nat` SET status = '" . $status . "', config = '" . $config . "', colors = '" . $colors . "', custom_stats = '" . $custom_stats . "', date_added = NOW()");
$poll_id = $this->db->getLastId();
if (isset($data['poll_description']) && is_array($data['poll_description'])) {
foreach ($data['poll_description'] as $language_id => $value) {
$q = $this->db->escape((string)$value['question']);
$a = $this->db->escape((string)$value['answers']);
$t_text = $this->db->escape((string)$value['thanks_text']);
$this->db->query("INSERT INTO `" . DB_PREFIX . "poll_widget_nat_description` SET poll_id = '" . (int)$poll_id . "', language_id = '" . (int)$language_id . "', question = '" . $q . "', answers = '" . $a . "', thanks_text = '" . $t_text . "'");
}
}
$lang_id = (int)$this->config->get('config_language_id');
$name = isset($data['poll_description'][$lang_id]['question']) ? (string)$data['poll_description'][$lang_id]['question'] : 'Опрос #' . $poll_id;
$setting = array(
'name' => $name,
'poll_id' => $poll_id,
'status' => $status
);
$this->db->query("INSERT INTO `" . DB_PREFIX . "module` SET `name` = '" . $this->db->escape($name) . "', `code` = 'poll_widget_nat', `setting` = '" . $this->db->escape(json_encode($setting)) . "'");
return $poll_id;
}
public function editPoll($poll_id, $data) {
$poll_id = (int)$poll_id;
$status = (int)$data['status'];
$config = $this->db->escape(json_encode($data['config']));
$colors = $this->db->escape(json_encode($data['colors']));
$custom_stats = $this->db->escape(json_encode($data['custom_stats']));
$this->db->query("UPDATE `" . DB_PREFIX . "poll_widget_nat` SET status = '" . $status . "', config = '" . $config . "', colors = '" . $colors . "', custom_stats = '" . $custom_stats . "' WHERE poll_id = '" . $poll_id . "'");
$this->db->query("DELETE FROM `" . DB_PREFIX . "poll_widget_nat_description` WHERE poll_id = '" . $poll_id . "'");
if (isset($data['poll_description']) && is_array($data['poll_description'])) {
foreach ($data['poll_description'] as $language_id => $value) {
$q = $this->db->escape((string)$value['question']);
$a = $this->db->escape((string)$value['answers']);
$t_text = $this->db->escape((string)$value['thanks_text']);
$this->db->query("INSERT INTO `" . DB_PREFIX . "poll_widget_nat_description` SET poll_id = '" . $poll_id . "', language_id = '" . (int)$language_id . "', question = '" . $q . "', answers = '" . $a . "', thanks_text = '" . $t_text . "'");
}
}
$lang_id = (int)$this->config->get('config_language_id');
$name = isset($data['poll_description'][$lang_id]['question']) ? (string)$data['poll_description'][$lang_id]['question'] : 'Опрос #' . $poll_id;
$setting = array(
'name' => $name,
'poll_id' => $poll_id,
'status' => $status
);
$module_query = $this->db->query("SELECT module_id, setting FROM `" . DB_PREFIX . "module` WHERE `code` = 'poll_widget_nat'");
$found = false;
foreach ($module_query->rows as $row) {
$mod_setting = json_decode($row['setting'], true);
if (isset($mod_setting['poll_id']) && (int)$mod_setting['poll_id'] === $poll_id) {
$this->db->query("UPDATE `" . DB_PREFIX . "module` SET `name` = '" . $this->db->escape($name) . "', `setting` = '" . $this->db->escape(json_encode($setting)) . "' WHERE module_id = '" . (int)$row['module_id'] . "'");
$found = true;
break;
}
}
if (!$found) {
$this->db->query("INSERT INTO `" . DB_PREFIX . "module` SET `name` = '" . $this->db->escape($name) . "', `code` = 'poll_widget_nat', `setting` = '" . $this->db->escape(json_encode($setting)) . "'");
}
}
public function deletePoll($poll_id) {
$poll_id = (int)$poll_id;
$this->db->query("DELETE FROM `" . DB_PREFIX . "poll_widget_nat` WHERE poll_id = '" . $poll_id . "'");
$this->db->query("DELETE FROM `" . DB_PREFIX . "poll_widget_nat_description` WHERE poll_id = '" . $poll_id . "'");
$this->db->query("DELETE FROM `" . DB_PREFIX . "poll_widget_nat_vote` WHERE poll_id = '" . $poll_id . "'");
$module_query = $this->db->query("SELECT module_id, setting FROM `" . DB_PREFIX . "module` WHERE `code` = 'poll_widget_nat'");
foreach ($module_query->rows as $row) {
$mod_setting = json_decode($row['setting'], true);
if (isset($mod_setting['poll_id']) && (int)$mod_setting['poll_id'] === $poll_id) {
$mod_id = (int)$row['module_id'];
$this->db->query("DELETE FROM `" . DB_PREFIX . "module` WHERE module_id = '" . $mod_id . "'");
$this->db->query("DELETE FROM `" . DB_PREFIX . "layout_module` WHERE `code` = 'poll_widget_nat." . $mod_id . "'");
break;
}
}
}
public function getPoll($poll_id) {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "poll_widget_nat` WHERE poll_id = '" . (int)$poll_id . "'");
return $query->row;
}
public function getPollDescriptions($poll_id) {
$poll_description_data = array();
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "poll_widget_nat_description` WHERE poll_id = '" . (int)$poll_id . "'");
foreach ($query->rows as $result) {
$poll_description_data[$result['language_id']] = array(
'question' => $result['question'],
'answers' => $result['answers'],
'thanks_text' => $result['thanks_text']
);
}
return $poll_description_data;
}
public function getPolls() {
$lang_id = (int)$this->config->get('config_language_id');
$sql = "SELECT p.poll_id, pd.question, p.status FROM `" . DB_PREFIX . "poll_widget_nat` p LEFT JOIN `" . DB_PREFIX . "poll_widget_nat_description` pd ON (p.poll_id = pd.poll_id) WHERE pd.language_id = '" . $lang_id . "' ORDER BY p.date_added DESC";
$query = $this->db->query($sql);
return $query->rows;
}
public function getVotes($poll_id, $start = 0, $limit = 10) {
$poll_id = (int)$poll_id;
$start = (int)$start;
$limit = (int)$limit;
if ($start < 0) {
$start = 0;
}
if ($limit < 1) {
$limit = 10;
}
$sql = "SELECT v.*, c.firstname, c.lastname, c.email FROM `" . DB_PREFIX . "poll_widget_nat_vote` v LEFT JOIN `" . DB_PREFIX . "customer` c ON (v.customer_id = c.customer_id) WHERE v.poll_id = '" . $poll_id . "' ORDER BY v.date_added DESC LIMIT " . $start . "," . $limit;
$query = $this->db->query($sql);
return $query->rows;
}
public function getTotalVotes($poll_id) {
$query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "poll_widget_nat_vote` WHERE poll_id = '" . (int)$poll_id . "'");
return (int)$query->row['total'];
}
public function getVotesCountByIndex($poll_id) {
$vote_data = array();
$query = $this->db->query("SELECT answer_index, COUNT(*) AS total FROM `" . DB_PREFIX . "poll_widget_nat_vote` WHERE poll_id = '" . (int)$poll_id . "' GROUP BY answer_index");
foreach ($query->rows as $result) {
$vote_data[(int)$result['answer_index']] = (int)$result['total'];
}
return $vote_data;
}
}

View File

@ -0,0 +1,352 @@
<?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-poll" 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 alert-dismissible"><i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php } ?>
<div class="panel panel-default">
<div class="panel-heading" style="background: #2c3e50; color: white;">
<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-poll" class="form-horizontal">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-general" data-toggle="tab"><i class="fa fa-cog"></i> <?php echo $tab_general; ?></a></li>
<li><a href="#tab-visual" data-toggle="tab"><i class="fa fa-paint-brush"></i> <?php echo $tab_visual; ?></a></li>
<li><a href="#tab-stats" data-toggle="tab"><i class="fa fa-bar-chart"></i> <?php echo $tab_stats; ?></a></li>
<li><a href="#tab-info" data-toggle="tab"><i class="fa fa-info-circle"></i> <?php echo $tab_info; ?></a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-general">
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $entry_status; ?></label>
<div class="col-sm-10">
<select name="status" class="form-control">
<option value="1" <?php if ($status == '1') { ?>selected="selected"<?php } ?>><?php echo $text_enabled; ?></option>
<option value="0" <?php if ($status == '0') { ?>selected="selected"<?php } ?>><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
<ul class="nav nav-tabs" id="language">
<?php foreach ($languages as $language) { ?>
<li><a href="#language<?php echo $language['language_id']; ?>" data-toggle="tab">
<?php if (version_compare(VERSION, '2.2.0.0', '<')) { ?>
<img src="view/image/flags/<?php echo $language['image']; ?>" title="<?php echo $language['name']; ?>" />
<?php } else { ?>
<img src="language/<?php echo $language['code']; ?>/<?php echo $language['code']; ?>.png" title="<?php echo $language['name']; ?>" />
<?php } ?>
<?php echo $language['name']; ?></a></li>
<?php } ?>
</ul>
<div class="tab-content">
<?php foreach ($languages as $language) { ?>
<div class="tab-pane" id="language<?php echo $language['language_id']; ?>">
<div class="form-group required">
<label class="col-sm-2 control-label"><?php echo $entry_question; ?></label>
<div class="col-sm-10">
<input type="text" name="poll_description[<?php echo $language['language_id']; ?>][question]" value="<?php echo isset($poll_description[$language['language_id']]) ? $poll_description[$language['language_id']]['question'] : ''; ?>" placeholder="<?php echo $entry_question; ?>" class="form-control" />
<?php if (isset($error_question[$language['language_id']])) { ?>
<div class="text-danger"><?php echo $error_question[$language['language_id']]; ?></div>
<?php } ?>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><span data-toggle="tooltip" title="<?php echo $help_answers; ?>"><?php echo $entry_answers; ?></span></label>
<div class="col-sm-10">
<textarea name="poll_description[<?php echo $language['language_id']; ?>][answers]" rows="5" placeholder="<?php echo $entry_answers; ?>" class="form-control"><?php echo isset($poll_description[$language['language_id']]) ? $poll_description[$language['language_id']]['answers'] : ''; ?></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $entry_thanks_text; ?></label>
<div class="col-sm-10">
<textarea name="poll_description[<?php echo $language['language_id']; ?>][thanks_text]" rows="3" placeholder="<?php echo $entry_thanks_text; ?>" class="form-control"><?php echo isset($poll_description[$language['language_id']]) ? $poll_description[$language['language_id']]['thanks_text'] : ''; ?></textarea>
</div>
</div>
</div>
<?php } ?>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $entry_guest; ?></label>
<div class="col-sm-10">
<select name="config[guest]" class="form-control">
<option value="1" <?php if (isset($config['guest']) && $config['guest'] == '1') { ?>selected="selected"<?php } ?>><?php echo $text_yes; ?></option>
<option value="0" <?php if (!isset($config['guest']) || $config['guest'] == '0') { ?>selected="selected"<?php } ?>><?php echo $text_no; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><span data-toggle="tooltip" title="<?php echo $help_limit; ?>"><?php echo $entry_limit; ?></span></label>
<div class="col-sm-10">
<input type="number" name="config[limit]" value="<?php echo isset($config['limit']) ? $config['limit'] : 1; ?>" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $entry_result_type; ?></label>
<div class="col-sm-10">
<select name="config[result_type]" class="form-control">
<option value="percent" <?php if (isset($config['result_type']) && $config['result_type'] == 'percent') { ?>selected="selected"<?php } ?>><?php echo $text_res_percent; ?></option>
<option value="count" <?php if (isset($config['result_type']) && $config['result_type'] == 'count') { ?>selected="selected"<?php } ?>><?php echo $text_res_count; ?></option>
<option value="both" <?php if (isset($config['result_type']) && $config['result_type'] == 'both') { ?>selected="selected"<?php } ?>><?php echo $text_res_both; ?></option>
<option value="none" <?php if (isset($config['result_type']) && $config['result_type'] == 'none') { ?>selected="selected"<?php } ?>><?php echo $text_res_none; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $entry_show_total; ?></label>
<div class="col-sm-10">
<select name="config[show_total]" class="form-control">
<option value="1" <?php if (isset($config['show_total']) && $config['show_total'] == '1') { ?>selected="selected"<?php } ?>><?php echo $text_yes; ?></option>
<option value="0" <?php if (!isset($config['show_total']) || $config['show_total'] == '0') { ?>selected="selected"<?php } ?>><?php echo $text_no; ?></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $entry_total_access; ?></label>
<div class="col-sm-10">
<select name="config[total_access]" class="form-control">
<option value="all" <?php if (isset($config['total_access']) && $config['total_access'] == 'all') { ?>selected="selected"<?php } ?>><?php echo $text_access_all; ?></option>
<option value="registered" <?php if (isset($config['total_access']) && $config['total_access'] == 'registered') { ?>selected="selected"<?php } ?>><?php echo $text_access_reg; ?></option>
</select>
</div>
</div>
</div>
<div class="tab-pane" id="tab-visual">
<?php
$color_fields = array(
'bg' => $entry_bg_color,
'text' => $entry_text_color,
'border' => $entry_border_color,
'btn_bg' => $entry_btn_bg,
'btn_color' => $entry_btn_color,
'bar_bg' => $entry_bar_bg,
'bar_fill' => $entry_bar_fill
);
?>
<?php foreach ($color_fields as $key => $label) { ?>
<div class="form-group">
<label class="col-sm-2 control-label"><?php echo $label; ?></label>
<div class="col-sm-4">
<div class="input-group">
<span class="input-group-addon" style="padding: 0; border: none; background: none;">
<input type="color" value="<?php echo isset($colors[$key]) ? $colors[$key] : '#ffffff'; ?>" oninput="$(this).parent().next().val(this.value)" style="width: 40px; height: 35px; border: 1px solid #ddd; cursor: pointer; padding: 0;">
</span>
<input type="text" name="colors[<?php echo $key; ?>]" value="<?php echo isset($colors[$key]) ? $colors[$key] : '#ffffff'; ?>" class="form-control" style="height: 35px;" oninput="$(this).prev().find('input').val(this.value)" />
</div>
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane" id="tab-stats">
<div class="alert alert-info"><i class="fa fa-info-circle"></i> <?php echo $text_stats_info; ?></div>
<div class="row">
<div class="col-sm-5">
<table class="table table-bordered">
<thead>
<tr style="background: #f9f9f9;">
<th><?php echo $column_answer; ?></th>
<th class="text-center"><?php echo $column_real; ?></th>
<th class="text-center"><?php echo $column_custom; ?></th>
</tr>
</thead>
<tbody>
<?php if ($answers_map) { ?>
<?php foreach ($answers_map as $index => $text) { ?>
<tr>
<td><?php echo $text; ?></td>
<td class="text-center"><span class="label label-info" style="font-size:12px;"><?php echo isset($voted_total[$index]) ? $voted_total[$index] : 0; ?></span></td>
<td><input type="number" name="custom_stats[<?php echo $index; ?>]" value="<?php echo isset($custom_stats[$index]) ? $custom_stats[$index] : 0; ?>" class="form-control input-sm" /></td>
</tr>
<?php } ?>
<?php } else { ?>
<tr>
<td colspan="3" class="text-center"><?php echo $text_no_answers_yet; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<div class="col-sm-7">
<div style="max-height: 500px; overflow-y: auto;">
<table class="table table-striped table-bordered">
<thead>
<tr><th colspan="4" class="text-center" style="background: #2c3e50; color:#fff;"><?php echo sprintf($text_log_title, $total_votes_count); ?></th></tr>
<tr>
<th><?php echo $column_who; ?></th>
<th><?php echo $column_ip; ?></th>
<th><?php echo $column_page; ?></th>
<th><?php echo $column_date; ?></th>
</tr>
</thead>
<tbody>
<?php if ($latest_votes) { ?>
<?php foreach ($latest_votes as $vote) { ?>
<tr>
<td>
<strong><?php echo $vote['user']; ?></strong><br>
<small class="text-muted"><?php echo $text_answer_prefix; ?> <span style="color:#2980b9;"><?php echo $vote['answer']; ?></span></small>
</td>
<td><?php echo $vote['ip']; ?></td>
<td>
<?php if ($vote['page_url']) { ?>
<a href="<?php echo $vote['page_url']; ?>" target="_blank" title="<?php echo $vote['page_url']; ?>" class="btn btn-default btn-xs"><i class="fa fa-external-link"></i></a>
<?php } else { ?>
-
<?php } ?>
</td>
<td><small><?php echo $vote['date']; ?></small></td>
</tr>
<?php } ?>
<?php } else { ?>
<tr><td colspan="4" class="text-center"><?php echo $text_no_results; ?></td></tr>
<?php } ?>
</tbody>
</table>
<div class="pagination-wrapper"><?php echo $pagination; ?></div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab-info">
<div class="alert alert-info" style="font-size: 15px;">
<i class="fa fa-info-circle"></i> <?php echo $text_footer_ecosystem; ?>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-cogs text-primary"></i> <?php echo $text_catalog_opt_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_catalog_opt_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-calendar-plus-o text-primary"></i> <?php echo $text_new_arrivals_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_new_arrivals_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-image text-primary"></i> <?php echo $text_img_opt_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_img_opt_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-search text-primary"></i> <?php echo $text_domain_scan_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_domain_scan_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff; border: 1px dashed #2980b9;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-question-circle text-primary"></i> <?php echo $text_poll_widget_title; ?></b> <span class="label label-success" style="font-size: 10px; vertical-align: middle;"><?php echo isset($text_current_module) ? $text_current_module : 'Текущий модуль'; ?></span></h4>
<p style="font-size: 13px;"><?php echo $text_poll_widget_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-database text-primary"></i> <?php echo $text_database_opt_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_database_opt_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-exchange text-primary"></i> <?php echo $text_easy_import_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_easy_import_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-wrench text-primary"></i> <?php echo $text_admin_tools_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_admin_tools_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-line-chart text-primary"></i> <?php echo $text_utm_tracker_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_utm_tracker_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-bullhorn text-primary"></i> <?php echo $text_info_title_promo_top_bar; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_info_desc_promo_top_bar; ?></p>
</div>
</div>
</div>
<div class="text-center" style="margin-top: 20px;">
<a href="https://www.opencart.com/index.php?route=marketplace/extension&amp;filter_member=nat.odua" target="_blank" class="btn btn-primary btn-lg" style="margin: 5px;">
<i class="fa fa-opencart"></i> OpenCart.com
</a>
<a href="https://opencartforum.com/ru/files/developer/725443-nertyod/" target="_blank" class="btn btn-info btn-lg" style="margin: 5px; background-color: #2980b9; border-color: #2980b9;">
<i class="fa fa-users"></i> OpenCartForum
</a>
</div>
</div>
</div>
</form>
</div>
<div class="panel-footer text-center" style="background: #f9f9f9; padding: 15px; border-top: 1px solid #e5e5e5;">
<?php echo $text_footer_ecosystem; ?>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#language a:first').tab('show');
// Сохранение/восстановление активной вкладки
var tabStorageKey = 'nat_active_tab_poll_widget_nat';
var $mainTabs = $('#form-poll > ul.nav-tabs');
var savedTab = localStorage.getItem(tabStorageKey);
if (savedTab) {
var $target = $mainTabs.find('a[href="' + savedTab + '"]');
if ($target.length) {
$target.tab('show');
}
}
$mainTabs.on('shown.bs.tab', 'a[data-toggle="tab"]', function(e) {
localStorage.setItem(tabStorageKey, $(e.target).attr('href'));
});
});
</script>
<?php echo $footer; ?>

View File

@ -0,0 +1,224 @@
<?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-module" data-toggle="tooltip" class="btn btn-primary" title="<?php echo $button_save; ?>">
<i class="fa fa-save"></i>
</button>
<?php if ($is_licensed) { ?>
<a href="<?php echo $add; ?>" data-toggle="tooltip" title="<?php echo $text_add; ?>" class="btn btn-success"><i class="fa fa-plus"></i></a>
<?php } ?>
<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_raw; ?></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 ($success) { ?>
<div class="alert alert-success alert-dismissible"><i class="fa fa-check-circle"></i> <?php echo $success; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php } ?>
<?php if ($error_warning) { ?>
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
<button type="button" class="close" data-dismiss="alert">&times;</button>
</div>
<?php } ?>
<div class="panel panel-default">
<div class="panel-heading" style="background: #2c3e50; color: white;">
<h3 class="panel-title"><i class="fa fa-list"></i> <?php echo $text_list; ?></h3>
</div>
<div class="panel-body">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-general" data-toggle="tab"><?php echo $tab_polls; ?></a></li>
<li><a href="#tab-info" data-toggle="tab"><?php echo $tab_info; ?></a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-general">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-module">
<div class="row">
<div class="col-md-4">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6;">
<label><?php echo $entry_status; ?></label>
<div class="input-group">
<select name="module_poll_widget_nat_status" class="form-control">
<option value="1" <?php if ($module_poll_widget_nat_status) { ?>selected="selected"<?php } ?>><?php echo $text_enabled; ?></option>
<option value="0" <?php if (!$module_poll_widget_nat_status) { ?>selected="selected"<?php } ?>><?php echo $text_disabled; ?></option>
</select>
<span class="input-group-btn">
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i></button>
</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6;">
<label><?php echo $entry_menu_position; ?></label>
<div class="input-group">
<select name="module_poll_widget_nat_menu_position" class="form-control">
<option value="module" <?php if ($module_poll_widget_nat_menu_position == 'module') { ?>selected="selected"<?php } ?>><?php echo $text_menu_module; ?></option>
<option value="header" <?php if ($module_poll_widget_nat_menu_position == 'header') { ?>selected="selected"<?php } ?>><?php echo $text_menu_header; ?></option>
<option value="sidebar" <?php if ($module_poll_widget_nat_menu_position == 'sidebar') { ?>selected="selected"<?php } ?>><?php echo $text_menu_sidebar; ?></option>
<option value="both" <?php if ($module_poll_widget_nat_menu_position == 'both') { ?>selected="selected"<?php } ?>><?php echo $text_menu_both; ?></option>
</select>
<span class="input-group-btn">
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i></button>
</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6;">
<label><?php echo $entry_license; ?></label>
<div class="input-group">
<input type="text" name="module_poll_widget_nat_license" value="<?php echo $module_poll_widget_nat_license; ?>" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn btn-info"><i class="fa fa-refresh"></i></button>
</span>
<span class="input-group-addon">
<?php if ($is_licensed) { ?>
<i class="fa fa-check text-success"></i>
<?php } else { ?>
<i class="fa fa-times text-danger"></i>
<?php } ?>
</span>
</div>
</div>
</div>
</div>
<?php if (!$is_licensed) { ?>
<div class="row">
<div class="col-md-12">
<div class="alert alert-warning">
<i class="fa fa-exclamation-triangle"></i> <?php echo $text_license_warning; ?>
</div>
</div>
</div>
<?php } ?>
</form>
<hr>
<?php if ($is_licensed) { ?>
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<td class="text-left"><?php echo $column_question; ?></td>
<td class="text-center" style="width: 150px;"><?php echo $column_status; ?></td>
<td class="text-right" style="width: 100px;"><?php echo $column_action; ?></td>
</tr>
</thead>
<tbody>
<?php if ($polls) { ?>
<?php foreach ($polls as $poll) { ?>
<tr>
<td class="text-left"><strong><?php echo $poll['question']; ?></strong></td>
<td class="text-center">
<?php if ($poll['status'] == $text_enabled) { ?>
<span class="label label-success"><?php echo $poll['status']; ?></span>
<?php } else { ?>
<span class="label label-danger"><?php echo $poll['status']; ?></span>
<?php } ?>
</td>
<td class="text-right">
<a href="<?php echo $poll['edit']; ?>" data-toggle="tooltip" title="<?php echo $button_edit; ?>" class="btn btn-primary btn-sm"><i class="fa fa-pencil"></i></a>
<a href="<?php echo $poll['delete']; ?>" data-toggle="tooltip" title="<?php echo $button_delete; ?>" class="btn btn-danger btn-sm" onclick="return confirm('<?php echo $text_confirm_delete; ?>');"><i class="fa fa-trash-o"></i></a>
</td>
</tr>
<?php } ?>
<?php } else { ?>
<tr>
<td class="text-center" colspan="3"><?php echo $text_no_results; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<?php } ?>
</div>
<div class="tab-pane" id="tab-info">
<div class="alert alert-info" style="font-size: 15px;">
<i class="fa fa-info-circle"></i> <?php echo $text_footer_ecosystem; ?>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-cogs text-primary"></i> <?php echo $text_catalog_opt_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_catalog_opt_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-database text-primary"></i> <?php echo $text_database_opt_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_database_opt_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-image text-primary"></i> <?php echo $text_img_opt_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_img_opt_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-search text-primary"></i> <?php echo $text_domain_scan_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_domain_scan_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-calendar-plus-o text-primary"></i> <?php echo $text_new_arrivals_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_new_arrivals_desc; ?></p>
</div>
</div>
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-wrench text-primary"></i> <?php echo $text_admin_tools_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_admin_tools_desc; ?></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="well" style="min-height: 140px; background: #fff;">
<h4 style="margin-top:0; color: #2c3e50;"><b><i class="fa fa-exchange text-primary"></i> <?php echo $text_easy_import_title; ?></b></h4>
<p style="font-size: 13px;"><?php echo $text_easy_import_desc; ?></p>
</div>
</div>
</div>
<div class="text-center" style="margin-top: 20px;">
<a href="https://www.opencart.com/index.php?route=marketplace/extension&amp;filter_member=nat.odua" target="_blank" class="btn btn-primary btn-lg" style="margin: 5px;">
<i class="fa fa-opencart"></i> OpenCart.com
</a>
<a href="https://opencartforum.com/ru/files/developer/725443-nertyod/" target="_blank" class="btn btn-info btn-lg" style="margin: 5px; background-color: #2980b9; border-color: #2980b9;">
<i class="fa fa-users"></i> OpenCartForum
</a>
</div>
</div>
</div>
</div>
<div class="panel-footer text-center" style="background: #f9f9f9; padding: 15px; border-top: 1px solid #e5e5e5;">
<?php echo $text_footer_ecosystem; ?>
</div>
</div>
</div>
</div>
<?php echo $footer; ?>

View File

@ -0,0 +1,210 @@
<?php
if (!defined('VERSION')) exit;
class ControllerModulePollWidgetNat extends Controller {
public function index($setting) {
if (!isset($setting['poll_id'])) {
return false;
}
$poll_id = (int)$setting['poll_id'];
$this->load->model('module/poll_widget_nat');
$this->load->language('module/poll_widget_nat');
$poll_info = $this->model_module_poll_widget_nat->getPoll($poll_id);
if (!$poll_info) {
return false;
}
$description = $this->model_module_poll_widget_nat->getPollDescription($poll_id);
if (!$description) {
return false;
}
$data['poll_id'] = (int)$poll_info['poll_id'];
$data['question'] = (string)$description['question'];
$data['colors'] = is_array($poll_info['colors']) ? $poll_info['colors'] : array();
$data['config'] = is_array($poll_info['config']) ? $poll_info['config'] : array();
$data['button_vote'] = $this->language->get('button_vote');
$data['error_select'] = $this->language->get('error_select');
$answers_raw = explode("\n", str_replace("\r", "", $description['answers']));
$data['answers'] = array();
if (!empty($answers_raw) && is_array($answers_raw)) {
foreach ($answers_raw as $index => $text) {
$text = trim((string)$text);
if ($text !== '') {
$data['answers'][] = array(
'index' => (int)$index,
'text' => $text
);
}
}
}
$limit = isset($poll_info['config']['limit']) ? (int)$poll_info['config']['limit'] : 0;
$data['voted'] = $this->model_module_poll_widget_nat->checkVoted($data['poll_id'], $limit);
$data['show_total'] = false;
$data['total_votes'] = 0;
$data['text_total_votes'] = $this->language->get('text_total_votes');
if (isset($poll_info['config']['show_total']) && $poll_info['config']['show_total']) {
$access = isset($poll_info['config']['total_access']) ? (string)$poll_info['config']['total_access'] : 'all';
if ($access === 'all' || ($access === 'registered' && $this->customer->isLogged())) {
$data['show_total'] = true;
$results_data = $this->getResultsData($poll_info, $data['answers']);
if (!empty($results_data) && is_array($results_data)) {
foreach ($results_data as $res) {
$data['total_votes'] += (int)$res['count'];
}
}
}
}
if ($data['voted']) {
$data['results'] = $this->getResultsData($poll_info, $data['answers']);
$data['thanks_text'] = (string)$description['thanks_text'];
} else {
$data['results'] = array();
$data['thanks_text'] = '';
}
if (version_compare(VERSION, '2.2.0.0', '<')) {
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/poll_widget_nat.tpl')) {
return $this->load->view($this->config->get('config_template') . '/template/module/poll_widget_nat.tpl', $data);
} else {
return $this->load->view('default/template/module/poll_widget_nat.tpl', $data);
}
} else {
return $this->load->view('module/poll_widget_nat', $data);
}
}
public function vote() {
$json = array();
if ($this->request->server['REQUEST_METHOD'] != 'POST') {
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode(array('error' => 'Invalid request')));
return;
}
$this->load->model('module/poll_widget_nat');
$this->load->language('module/poll_widget_nat');
$poll_id = isset($this->request->post['poll_id']) ? (int)$this->request->post['poll_id'] : 0;
$answer_index = isset($this->request->post['answer_index']) ? (int)$this->request->post['answer_index'] : -1;
$page_url = '';
if (isset($this->request->post['page_url'])) {
$page_url = strip_tags(html_entity_decode((string)$this->request->post['page_url'], ENT_QUOTES, 'UTF-8'));
$page_url = mb_substr($page_url, 0, 500);
}
$poll_info = $this->model_module_poll_widget_nat->getPoll($poll_id);
if ($poll_info && $answer_index !== -1) {
$limit = isset($poll_info['config']['limit']) ? (int)$poll_info['config']['limit'] : 0;
$voted = $this->model_module_poll_widget_nat->checkVoted($poll_id, $limit);
if (!$voted) {
$guest_allowed = !empty($poll_info['config']['guest']);
if (!$this->customer->isLogged() && !$guest_allowed) {
$json['error'] = $this->language->get('error_guest');
} else {
$this->model_module_poll_widget_nat->addVote($poll_id, $answer_index, $page_url);
$description = $this->model_module_poll_widget_nat->getPollDescription($poll_id);
$answers_raw = explode("\n", str_replace("\r", "", $description['answers']));
$answers = array();
if (!empty($answers_raw) && is_array($answers_raw)) {
foreach ($answers_raw as $i => $t) {
$t = trim((string)$t);
if ($t !== '') {
$answers[] = array('index' => (int)$i, 'text' => $t);
}
}
}
$json['success'] = true;
$json['thanks_text'] = (string)$description['thanks_text'];
$json['results'] = $this->getResultsData($poll_info, $answers);
$json['result_type'] = isset($poll_info['config']['result_type']) ? (string)$poll_info['config']['result_type'] : 'none';
$total_votes = 0;
if (!empty($json['results']) && is_array($json['results'])) {
foreach ($json['results'] as $res) {
$total_votes += (int)$res['count'];
}
}
$json['total_votes'] = $total_votes;
$json['text_total_votes'] = $this->language->get('text_total_votes');
}
} else {
$json['error'] = $this->language->get('error_voted');
}
} else {
$json['error'] = $this->language->get('error_select');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
private function getResultsData($poll_info, $answers) {
$poll_id = isset($poll_info['poll_id']) ? (int)$poll_info['poll_id'] : 0;
$votes = $this->model_module_poll_widget_nat->getPollResults($poll_id);
if (!is_array($votes)) {
$votes = array();
}
if (isset($poll_info['custom_stats']) && is_array($poll_info['custom_stats'])) {
foreach ($poll_info['custom_stats'] as $index => $count) {
$idx = (int)$index;
$cnt = (int)$count;
$answer_exists = false;
foreach ($answers as $ans) {
if ($ans['index'] === $idx) {
$answer_exists = true;
break;
}
}
if ($answer_exists) {
if (!isset($votes[$idx])) {
$votes[$idx] = 0;
}
$votes[$idx] += $cnt;
}
}
}
$total_sum = is_array($votes) ? array_sum($votes) : 0;
$data = array();
if (!empty($answers) && is_array($answers)) {
foreach ($answers as $answer) {
$ans_idx = (int)$answer['index'];
$count = isset($votes[$ans_idx]) ? (int)$votes[$ans_idx] : 0;
$percent = ($total_sum > 0) ? round(($count / $total_sum) * 100, 1) : 0;
$data[] = array(
'text' => (string)$answer['text'],
'count' => $count,
'percent' => $percent
);
}
}
return $data;
}
}

View File

@ -0,0 +1,6 @@
<?php
$_['button_vote'] = 'Vote';
$_['error_voted'] = 'You have already voted in this poll!';
$_['error_guest'] = 'Only registered users can vote in this poll.';
$_['error_select'] = 'Please select an answer!';
$_['text_total_votes'] = 'Total votes';

View File

@ -0,0 +1,6 @@
<?php
$_['button_vote'] = 'Vote';
$_['error_voted'] = 'You have already voted in this poll!';
$_['error_guest'] = 'Only registered users can vote in this poll.';
$_['error_select'] = 'Please select an answer!';
$_['text_total_votes'] = 'Total votes';

View File

@ -0,0 +1,6 @@
<?php
$_['button_vote'] = 'Голосовать';
$_['error_voted'] = 'Вы уже голосовали в этом опросе!';
$_['error_guest'] = 'Голосование доступно только авторизованным пользователям.';
$_['error_select'] = 'Пожалуйста, выберите один из вариантов ответа!';
$_['text_total_votes'] = 'Всего проголосовало';

View File

@ -0,0 +1,6 @@
<?php
$_['button_vote'] = 'Голосовать';
$_['error_voted'] = 'Вы уже голосовали в этом опросе!';
$_['error_guest'] = 'Голосование доступно только авторизованным пользователям.';
$_['error_select'] = 'Пожалуйста, выберите один из вариантов ответа!';
$_['text_total_votes'] = 'Всего проголосовало';

View File

@ -0,0 +1,6 @@
<?php
$_['button_vote'] = 'Голосувати';
$_['error_voted'] = 'Ви вже голосували в цьому опитуванні!';
$_['error_guest'] = 'Голосування доступне тільки авторизованим користувачам.';
$_['error_select'] = 'Будь ласка, оберіть один із варіантів відповіді!';
$_['text_total_votes'] = 'Всього проголосувало';

View File

@ -0,0 +1,6 @@
<?php
$_['button_vote'] = 'Голосувати';
$_['error_voted'] = 'Ви вже голосували в цьому опитуванні!';
$_['error_guest'] = 'Голосування доступне тільки авторизованим користувачам.';
$_['error_select'] = 'Будь ласка, оберіть один із варіантів відповіді!';
$_['text_total_votes'] = 'Всього проголосувало';

View File

@ -0,0 +1,63 @@
<?php
if (!defined('VERSION')) exit;
class ModelModulePollWidgetNat extends Model {
public function getPoll($poll_id) {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "poll_widget_nat` WHERE poll_id = '" . (int)$poll_id . "' AND status = '1'");
if ($query->num_rows) {
$poll_info = $query->row;
$poll_info['config'] = json_decode($poll_info['config'], true);
$poll_info['colors'] = json_decode($poll_info['colors'], true);
$poll_info['custom_stats'] = json_decode($poll_info['custom_stats'], true);
return $poll_info;
}
return false;
}
public function getPollDescription($poll_id) {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "poll_widget_nat_description` WHERE poll_id = '" . (int)$poll_id . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
return $query->row;
}
public function addVote($poll_id, $answer_index, $page_url = '') {
$customer_id = $this->customer->isLogged() ? (int)$this->customer->getId() : 0;
$ip = isset($this->request->server['REMOTE_ADDR']) ? $this->request->server['REMOTE_ADDR'] : '';
$user_agent = isset($this->request->server['HTTP_USER_AGENT']) ? $this->request->server['HTTP_USER_AGENT'] : '';
$this->db->query("INSERT INTO `" . DB_PREFIX . "poll_widget_nat_vote` SET poll_id = '" . (int)$poll_id . "', answer_index = '" . (int)$answer_index . "', customer_id = '" . (int)$customer_id . "', ip = '" . $this->db->escape((string)$ip) . "', user_agent = '" . $this->db->escape((string)$user_agent) . "', page_url = '" . $this->db->escape((string)$page_url) . "', date_added = NOW()");
}
public function checkVoted($poll_id, $limit) {
if ((int)$limit === 0) {
return false;
}
$ip = isset($this->request->server['REMOTE_ADDR']) ? $this->request->server['REMOTE_ADDR'] : '';
$customer_id = $this->customer->isLogged() ? (int)$this->customer->getId() : 0;
$sql = "SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "poll_widget_nat_vote` WHERE poll_id = '" . (int)$poll_id . "' AND (ip = '" . $this->db->escape((string)$ip) . "'";
if ($customer_id) {
$sql .= " OR customer_id = '" . (int)$customer_id . "'";
}
$sql .= ")";
$query = $this->db->query($sql);
return ((int)$query->row['total'] >= (int)$limit);
}
public function getPollResults($poll_id) {
$query = $this->db->query("SELECT answer_index, COUNT(*) AS total FROM `" . DB_PREFIX . "poll_widget_nat_vote` WHERE poll_id = '" . (int)$poll_id . "' GROUP BY answer_index");
$results = array();
foreach ($query->rows as $row) {
$results[(int)$row['answer_index']] = (int)$row['total'];
}
return $results;
}
}

View File

@ -0,0 +1,196 @@
<style>
.nat-poll-<?php echo $poll_id; ?> {
background: <?php echo !empty($colors['bg']) ? $colors['bg'] : '#ffffff'; ?>;
border: 1px solid <?php echo !empty($colors['border']) ? $colors['border'] : '#e5e5e5'; ?>;
padding: 20px;
border-radius: 8px;
color: <?php echo !empty($colors['text']) ? $colors['text'] : '#333333'; ?>;
margin-bottom: 25px;
font-family: inherit;
box-sizing: border-box;
}
.nat-poll-<?php echo $poll_id; ?> h4 {
margin-top: 0;
margin-bottom: 15px;
font-size: 16px;
font-weight: 600;
line-height: 1.4;
}
.nat-poll-options {
list-style: none;
padding: 0;
margin: 0;
}
.nat-poll-option {
margin-bottom: 12px;
cursor: pointer;
display: flex;
align-items: center;
gap: 10px;
font-size: 14px;
}
.nat-poll-option input[type="radio"] {
margin: 0;
cursor: pointer;
}
.nat-poll-btn {
display: block;
width: 100%;
margin-top: 15px;
background: <?php echo !empty($colors['btn_bg']) ? $colors['btn_bg'] : '#2980b9'; ?>;
color: <?php echo !empty($colors['btn_color']) ? $colors['btn_color'] : '#ffffff'; ?>;
border: none;
padding: 10px;
border-radius: 4px;
font-weight: bold;
cursor: pointer;
transition: opacity 0.2s;
text-transform: uppercase;
font-size: 13px;
outline: none;
}
.nat-poll-btn:hover { opacity: 0.85; }
.nat-poll-result-item { margin-bottom: 15px; }
.nat-poll-label { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 5px; }
.nat-poll-bar-bg {
background: <?php echo !empty($colors['bar_bg']) ? $colors['bar_bg'] : '#eeeeee'; ?>;
height: 8px;
border-radius: 4px;
overflow: hidden;
}
.nat-poll-bar-fill {
background: <?php echo !empty($colors['bar_fill']) ? $colors['bar_fill'] : '#2980b9'; ?>;
height: 100%;
width: 0;
transition: width 0.8s ease-out;
}
.nat-poll-thanks {
text-align: center;
font-style: italic;
margin-top: 15px;
font-size: 14px;
color: <?php echo !empty($colors['text']) ? $colors['text'] : '#333333'; ?>;
opacity: 0.8;
}
.nat-poll-total-votes {
margin-top: 15px;
text-align: right;
font-size: 13px;
font-weight: bold;
opacity: 0.8;
}
</style>
<div class="nat-poll-<?php echo $poll_id; ?>" id="poll-module-<?php echo $poll_id; ?>">
<h4><?php echo $question; ?></h4>
<div class="poll-content">
<?php if (!$voted) { ?>
<div class="nat-poll-options">
<?php foreach ($answers as $answer) { ?>
<label class="nat-poll-option">
<input type="radio" name="poll_answer_<?php echo $poll_id; ?>" value="<?php echo $answer['index']; ?>">
<span><?php echo $answer['text']; ?></span>
</label>
<?php } ?>
</div>
<button type="button" class="nat-poll-btn" onclick="natPollVote(<?php echo $poll_id; ?>);"><?php echo $button_vote; ?></button>
<?php } else { ?>
<?php if ($results && isset($config['result_type']) && $config['result_type'] != 'none') { ?>
<?php foreach ($results as $res) { ?>
<div class="nat-poll-result-item">
<div class="nat-poll-label">
<span><?php echo $res['text']; ?></span>
<span>
<?php if ($config['result_type'] == 'percent' || $config['result_type'] == 'both') { echo $res['percent'] . '%'; } ?>
<?php if ($config['result_type'] == 'both') { echo ' / '; } ?>
<?php if ($config['result_type'] == 'count' || $config['result_type'] == 'both') { echo $res['count']; } ?>
</span>
</div>
<div class="nat-poll-bar-bg">
<div class="nat-poll-bar-fill" style="width: <?php echo $res['percent']; ?>%;"></div>
</div>
</div>
<?php } ?>
<?php } ?>
<?php if ($thanks_text) { ?>
<div class="nat-poll-thanks"><?php echo $thanks_text; ?></div>
<?php } ?>
<?php } ?>
<?php if ($show_total) { ?>
<div class="nat-poll-total-votes">
<?php echo $text_total_votes; ?>: <span class="nat-poll-total-count"><?php echo $total_votes; ?></span>
</div>
<?php } ?>
</div>
</div>
<script type="text/javascript">
function natPollVote(poll_id) {
var answer_index = $('input[name="poll_answer_' + poll_id + '"]:checked').val();
if (typeof answer_index === 'undefined') {
alert('<?php echo addslashes($error_select); ?>');
return;
}
var current_url = window.location.href;
$.ajax({
url: 'index.php?route=module/poll_widget_nat/vote',
type: 'post',
data: { poll_id: poll_id, answer_index: answer_index, page_url: current_url },
dataType: 'json',
beforeSend: function() {
$('#poll-module-' + poll_id + ' .nat-poll-btn').prop('disabled', true).css('opacity', '0.5');
},
success: function(json) {
if (json['error']) {
alert(json['error']);
$('#poll-module-' + poll_id + ' .nat-poll-btn').prop('disabled', false).css('opacity', '1');
}
if (json['success']) {
var html = '';
if (json['results'] && json['result_type'] !== 'none') {
json['results'].forEach(function(res) {
html += '<div class="nat-poll-result-item">';
html += ' <div class="nat-poll-label"><span>' + res.text + '</span><span>';
if (json['result_type'] === 'percent' || json['result_type'] === 'both') html += res.percent + '%';
if (json['result_type'] === 'both') html += ' / ';
if (json['result_type'] === 'count' || json['result_type'] === 'both') html += res.count;
html += ' </span></div>';
html += ' <div class="nat-poll-bar-bg"><div class="nat-poll-bar-fill" style="width:' + res.percent + '%"></div></div>';
html += '</div>';
});
}
if (json['thanks_text']) {
html += '<div class="nat-poll-thanks">' + json['thanks_text'] + '</div>';
}
<?php if ($show_total) { ?>
if (typeof json['total_votes'] !== 'undefined') {
var total_text = (json['text_total_votes'] ? json['text_total_votes'] : '<?php echo addslashes($text_total_votes); ?>');
html += '<div class="nat-poll-total-votes">';
html += total_text + ': <span class="nat-poll-total-count">' + json['total_votes'] + '</span>';
html += '</div>';
}
<?php } ?>
$('#poll-module-' + poll_id + ' .poll-content').fadeOut(300, function() {
$(this).html(html).fadeIn(300);
});
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
$('#poll-module-' + poll_id + ' .nat-poll-btn').prop('disabled', false).css('opacity', '1');
}
});
}
</script>