+
+ ]]>
+
+
+
\ No newline at end of file
diff --git a/poll_widget_nat_OC_20_22_1_0.ocmod.zip b/poll_widget_nat_OC_20_22_1_0.ocmod.zip
new file mode 100644
index 0000000..a5f9717
Binary files /dev/null and b/poll_widget_nat_OC_20_22_1_0.ocmod.zip differ
diff --git a/readme.txt b/readme.txt
index 6785ae1..30f1200 100644
--- a/readme.txt
+++ b/readme.txt
@@ -24,7 +24,7 @@ Poll Widget [NAT] is a powerful tool for creating responsive voting widgets and
INSTALLATION:
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.
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".
diff --git a/upload/admin/controller/module/poll_widget_nat.php b/upload/admin/controller/module/poll_widget_nat.php
new file mode 100644
index 0000000..eb66f96
--- /dev/null
+++ b/upload/admin/controller/module/poll_widget_nat.php
@@ -0,0 +1,370 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/upload/admin/language/en-gb/module/poll_widget_nat.php b/upload/admin/language/en-gb/module/poll_widget_nat.php
new file mode 100644
index 0000000..e625736
--- /dev/null
+++ b/upload/admin/language/en-gb/module/poll_widget_nat.php
@@ -0,0 +1,93 @@
+Poll Widget [NAT]: 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 [NAT] ecosystem. Support: info@nat.od.ua';
+$_['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.';
\ No newline at end of file
diff --git a/upload/admin/language/english/module/poll_widget_nat.php b/upload/admin/language/english/module/poll_widget_nat.php
new file mode 100644
index 0000000..e625736
--- /dev/null
+++ b/upload/admin/language/english/module/poll_widget_nat.php
@@ -0,0 +1,93 @@
+Poll Widget [NAT]: 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 [NAT] ecosystem. Support: info@nat.od.ua';
+$_['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.';
\ No newline at end of file
diff --git a/upload/admin/language/ru-ru/module/poll_widget_nat.php b/upload/admin/language/ru-ru/module/poll_widget_nat.php
new file mode 100644
index 0000000..9ab18fb
--- /dev/null
+++ b/upload/admin/language/ru-ru/module/poll_widget_nat.php
@@ -0,0 +1,93 @@
+Poll Widget [NAT]: Опросы и голосования';
+$_['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'] = 'Разработано для экосистемы [NAT]. Поддержка: info@nat.od.ua';
+$_['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'] = 'Создание интерактивных промо-панелей и слайд-шоу в шапке сайта с конструктором блоков, таймерами, формой подписки и гибким таргетингом.';
\ No newline at end of file
diff --git a/upload/admin/language/russian/module/poll_widget_nat.php b/upload/admin/language/russian/module/poll_widget_nat.php
new file mode 100644
index 0000000..9ab18fb
--- /dev/null
+++ b/upload/admin/language/russian/module/poll_widget_nat.php
@@ -0,0 +1,93 @@
+Poll Widget [NAT]: Опросы и голосования';
+$_['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'] = 'Разработано для экосистемы [NAT]. Поддержка: info@nat.od.ua';
+$_['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'] = 'Создание интерактивных промо-панелей и слайд-шоу в шапке сайта с конструктором блоков, таймерами, формой подписки и гибким таргетингом.';
\ No newline at end of file
diff --git a/upload/admin/language/uk-ua/module/poll_widget_nat.php b/upload/admin/language/uk-ua/module/poll_widget_nat.php
new file mode 100644
index 0000000..9388c5d
--- /dev/null
+++ b/upload/admin/language/uk-ua/module/poll_widget_nat.php
@@ -0,0 +1,90 @@
+Poll Widget [NAT]: Опитування та голосування';
+$_['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'] = 'Розроблено для екосистеми [NAT]. Підтримка: info@nat.od.ua';
+$_['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'] = 'Створення інтерактивних промо-панелей та слайд-шоу в шапці сайту з конструктором блоків, таймерами, формою підписки та гнучким націлюванням.';
\ No newline at end of file
diff --git a/upload/admin/language/ukrainian/module/poll_widget_nat.php b/upload/admin/language/ukrainian/module/poll_widget_nat.php
new file mode 100644
index 0000000..9388c5d
--- /dev/null
+++ b/upload/admin/language/ukrainian/module/poll_widget_nat.php
@@ -0,0 +1,90 @@
+Poll Widget [NAT]: Опитування та голосування';
+$_['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'] = 'Розроблено для екосистеми [NAT]. Підтримка: info@nat.od.ua';
+$_['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'] = 'Створення інтерактивних промо-панелей та слайд-шоу в шапці сайту з конструктором блоків, таймерами, формою підписки та гнучким націлюванням.';
\ No newline at end of file
diff --git a/upload/admin/model/module/poll_widget_nat.php b/upload/admin/model/module/poll_widget_nat.php
new file mode 100644
index 0000000..72d3cd2
--- /dev/null
+++ b/upload/admin/model/module/poll_widget_nat.php
@@ -0,0 +1,163 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/upload/admin/view/template/module/poll_widget_nat_form.tpl b/upload/admin/view/template/module/poll_widget_nat_form.tpl
new file mode 100644
index 0000000..91be029
--- /dev/null
+++ b/upload/admin/view/template/module/poll_widget_nat_form.tpl
@@ -0,0 +1,352 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/upload/admin/view/template/module/poll_widget_nat_list.tpl b/upload/admin/view/template/module/poll_widget_nat_list.tpl
new file mode 100644
index 0000000..d701cb1
--- /dev/null
+++ b/upload/admin/view/template/module/poll_widget_nat_list.tpl
@@ -0,0 +1,224 @@
+
+