У каждого начинающего веб-мастера наступает момент, когда заказчик говорит “нужно так”, а “именно так” готового модуля нет. Но есть множество похожих – но заказчик уперся рогом и стоимость разработки явно не включает написание полноценного модуля к CMS.

Сегодня я расскажу как “взять” часть функционала из стороннего модуля к OpenCart 2.0 и доработать ее под нужды заказчика.

Задача такова: Нужно сделать таймер обратного отсчета на главной страницы, но такой, который задается из админки. Усугубляет положение версия opencart – 2.0. На момент написания ближайшим по схожести решением был модуль countdown timer

Сей модуль умеет выводить таймер в товаре. Но считаем, что вывод товара у нас кастомный, или мы создаем товар, который нигде не будет выводиться, назвем товар ТАЙМЕР.

Для начала ставим стандартно модуль – выгружаем его через фтп, добавляем товар и запоминает его ID. И начинаем ковырять его.

Нам нужно выяснить где берутся данные. Начнем смотреть с install.xml – ведь здесь написано что куда грузить и менять при установке.

<![CDATA[ /* Nikita_SP MOD FOR COUNTER */ public function getProductSpecialData($product_id) { if ($this->customer->isLogged()) {
 $customer_group_id = $this->customer->;getGroupId();
 } else {
 $customer_group_id = $this->config->get('config_customer_group_id');
 }
 
 $query = $this->db->query("SELECT `price`, `date_end` FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "' AND customer_group_id = '" . (int)$customer_group_id . "' AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) ORDER BY priority ASC, price ASC LIMIT 1");
 
 if ($query->num_rows) {
 return $query->row;
 } else {
 return FALSE;
 }
 }
 ]]>

Таким вот образом мы видим в коде следующее: добавляется текст, который проверяем зарегистрирован ли пользователь, затем выбирает из базы дату акции. Это то нам и нужно.

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

Теперь посмотрим как данные добавляются в страницу:

Строка search ищет текст:
возьмем к примеру получаение для продукт пхп

 <![CDATA[ $data['special'] = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')));
 ]]>

И после найденного добавляет текст:

 <![CDATA[ $special = $this->model_catalog_product->getProductSpecialData($this->request->get['product_id']);
 if($special['date_end'] && $this->config->get('countdowntimer_product') && time() > strtotime($special['date_end'])){
 $this->load->language('module/countdowntimer');
 $data['special_end'] = $special['date_end'];
 $data['text_countdown'] = $this->language->get('text_countdown');
 
 $data['countdowntimer_product_texttimer'] = $this->config->get('countdowntimer_product_texttimer');
 $data['countdowntimer_product_days'] = $this->config->get('countdowntimer_product_days');
 $data['countdowntimer_product_countdays'] = $this->config->get('countdowntimer_product_countdays');
 $data['countdowntimer_product_seconds'] = $this->config->get('countdowntimer_product_seconds');
 
 if($this->config->get('countdowntimer_product_texttimer')){
 $data['config_language'] = $this->config->get('config_language');
 $data['text_countdown_days'] = $this->language->get('text_countdown_days');
 $data['text_countdown_hours'] = $this->language->get('text_countdown_hours');
 $data['text_countdown_minutes'] = $this->language->get('text_countdown_minutes');
 $data['text_countdown_seconds'] = $this->language->get('text_countdown_seconds');
 }
 }else{
 $data['special_end'] = false;
 }
 ]]>

На данном этапе мы знаем откудова модуль берет данные и как вставляем. Заполняются данные из админки – здесь нас все устраивает и ничего менять не будем.

Далее нужно дописать контроллер главной страницы, чтобы туда принудительно дописывать вывод счетчика товара ТАЙМЕР.

Писать нужно как обычно в контроллер – функции отдельно, а в index только пользуемся написанными функциями.

Функция получения данных:

public function getProductSpecialData($product_id) {
				if ($this-&gt;customer-&gt;isLogged()) {
					$customer_group_id = $this-&gt;customer-&gt;getGroupId();
				} else {
					$customer_group_id = $this-&gt;config-&gt;get('config_customer_group_id');
				}
 
				$query = $this-&gt;db-&gt;query("SELECT `price`, `date_end` FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "' AND customer_group_id = '" . (int)$customer_group_id . "' AND ((date_start = '0000-00-00' OR date_start &lt; NOW()) AND (date_end = '0000-00-00' OR date_end &gt; NOW())) ORDER BY priority ASC, price ASC LIMIT 1");
 
				if ($query-&gt;num_rows) {
					return $query-&gt;row;
				} else {
					return FALSE;
				}
			}

При создании этой статьи ID товара получился 50, у вас выйдет другой скорей всего.

Получаем данные, записываем их в массив:

$special = $this-&gt;getProductSpecialData(50);

Далее используем функцию вывода в файл product (как хотел создатель плагина) и заполняем данные для передачи в шаблон

if($special['date_end'] &amp;&amp; time() &lt; strtotime($special['date_end'])){ $this-&gt;load-&gt;language('module/countdowntimer');
 $data['special_end'] = $special['date_end'];
 $data['text_countdown'] = $this-&gt;language-&gt;get('text_countdown');
 
 $data['countdowntimer_product_texttimer'] = $this-&gt;config-&gt;get('countdowntimer_product_texttimer');
 $data['countdowntimer_product_days'] = $this-&gt;config-&gt;get('countdowntimer_product_days');
 $data['countdowntimer_product_countdays'] = $this-&gt;config-&gt;get('countdowntimer_product_countdays');
 $data['countdowntimer_product_seconds'] = $this-&gt;config-&gt;get('countdowntimer_product_seconds');
 
 if($this-&gt;config-&gt;get('countdowntimer_product_texttimer')){
 $data['config_language'] = $this-&gt;config-&gt;get('config_language');
 $data['text_countdown_days'] = $this-&gt;language-&gt;get('text_countdown_days');
 $data['text_countdown_hours'] = $this-&gt;language-&gt;get('text_countdown_hours');
 $data['text_countdown_minutes'] = $this-&gt;language-&gt;get('text_countdown_minutes');
 $data['text_countdown_seconds'] = $this-&gt;language-&gt;get('text_countdown_seconds');
 }
 }else{
 $data['special_end'] = false;
 }

Таким образом контроллер извлек данные об акции, сформировал их потребным образом и отправил к файлу отрисовки (tpl)

Далее необходимо в исходно install.xml находим вывод таймера.
Он находится после строки:

 

Копируем его в home.tpl

 

В конце добавляем условие else так как изначально задумка не выводить таймер если акция закончена.

Счетчик зациклить нельзя – но можно ввести несколько дат акций (только конец акции) например – на каждую неделю, сев 1 раз набрав на 2-3 месяца вперед окончания акций можно не париться весь этот срок, потом их все вместе удалить и поставить новых.