diff --git a/Instruction ru-uk-en.txt b/Instruction ru-uk-en.txt index ca6a12b..f7c9d5f 100644 --- a/Instruction ru-uk-en.txt +++ b/Instruction ru-uk-en.txt @@ -1,7 +1,7 @@ ============================================================================= Poll Widget [NAT] 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 Contact: info@nat.od.ua ============================================================================= @@ -18,7 +18,7 @@ Poll Widget [NAT] — это функциональный модуль для с УСТАНОВКА: 1. Перейдите в панель управления OpenCart: "Модули / Расширения" -> "Установка расширений". -2. Загрузите архив `poll_widget_nat.ocmod.zip`. +2. Загрузите архив poll_widget_nat_OC_20_22_1_0.ocmod.zip. 3. Перейдите в "Модули / Расширения" -> "Модификаторы" и нажмите синюю кнопку "Обновить" (Очистить кэш). 4. Перейдите в "Система" -> "Пользователи" -> "Группы пользователей", выберите вашу группу (Administrator), нажмите "Выделить все" в правах просмотра и изменения, затем сохраните. 5. Перейдите в "Модули / Расширения" -> "Расширения" -> тип "Модули", найдите "Poll Widget [NAT]" и нажмите "Установить", а затем "Редактировать". @@ -52,7 +52,7 @@ Poll Widget [NAT] — це функціональний модуль для ст ВСТАНОВЛЕННЯ: 1. Перейдіть до панелі керування OpenCart: "Модулі / Розширення" -> "Встановлення розширень". -2. Завантажте архів `poll_widget_nat.ocmod.zip`. +2. Завантажте архів poll_widget_nat_OC_20_22_1_0.ocmod.zip. 3. Перейдіть до "Модулі / Розширення" -> "Модифікатори" і натисніть синю кнопку "Оновити". 4. Перейдіть до "Система" -> "Користувачі" -> "Групи користувачів", виберіть вашу групу (Administrator), натисніть "Виділити все" у правах перегляду та зміни, збережіть. 5. Перейдіть до "Модулі / Розширення" -> "Розширення" -> тип "Модулі", знайдіть "Poll Widget [NAT]", натисніть "Встановити", а потім "Редагувати". @@ -86,7 +86,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.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/install.xml b/install.xml new file mode 100644 index 0000000..79937e1 --- /dev/null +++ b/install.xml @@ -0,0 +1,95 @@ + + + Poll Widget [NAT] + poll_widget_nat + poll_widget_nat_od_ua + 1.0.0 + NAT + mailto:info@nat.od.ua + + + + user->hasPermission('access', 'catalog/product')) {]]> + 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) + ); + } + } + } + } + ]]> + + + + + + url->link('common/logout']]> + 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) + ); + } + } + } + ]]> + + + + + + + + + + + ]]> + + + \ 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 @@ + +
+ +
+ +
+ +
+ +
+
+

+
+
+
+ + + +
+
+
+ +
+ +
+
+ + + +
+ +
+
+ +
+ + +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ $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 + ); + ?> + + $label) { ?> +
+ +
+
+ + + + +
+
+
+ +
+ +
+
+
+
+ + + + + + + + + + + $text) { ?> + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + - + +
+
+
+
+
+
+ +
+
+ +
+ +
+
+
+

+

+
+
+
+
+

+

+
+
+
+
+
+
+

+

+
+
+
+
+

+

+
+
+
+
+
+
+

+

+
+
+
+
+

+

+
+
+
+
+
+
+

+

+
+
+
+
+

+

+
+
+
+
+
+
+

+

+
+
+
+
+

+

+
+
+
+ + +
+ +
+
+
+ +
+
+
+ + \ 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 @@ + +
+ +
+ +
+ +
+ + +
+ +
+ +
+
+

+
+
+ + + +
+
+
+
+
+
+ +
+ + + + +
+
+
+
+
+ +
+ + + + +
+
+
+
+
+ +
+ + + + + + + + + + + +
+
+
+
+ +
+
+
+ +
+
+
+ +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ +
+ +
+
+
+

+

+
+
+
+
+

+

+
+
+
+
+
+
+

+

+
+
+
+
+

+

+
+
+
+
+
+
+

+

+
+
+
+
+

+

+
+
+
+
+
+
+

+

+
+
+
+ + +
+ +
+ +
+ +
+
+
+ \ No newline at end of file diff --git a/upload/catalog/controller/module/poll_widget_nat.php b/upload/catalog/controller/module/poll_widget_nat.php new file mode 100644 index 0000000..f78972f --- /dev/null +++ b/upload/catalog/controller/module/poll_widget_nat.php @@ -0,0 +1,210 @@ +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; + } +} \ No newline at end of file diff --git a/upload/catalog/language/en-gb/module/poll_widget_nat.php b/upload/catalog/language/en-gb/module/poll_widget_nat.php new file mode 100644 index 0000000..aa21920 --- /dev/null +++ b/upload/catalog/language/en-gb/module/poll_widget_nat.php @@ -0,0 +1,6 @@ +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; + } +} \ No newline at end of file diff --git a/upload/catalog/view/theme/default/template/module/poll_widget_nat.tpl b/upload/catalog/view/theme/default/template/module/poll_widget_nat.tpl new file mode 100644 index 0000000..432a9c2 --- /dev/null +++ b/upload/catalog/view/theme/default/template/module/poll_widget_nat.tpl @@ -0,0 +1,196 @@ + + +
+

+ +
+ +
+ + + +
+ + + + +
+
+ + + + + + +
+
+
+
+
+ + + + +
+ + + + +
+ : +
+ +
+
+ + \ No newline at end of file