diff --git a/public/admin/controller/extension/advertise/google.php b/public/admin/controller/extension/advertise/google.php deleted file mode 100644 index 1f9b668..0000000 --- a/public/admin/controller/extension/advertise/google.php +++ /dev/null @@ -1,2089 +0,0 @@ -store_id = isset($this->request->get['store_id']) ? (int)$this->request->get['store_id'] : 0; - - $this->loadStore($this->store_id); - - $this->loadLibrary($this->store_id); - } - - public function index() { - $this->load->language('extension/advertise/google'); - - $this->load->model('extension/advertise/google'); - - $this->load->config('googleshopping/googleshopping'); - - // Fix clashes with third-party extension table names - $this->model_extension_advertise_google->renameTables(); - - // Even though this should be ran during install, there are known cases of webstores which do not trigger the install method. This is why we run createTables here explicitly. - $this->model_extension_advertise_google->createTables(); - - // Fix a missing AUTO_INCREMENT - $this->model_extension_advertise_google->fixColumns(); - - // Redirect to the preliminary check-list - if (!$this->setting->get('advertise_google_checklist_confirmed')) { - $this->response->redirect($this->url->link('extension/advertise/google/checklist', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - - try { - // If we have not connected, navigate to connect screen - if (!$this->setting->has('advertise_google_access_token')) { - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } else if (!$this->setting->has('advertise_google_gmc_account_selected')) { - // In case the merchant has made no decision about which GMC account to use, redirect to the form for connection - $this->response->redirect($this->url->link('extension/advertise/google/merchant', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } else if (!$this->googleshopping->isStoreUrlClaimed()) { - if (empty($this->session->data['error'])) { - $this->session->data['error'] = $this->language->get('error_store_url_claim'); - } - - // In case the merchant has made no decision about which GMC account to use, redirect to the form for connection - $this->response->redirect($this->url->link('extension/advertise/google/merchant', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } else if (count($this->googleshopping->getTargets($this->store_id)) == 0) { - $this->response->redirect($this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } else if (!$this->setting->has('advertise_google_gmc_shipping_taxes_configured')) { - // In case the merchant has not set up shipping and taxes, redirect them to the form for shipping and taxes - $this->response->redirect($this->url->link('extension/advertise/google/shipping_taxes', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } else if (count($this->model_extension_advertise_google->getMapping($this->store_id)) == 0) { - // In case the merchant has not set up mapping, redirect them to the form for mapping - $this->response->redirect($this->url->link('extension/advertise/google/mapping', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - - // Pull the campaign reports - $this->googleshopping->getCampaignReports(); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->error['warning'] = $e->getMessage(); - } - - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validateSettings()) { - $this->applyNewSettings($this->request->post); - - try { - // Profilactic target push, as sometimes targets are not initialized properly - $this->googleshopping->pushTargets(); - $this->googleshopping->pushCampaignStatus(); - - $this->session->data['success'] = $this->language->get('success_index'); - - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->error['warning'] = $e->getMessage(); - } - } - - $this->document->setTitle($this->language->get('heading_title')); - - $data = array(); - - $data['text_connected'] = sprintf($this->language->get('text_connected'), $this->setting->get('advertise_google_gmc_account_id')); - - $data['error'] = ''; - - if (isset($this->session->data['error'])) { - $data['error'] = $this->session->data['error']; - unset($this->session->data['error']); - } else if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - $data['error_cron_email'] = $this->getValidationError('cron_email'); - $data['error_cron_acknowledge'] = $this->getValidationError('cron_acknowledge'); - - $data['success'] = ''; - - if (isset($this->session->data['success'])) { - $data['success'] = $this->session->data['success']; - unset($this->session->data['success']); - } - - $advertised_count = $this->model_extension_advertise_google->getAdvertisedCount($this->store_id); - $last_cron_executed = (int)$this->setting->get('advertise_google_cron_last_executed'); - - $data['warning'] = ''; - - if (!$this->setting->get('advertise_google_status') && $this->model_extension_advertise_google->hasActiveTarget($this->store_id)) { - $data['warning'] = $this->language->get('warning_disabled'); - } else if (!$this->model_extension_advertise_google->hasActiveTarget($this->store_id)) { - $data['warning'] = sprintf($this->language->get('warning_no_active_campaigns'), $this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true)); - } else if ($advertised_count == 0) { - $data['warning'] = sprintf($this->language->get("warning_no_advertised_products"), $this->language->get("text_video_tutorial_url_advertise")); - } else if ($last_cron_executed + 24 * 60 * 60 <= time()) { - $data['warning'] = sprintf($this->language->get("warning_last_cron_executed"), $this->language->get("text_tutorial_cron")); - } - - $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extensions'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), - ); - - $reporting_intervals = $this->config->get('advertise_google_reporting_intervals'); - - $data['user_token'] = $this->session->data['user_token']; - - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true); - $data['action'] = $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - $data['shipping_taxes'] = $this->url->link('extension/advertise/google/shipping_taxes', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true); - $data['campaign'] = $this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true); - $data['mapping'] = $this->url->link('extension/advertise/google/mapping', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true); - $data['disconnect'] = $this->url->link('extension/advertise/google/disconnect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - $data['list_ads'] = html_entity_decode($this->url->link('extension/advertise/google/list_ads', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['advertise'] = html_entity_decode($this->url->link('extension/advertise/google/advertise', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['url_popup'] = html_entity_decode($this->url->link('extension/advertise/google/popup_product', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['url_category_autocomplete'] = html_entity_decode($this->url->link('extension/advertise/google/category_autocomplete', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['url_debug_log_download'] = html_entity_decode($this->url->link('extension/advertise/google/debug_log_download', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - - $data['advertise_google_status'] = $this->getSettingValue('advertise_google_status', 0); - $data['advertise_google_debug_log'] = $this->getSettingValue('advertise_google_debug_log', 0); - $data['advertise_google_cron_email_status'] = $this->getSettingValue('advertise_google_cron_email_status'); - $data['advertise_google_cron_email'] = $this->getSettingValue('advertise_google_cron_email', $this->config->get('config_email')); - $data['advertise_google_cron_token'] = $this->getSettingValue('advertise_google_cron_token'); - $data['advertise_google_cron_acknowledge'] = $this->getSettingValue('advertise_google_cron_acknowledge', null, true); - - if (isset($this->request->post['advertise_google_reporting_interval'])) { - $data['advertise_google_reporting_interval'] = $this->request->post['advertise_google_reporting_interval']; - } else if ($this->setting->has('advertise_google_reporting_interval') && in_array($this->setting->get('advertise_google_reporting_interval'), $reporting_intervals)) { - $data['advertise_google_reporting_interval'] = $this->setting->get('advertise_google_reporting_interval'); - } else { - $data['advertise_google_reporting_interval'] = $this->config->get('advertise_google_reporting_intervals_default'); - } - - $server = $this->googleshopping->getStoreUrl(); - - $data['advertise_google_cron_command'] = 'export CUSTOM_SERVER_NAME=' . parse_url($server, PHP_URL_HOST) . '; export CUSTOM_SERVER_PORT=443; export ADVERTISE_GOOGLE_CRON=1; export ADVERTISE_GOOGLE_STORE_ID=' . $this->store_id . '; ' . PHP_BINDIR . '/php -d session.save_path=' . session_save_path() . ' -d memory_limit=256M ' . DIR_SYSTEM . 'library/googleshopping/cron.php > /dev/null 2> /dev/null'; - - if (!$this->setting->get('advertise_google_cron_token')) { - $data['advertise_google_cron_token'] = md5(mt_rand()); - } - - $host_and_uri = parse_url($server, PHP_URL_HOST) . parse_url($server, PHP_URL_PATH); - - $data['advertise_google_cron_url'] = 'https://' . rtrim($host_and_uri, '/') . '/index.php?route=extension/advertise/google/cron&cron_token={CRON_TOKEN}'; - - $data['reporting_intervals'] = array(); - - foreach ($reporting_intervals as $interval) { - $data['reporting_intervals'][$interval] = $this->language->get('text_reporting_interval_' . $interval); - } - - $campaign_reports = $this->setting->get('advertise_google_report_campaigns'); - - $data['campaigns'] = $this->googleshopping->getTargets($this->store_id); - - $data['text_report_date_range'] = sprintf($this->language->get('text_report_date_range'), $campaign_reports['date_range']); - $data['text_ads_intro'] = sprintf($this->language->get('text_ads_intro'), $data['shipping_taxes']); - $data['advertise_google_report_campaigns'] = $campaign_reports['reports']; - $data['text_panel_heading'] = sprintf($this->language->get('text_panel_heading'), $this->googleshopping->getStoreName()); - - $data['text_selection_all'] = str_replace("'", "\\'", $this->language->get('text_selection_all')); - $data['text_selection_page'] = str_replace("'", "\\'", $this->language->get('text_selection_page')); - - $data['tab_settings'] = $this->load->view('extension/advertise/google_settings', $data); - $data['tab_ads'] = $this->load->view('extension/advertise/google_ads', $data); - $data['tab_reports'] = $this->load->view('extension/advertise/google_reports', $data); - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $this->response->setOutput($this->load->view('extension/advertise/google', $data)); - } - - public function debug_log_download() { - $filename = sprintf(Googleshopping::DEBUG_LOG_FILENAME, $this->store_id); - - header('Pragma: no-cache'); - header('Expires: 0'); - header('Content-Description: File Transfer'); - header('Content-Type: plain/text'); - header('Content-Disposition: attachment; filename="' . $filename . '"'); - header('Content-Transfer-Encoding: binary'); - - $file = DIR_LOGS . $filename; - - if (file_exists($file)) { - readfile($file); - } - - exit; - } - - public function advertise() { - $this->load->language('extension/advertise/google'); - - $json = array( - 'success' => null, - 'redirect' => null, - 'error' => null, - 'warning' => null - ); - - if ($this->validatePermission()) { - $this->load->model('extension/advertise/google'); - - $select = array(); - $filter_data = array(); - - if (!empty($this->request->post['all_pages'])) { - $filter_data = $this->getFilter($this->request->post['filter']); - } else if (isset($this->request->post['select']) && is_array($this->request->post['select'])) { - $select = $this->request->post['select']; - } - - if (!empty($select) || !empty($filter_data)) { - $target_ids = !empty($this->request->post['target_ids']) ? $this->request->post['target_ids'] : array(); - - if (!empty($select)) { - $this->model_extension_advertise_google->setAdvertisingBySelect($select, $target_ids, $this->store_id); - } else if (!empty($filter_data)) { - $this->model_extension_advertise_google->setAdvertisingByFilter($filter_data, $target_ids, $this->store_id); - } - - if (!empty($target_ids)) { - $json['success'] = $this->language->get('success_advertise_listed'); - } else { - $json['success'] = $this->language->get('success_advertise_unlisted'); - } - } - } else { - $json['error'] = $this->error['warning']; - } - - // Refresh warnings - $advertised_count = $this->model_extension_advertise_google->getAdvertisedCount($this->store_id); - $last_cron_executed = (int)$this->setting->get('advertise_google_cron_last_executed'); - - if (!$this->setting->get('advertise_google_status') && $this->model_extension_advertise_google->hasActiveTarget($this->store_id)) { - $json['warning'] = $this->language->get('warning_disabled'); - } else if (!$this->model_extension_advertise_google->hasActiveTarget($this->store_id)) { - $json['warning'] = sprintf($this->language->get('warning_no_active_campaigns'), $this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true)); - } else if ($advertised_count == 0) { - $json['warning'] = sprintf($this->language->get("warning_no_advertised_products"), $this->language->get("text_video_tutorial_url_advertise")); - } else if ($last_cron_executed + 24 * 60 * 60 <= time()) { - $json['warning'] = sprintf($this->language->get("warning_last_cron_executed"), $this->language->get("text_tutorial_cron")); - } - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function list_ads() { - $json = array(); - - $this->load->model('extension/advertise/google'); - - $this->model_extension_advertise_google->insertNewProducts(array(), $this->store_id); - - $this->load->language('extension/advertise/google'); - - $page = (int)$this->request->post['page']; - - $filter_data = array( - 'sort' => $this->request->post['sort'], - 'order' => $this->request->post['order'], - 'start' => ($page - 1) * $this->config->get('config_limit_admin'), - 'limit' => $this->config->get('config_limit_admin') - ); - - $filter_data = array_merge($filter_data, $this->getFilter($this->request->post['filter'])); - - $products = $this->googleshopping->getProducts($filter_data, $this->store_id); - - $json['products'] = array_map(array($this, 'product'), $products); - - $product_total = $this->googleshopping->getTotalProducts($filter_data, $this->store_id); - - $pagination = new Pagination(); - $pagination->total = $product_total; - $pagination->page = $this->request->post['page']; - $pagination->limit = $this->config->get('config_limit_admin'); - $pagination->url = '{page}'; - - $pages = ceil($product_total / $this->config->get('config_limit_admin')); - - $json['showing'] = sprintf($this->language->get('text_pagination'), ($product_total) ? (($page - 1) * $this->config->get('config_limit_admin')) + 1 : 0, ((($page - 1) * $this->config->get('config_limit_admin')) > ($product_total - $this->config->get('config_limit_admin'))) ? $product_total : ((($page - 1) * $this->config->get('config_limit_admin')) + $this->config->get('config_limit_admin')), $product_total, $pages); - - $json['pagination'] = $pagination->render(); - $json['total'] = (int)$product_total; - $json['pages'] = (int)$pages; - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function merchant() { - $this->load->language('extension/advertise/google'); - - $this->document->setTitle($this->language->get('heading_merchant')); - - $this->document->addStyle('view/stylesheet/googleshopping/stepper.css'); - - $this->load->model('extension/advertise/google'); - - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validatePermission()) { - try { - $redirect_uri = html_entity_decode($this->url->link('extension/advertise/google/callback_merchant', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $state = md5(microtime(true) . $redirect_uri . microtime(true)); - - $auth_url_data = array( - 'account_type' => $this->request->post['advertise_google_gmc_account_type'], - 'redirect_uri' => $redirect_uri . '&state=' . $state - ); - - $this->session->data['advertise_google'] = $auth_url_data; - $this->session->data['advertise_google']['state'] = $state; - - $this->response->redirect($this->googleshopping->getMerchantAuthUrl($auth_url_data)); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->error['warning'] = $e->getMessage(); - } - } - - $data = array(); - - $data['error'] = ''; - - if (isset($this->session->data['error'])) { - $data['error'] = $this->session->data['error']; - unset($this->session->data['error']); - } else if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - $data['success'] = ''; - - if (isset($this->session->data['success'])) { - $data['success'] = $this->session->data['success']; - unset($this->session->data['success']); - } - - $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extensions'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/advertise/google/merchant', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), - ); - - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true); - $data['action'] = $this->url->link('extension/advertise/google/merchant', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - - if (isset($this->request->post['advertise_google_gmc_account_type'])) { - $data['advertise_google_gmc_account_type'] = $this->request->post['advertise_google_gmc_account_type']; - } else { - $data['advertise_google_gmc_account_type'] = 'api'; - } - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $data['current_step'] = 2; - $data['steps'] = $this->load->view('extension/advertise/google_steps', $data); - - $this->response->setOutput($this->load->view('extension/advertise/google_merchant', $data)); - } - - public function shipping_taxes() { - $this->load->language('extension/advertise/google'); - - $this->document->setTitle($this->language->get('heading_shipping_taxes')); - - $this->document->addStyle('view/stylesheet/googleshopping/stepper.css'); - - $this->load->model('extension/advertise/google'); - - $this->load->config('googleshopping/googleshopping'); - - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validateShippingAndTaxes()) { - try { - $this->applyNewSettings($this->request->post); - - $this->googleshopping->pushShippingAndTaxes(); - - $this->applyNewSettings(array( - 'advertise_google_gmc_shipping_taxes_configured' => '1' - )); - - $this->session->data['success'] = $this->language->get('success_shipping_taxes'); - - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->error['warning'] = $e->getMessage(); - } - } - - $available_carriers = array(); - - try { - $available_carriers = $this->googleshopping->getAvailableCarriers(); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->error['warning'] = $e->getMessage(); - } - - $data = array(); - - $data['error'] = ''; - - if (isset($this->session->data['error'])) { - $data['error'] = $this->session->data['error']; - unset($this->session->data['error']); - } else if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - if (isset($this->error['min_transit_time'])) { - $data['error_min_transit_time'] = $this->error['min_transit_time']; - } else { - $data['error_min_transit_time'] = ''; - } - - if (isset($this->error['max_transit_time'])) { - $data['error_max_transit_time'] = $this->error['max_transit_time']; - } else { - $data['error_max_transit_time'] = ''; - } - - if (isset($this->error['flat_rate'])) { - $data['error_flat_rate'] = $this->error['flat_rate']; - } else { - $data['error_flat_rate'] = ''; - } - - if (isset($this->error['carrier_postcode'])) { - $data['error_carrier_postcode'] = $this->error['carrier_postcode']; - } else { - $data['error_carrier_postcode'] = ''; - } - - if (isset($this->error['carrier_price_percentage'])) { - $data['error_carrier_price_percentage'] = $this->error['carrier_price_percentage']; - } else { - $data['error_carrier_price_percentage'] = ''; - } - - if (isset($this->error['carrier'])) { - $data['error_carrier'] = $this->error['carrier']; - } else { - $data['error_carrier'] = ''; - } - - $data['success'] = ''; - - if (isset($this->session->data['success'])) { - $data['success'] = $this->session->data['success']; - unset($this->session->data['success']); - } - - $data['from_dashboard'] = isset($this->request->get['from_dashboard']); - - $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extensions'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), - ); - - if ($data['from_dashboard']) { - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_shipping_taxes'), - 'href' => $this->url->link('extension/advertise/google/shipping_taxes', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true), - ); - } - - if ($data['from_dashboard']) { - $data['cancel'] = $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - } else { - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true); - } - - $data['action'] = $this->url->link('extension/advertise/google/shipping_taxes', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - - if (isset($this->request->post['advertise_google_shipping_taxes'])) { - $data['advertise_google_shipping_taxes'] = $this->request->post['advertise_google_shipping_taxes']; - } else if ($this->setting->has('advertise_google_shipping_taxes')) { - $data['advertise_google_shipping_taxes'] = $this->setting->get('advertise_google_shipping_taxes'); - } else { - $data['advertise_google_shipping_taxes'] = array( - 'shipping_type' => 'flat', - 'flat_rate' => $this->config->get('shipping_flat_cost'), - 'min_transit_time' => 1, - 'max_transit_time' => 14, - 'carrier_price_percentage' => 5, - 'tax_type' => $this->config->get('config_country_id') == 223 ? 'usa' : 'not_usa' - ); - } - - $data['available_carriers'] = $available_carriers; - - $data['states'] = $this->config->get('advertise_google_tax_usa_states'); - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $data['current_step'] = 4; - $data['steps'] = $this->load->view('extension/advertise/google_steps', $data); - - $this->response->setOutput($this->load->view('extension/advertise/google_shipping_taxes', $data)); - } - - public function mapping() { - $this->load->language('extension/advertise/google'); - - $this->document->setTitle($this->language->get('heading_mapping')); - - $this->document->addStyle('view/stylesheet/googleshopping/stepper.css'); - - $this->load->model('extension/advertise/google'); - - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validateMapping()) { - try { - foreach ($this->request->post['advertise_google_mapping'] as $google_product_category => $category_id) { - $this->model_extension_advertise_google->setCategoryMapping($google_product_category, $this->store_id, $category_id); - } - - if (!empty($this->request->post['advertise_google_modify_existing'])) { - $this->model_extension_advertise_google->updateGoogleProductCategoryMapping($this->store_id); - } - - $this->session->data['success'] = $this->language->get('success_mapping'); - - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->error['warning'] = $e->getMessage(); - } - } - - $data = array(); - - $data['error'] = ''; - - if (isset($this->session->data['error'])) { - $data['error'] = $this->session->data['error']; - unset($this->session->data['error']); - } else if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - $data['success'] = ''; - - if (isset($this->session->data['success'])) { - $data['success'] = $this->session->data['success']; - unset($this->session->data['success']); - } - - $data['from_dashboard'] = isset($this->request->get['from_dashboard']); - - $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extensions'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), - ); - - if ($data['from_dashboard']) { - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_shipping_taxes'), - 'href' => $this->url->link('extension/advertise/google/mapping', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true), - ); - } - - $this->load->config('googleshopping/googleshopping'); - - $data['mapping'] = array(); - - foreach ($this->config->get('advertise_google_google_product_categories') as $google_product_category_id => $google_product_category_name) { - if ($google_product_category_id == 0) continue; - - $category_id = ''; - $name = ''; - - if (null !== $category = $this->model_extension_advertise_google->getMappedCategory($google_product_category_id, $this->store_id)) { - $category_id = $category['category_id']; - $name = $category['name']; - } - - $map = array( - 'google_product_category' => array( - 'id' => $google_product_category_id, - 'name' => $google_product_category_name - ), - 'oc_category' => array( - 'category_id' => $category_id, - 'name' => $name - ) - ); - - $data['mapping'][] = $map; - } - - $data['mapping_json'] = json_encode($data['mapping']); - - if ($data['from_dashboard']) { - $data['cancel'] = $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - } else { - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true); - } - - $data['action'] = $this->url->link('extension/advertise/google/mapping', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - - $data['user_token'] = $this->session->data['user_token']; - - $data['url_mapping_verify'] = html_entity_decode($this->url->link('extension/advertise/google/mapping_verify', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['url_category_autocomplete'] = html_entity_decode($this->url->link('extension/advertise/google/category_autocomplete', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $data['current_step'] = 5; - $data['steps'] = $this->load->view('extension/advertise/google_steps', $data); - - $this->response->setOutput($this->load->view('extension/advertise/google_mapping', $data)); - } - - public function mapping_verify() { - $this->load->language('extension/advertise/google'); - - $this->load->model('extension/advertise/google'); - - $data = array(); - - $json = array( - 'submit_directly' => !$this->model_extension_advertise_google->isAnyProductCategoryModified($this->store_id), - 'modal_confirmation' => $this->load->view('extension/advertise/google_mapping_verify', $data) - ); - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function campaign_test() { - $json = array( - 'status' => false, - 'redirect' => null, - 'error' => null - ); - - if ($this->validatePermission()) { - try { - $json['status'] = $this->googleshopping->testCampaigns(); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $json['redirect'] = html_entity_decode($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - } catch (\RuntimeException $e) { - $json['status'] = false; - $json['error'] = $e->getMessage(); - } - - $this->applyNewSettings(array( - 'advertise_google_can_edit_campaigns' => (int)$json['status'] - )); - } else { - $json['error'] = $this->error['warning']; - } - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function campaign() { - $this->load->language('extension/advertise/google'); - - $this->document->setTitle($this->language->get('heading_campaign')); - - $this->document->addStyle('view/stylesheet/googleshopping/stepper.css'); - - $this->load->model('extension/advertise/google'); - - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validateCampaign()) { - $this->applyNewSettings($this->request->post); - - // If there is no redirect from the push of targets, go back to the extension dashboard - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - - $data = array(); - - $data['error'] = ''; - - if (isset($this->session->data['error'])) { - $data['error'] = $this->session->data['error']; - unset($this->session->data['error']); - } else if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - $data['success'] = ''; - - if (isset($this->session->data['success'])) { - $data['success'] = $this->session->data['success']; - unset($this->session->data['success']); - } - - $data['warning'] = ''; - - if (!$this->setting->get('advertise_google_status') && $this->model_extension_advertise_google->hasActiveTarget($this->store_id)) { - $data['warning'] = $this->language->get('warning_paused_targets'); - } - - $data['from_dashboard'] = isset($this->request->get['from_dashboard']); - - $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extensions'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), - ); - - if ($data['from_dashboard']) { - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_campaign'), - 'href' => $this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&from_dashboard=true', true), - ); - } - - if (isset($this->request->post['advertise_google_auto_advertise'])) { - $data['advertise_google_auto_advertise'] = $this->request->post['advertise_google_auto_advertise']; - } else if ($this->setting->has('advertise_google_auto_advertise')) { - $data['advertise_google_auto_advertise'] = $this->setting->get('advertise_google_auto_advertise'); - } else { - $data['advertise_google_auto_advertise'] = '0'; - } - - if ($data['from_dashboard']) { - $data['cancel'] = $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - } else { - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true); - } - - $data['action'] = $this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - $data['target_add'] = html_entity_decode($this->url->link('extension/advertise/google/target_add', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['target_edit'] = html_entity_decode($this->url->link('extension/advertise/google/target_edit', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&advertise_google_target_id={target_id}', true), ENT_QUOTES, 'UTF-8'); - $data['target_delete'] = html_entity_decode($this->url->link('extension/advertise/google/target_delete', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&advertise_google_target_id={target_id}', true), ENT_QUOTES, 'UTF-8'); - $data['target_list'] = html_entity_decode($this->url->link('extension/advertise/google/target_list', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['url_campaign_test'] = html_entity_decode($this->url->link('extension/advertise/google/campaign_test', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $data['can_edit_campaigns'] = (bool)$this->setting->get('advertise_google_can_edit_campaigns'); - $data['text_roas_warning'] = sprintf($this->language->get('warning_roas'), date($this->language->get('date_format_long'), time() + Googleshopping::ROAS_WAIT_INTERVAL)); - - $data['json_allowed_targets'] = json_encode($this->model_extension_advertise_google->getAllowedTargets()); - - $targets = $this->googleshopping->getTargets($this->store_id); - - foreach ($targets as &$target) { - if (!$target['roas_status']) { - $target['roas_warning'] = sprintf($this->language->get('warning_roas'), date($this->language->get('date_format_long'), $target['roas_available_on'])); - } else { - $target['roas_warning'] = null; - } - } - - $data['targets'] = $targets; - $data['json_targets'] = json_encode($targets); - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $data['current_step'] = 3; - $data['steps'] = $this->load->view('extension/advertise/google_steps', $data); - - $this->response->setOutput($this->load->view('extension/advertise/google_campaign', $data)); - } - - public function target_add() { - $this->load->language('extension/advertise/google'); - - $json = array( - 'success' => null, - 'redirect' => null, - 'error' => null - ); - - if ($this->validatePermission()) { - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validateTarget()) { - $this->load->model('extension/advertise/google'); - - $target = array( - 'store_id' => $this->store_id, - 'campaign_name' => str_replace(',', ',', trim($this->request->post['campaign_name'])), - 'country' => $this->request->post['country'], - 'status' => $this->request->post['status'] == 'active' ? 'active' : 'paused', - 'budget' => (float)preg_replace('~[^0-9\.]~i', '', $this->request->post['budget']), - 'roas' => isset($this->request->post['roas']) ? (int)$this->request->post['roas'] : 0, - 'feeds' => array_values($this->request->post['feed']) - ); - - $this->model_extension_advertise_google->addTarget($target, $this->store_id); - - try { - $this->googleshopping->pushTargets(); - - $json['success'] = $this->language->get('success_target_add'); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $json['redirect'] = html_entity_decode($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - } catch (\RuntimeException $e) { - $json['error'] = $e->getMessage(); - } - } else { - $json['error'] = $this->error['warning']; - - if (isset($this->error['campaign_name'])) { - $json['error_campaign_name'] = $this->error['campaign_name']; - } - - if (isset($this->error['country'])) { - $json['error_country'] = $this->error['country']; - } - - if (isset($this->error['budget'])) { - $json['error_budget'] = $this->error['budget']; - } - - if (isset($this->error['feed'])) { - $json['error_feed'] = $this->error['feed']; - } - } - } else { - $json['error'] = $this->error['warning']; - } - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function target_edit() { - $this->load->language('extension/advertise/google'); - - $json = array( - 'success' => null, - 'redirect' => null, - 'error' => null - ); - - if ($this->validatePermission()) { - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validateTarget()) { - $this->load->model('extension/advertise/google'); - - $target = array( - 'campaign_name' => str_replace(',', ',', trim($this->request->post['campaign_name'])), - 'country' => $this->request->post['country'], - 'status' => $this->request->post['status'] == 'active' ? 'active' : 'paused', - 'budget' => (float)preg_replace('~[^0-9\.]~i', '', $this->request->post['budget']), - 'roas' => isset($this->request->post['roas']) ? (int)$this->request->post['roas'] : 0, - 'feeds' => array_values($this->request->post['feed']) - ); - - $this->googleshopping->editTarget((int)$this->request->get['advertise_google_target_id'], $target); - - try { - $this->googleshopping->pushTargets(); - - $json['success'] = $this->language->get('success_target_edit'); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $json['redirect'] = html_entity_decode($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - } catch (\RuntimeException $e) { - $json['error'] = $e->getMessage(); - } - } else { - $json['error'] = $this->error['warning']; - - if (isset($this->error['campaign_name'])) { - $json['error_campaign_name'] = $this->error['campaign_name']; - } - - if (isset($this->error['country'])) { - $json['error_country'] = $this->error['country']; - } - - if (isset($this->error['budget'])) { - $json['error_budget'] = $this->error['budget']; - } - - if (isset($this->error['feed'])) { - $json['error_feed'] = $this->error['feed']; - } - } - } else { - $json['error'] = $this->error['warning']; - } - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function target_delete() { - $this->load->language('extension/advertise/google'); - - $json = array( - 'success' => null, - 'redirect' => null, - 'error' => null - ); - - if ($this->validatePermission()) { - $this->load->model('extension/advertise/google'); - - $advertise_google_target_id = (int)$this->request->get['advertise_google_target_id']; - - $target_info = $this->googleshopping->getTarget($advertise_google_target_id); - - if (!empty($target_info)) { - try { - $this->googleshopping->deleteCampaign($target_info['campaign_name']); - - $this->googleshopping->deleteTarget($advertise_google_target_id); - - $json['success'] = $this->language->get('success_target_delete'); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $json['redirect'] = html_entity_decode($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - } catch (\RuntimeException $e) { - $json['error'] = $e->getMessage(); - } - } - } else { - $json['error'] = $this->error['warning']; - } - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function target_list() { - $this->load->language('extension/advertise/google'); - - $json = array( - 'targets' => null, - 'error' => null - ); - - $this->load->model('extension/advertise/google'); - - $targets = $this->googleshopping->getTargets($this->store_id); - - foreach ($targets as &$target) { - if (!$target['roas_status']) { - $target['roas_warning'] = sprintf($this->language->get('warning_roas'), date($this->language->get('date_format_long'), $target['roas_available_on'])); - } else { - $target['roas_warning'] = null; - } - } - - $json['targets'] = $targets; - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function callback_merchant() { - $state_verified = - !empty($this->session->data['advertise_google']['state']) && - !empty($this->request->get['state']) && - $this->request->get['state'] == $this->session->data['advertise_google']['state']; - - $error = isset($this->request->get['error']) ? $this->request->get['error'] : null; - $merchant_id = isset($this->request->get['merchant_id']) ? $this->request->get['merchant_id'] : null; - - if ($state_verified && is_null($error)) { - $this->load->language('extension/advertise/google'); - - try { - $this->googleshopping->verifySite(); - - $this->load->model('user/user'); - $user_info = $this->model_user_user->getUser($this->user->getId()); - - $this->applyNewSettings(array( - 'advertise_google_gmc_account_selected' => true, - 'advertise_google_gmc_account_id' => $merchant_id, - 'advertise_google_gmc_account_accepted_by' => array( - 'user_id' => $user_info['user_id'], - 'user_group_id' => $user_info['user_group_id'], - 'user_group' => $user_info['user_group'], - 'username' => $user_info['username'], - 'firstname' => $user_info['firstname'], - 'lastname' => $user_info['lastname'], - 'email' => $user_info['email'], - 'ip' => $user_info['ip'] - ), - 'advertise_google_gmc_account_accepted_at' => time(), - 'advertise_google_conversion_tracker' => $this->googleshopping->getConversionTracker(), - 'advertise_google_can_edit_campaigns' => '0' - )); - - if ($this->session->data['advertise_google']['account_type'] == 'api') { - $this->session->data['success'] = sprintf($this->language->get('success_merchant_access'), $merchant_id); - } else { - $this->session->data['success'] = $this->language->get('success_merchant'); - } - - if (count($this->googleshopping->getTargets($this->store_id)) > 0) { - $this->response->redirect($this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - unset($this->session->data['advertise_google']); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->session->data['error'] = $e->getMessage(); - } - } else if (!is_null($error)) { - $this->session->data['error'] = $error; - - $setting = $this->model_setting_setting->getSetting('advertise_google', $this->store_id); - - unset($setting['advertise_google_status']); - unset($setting['advertise_google_work']); - unset($setting['advertise_google_gmc_account_selected']); - unset($setting['advertise_google_gmc_shipping_taxes_configured']); - unset($setting['advertise_google_can_edit_campaigns']); - - $this->model_setting_setting->editSetting('advertise_google', $setting, $this->store_id); - } - - unset($this->session->data['advertise_google']); - - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - - public function callback_connect() { - $state_verified = - !empty($this->session->data['advertise_google']['state']) && - !empty($this->request->get['state']) && - $this->request->get['state'] == $this->session->data['advertise_google']['state']; - - if ($state_verified) { - $this->load->language('extension/advertise/google'); - - $this->load->model('extension/advertise/google'); - - try { - $access = $this->googleshopping->access($this->session->data['advertise_google'], urldecode($this->request->get['code'])); - - $this->applyNewSettings(array( - 'advertise_google_app_id' => $this->session->data['advertise_google']['app_id'], - 'advertise_google_app_secret' => $this->session->data['advertise_google']['app_secret'], - 'advertise_google_status' => $this->session->data['advertise_google']['status'], - 'advertise_google_cron_token' => $this->session->data['advertise_google']['cron_token'], - 'advertise_google_cron_acknowledge' => $this->session->data['advertise_google']['cron_acknowledge'], - 'advertise_google_cron_email' => $this->session->data['advertise_google']['cron_email'], - 'advertise_google_cron_email_status' => $this->session->data['advertise_google']['cron_email_status'], - 'advertise_google_access_token' => $access['access_token'], - 'advertise_google_refresh_token' => $access['refresh_token'] - )); - - $this->session->data['success'] = $this->language->get('success_connect'); - - if (count($this->googleshopping->getTargets($this->store_id)) > 0 && $this->setting->get('advertise_google_gmc_account_selected')) { - $this->response->redirect($this->url->link('extension/advertise/google/campaign', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->session->data['error'] = $e->getMessage(); - } - } else if (isset($this->request->get['error'])) { - $this->session->data['error'] = $this->request->get['error']; - } - - unset($this->session->data['advertise_google']); - - if ($this->setting->get('advertise_google_gmc_account_selected')) { - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } else { - $this->response->redirect($this->url->link('extension/advertise/google/merchant', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - } - - public function connect() { - $this->load->language('extension/advertise/google'); - - $this->document->setTitle($this->language->get('heading_title')); - - $this->document->addStyle('view/stylesheet/googleshopping/stepper.css'); - - $this->load->model('extension/advertise/google'); - - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validateSettings() && $this->validateConnect()) { - unset($this->session->data['advertise_google']); - - $this->session->data['advertise_google']['app_id'] = $this->request->post['advertise_google_app_id']; - $this->session->data['advertise_google']['app_secret'] = $this->request->post['advertise_google_app_secret']; - $this->session->data['advertise_google']['status'] = $this->request->post['advertise_google_status']; - $this->session->data['advertise_google']['cron_email_status'] = $this->request->post['advertise_google_cron_email_status']; - $this->session->data['advertise_google']['cron_email'] = $this->request->post['advertise_google_cron_email']; - $this->session->data['advertise_google']['cron_token'] = $this->request->post['advertise_google_cron_token']; - $this->session->data['advertise_google']['cron_acknowledge'] = isset($this->request->post['advertise_google_cron_acknowledge']); - $this->session->data['advertise_google']['redirect_uri'] = html_entity_decode($this->url->link('extension/advertise/google/callback_connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), ENT_QUOTES, 'UTF-8'); - $this->session->data['advertise_google']['state'] = md5(microtime(true) . json_encode($this->session->data['advertise_google']) . microtime(true)); - - $url = $this->googleshopping->authorize($this->session->data['advertise_google']); - - $this->response->redirect($url); - } - - $data = array(); - - $data['error'] = ''; - - if (isset($this->session->data['error'])) { - if (empty($this->session->data['success']) && $this->getSettingValue('advertise_google_app_id', false) && $this->getSettingValue('advertise_google_app_secret', false)) { - $data['error'] = $this->session->data['error']; - } - unset($this->session->data['error']); - } else if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - $data['error_cron_email'] = $this->getValidationError('cron_email'); - $data['error_cron_acknowledge'] = $this->getValidationError('cron_acknowledge'); - - if (isset($this->error['app_id'])) { - $data['error_app_id'] = $this->error['app_id']; - } else { - $data['error_app_id'] = ''; - } - - if (isset($this->error['app_secret'])) { - $data['error_app_secret'] = $this->error['app_secret']; - } else { - $data['error_app_secret'] = ''; - } - - $data['success'] = ''; - - if (isset($this->session->data['success'])) { - $data['success'] = $this->session->data['success']; - unset($this->session->data['success']); - } - - $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extensions'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), - ); - - $data['advertise_google_status'] = $this->getSettingValue('advertise_google_status', 1); - $data['advertise_google_app_id'] = $this->getSettingValue('advertise_google_app_id', ''); - $data['advertise_google_app_secret'] = $this->getSettingValue('advertise_google_app_secret', ''); - $data['advertise_google_cron_email_status'] = $this->getSettingValue('advertise_google_cron_email_status'); - $data['advertise_google_cron_email'] = $this->getSettingValue('advertise_google_cron_email', $this->config->get('config_email')); - $data['advertise_google_cron_token'] = $this->getSettingValue('advertise_google_cron_token'); - $data['advertise_google_cron_acknowledge'] = $this->getSettingValue('advertise_google_cron_acknowledge', null, true); - - $server = $this->googleshopping->getStoreUrl(); - - $data['advertise_google_cron_command'] = 'export CUSTOM_SERVER_NAME=' . parse_url($server, PHP_URL_HOST) . '; export CUSTOM_SERVER_PORT=443; export ADVERTISE_GOOGLE_CRON=1; export ADVERTISE_GOOGLE_STORE_ID=' . $this->store_id . '; ' . PHP_BINDIR . '/php -d session.save_path=' . session_save_path() . ' -d memory_limit=256M ' . DIR_SYSTEM . 'library/googleshopping/cron.php > /dev/null 2> /dev/null'; - - if (!$this->setting->get('advertise_google_cron_token')) { - $data['advertise_google_cron_token'] = md5(mt_rand()); - } - - $host_and_uri = parse_url($server, PHP_URL_HOST) . dirname(parse_url($server, PHP_URL_PATH)); - - $data['advertise_google_cron_url'] = 'https://' . rtrim($host_and_uri, '/') . '/index.php?route=extension/advertise/google/cron&cron_token={CRON_TOKEN}'; - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true); - $data['action'] = $this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - - $data['text_connect_intro'] = sprintf($this->language->get('text_connect_intro'), Googleshopping::API_URL); - - $data['current_step'] = 1; - $data['steps'] = $this->load->view('extension/advertise/google_steps', $data); - - $this->response->setOutput($this->load->view('extension/advertise/google_connect', $data)); - } - - public function disconnect() { - $this->load->language('extension/advertise/google'); - - if ($this->validatePermission()) { - try { - $this->load->model('setting/setting'); - - $this->googleshopping->disconnect(); - - foreach ($this->googleshopping->getTargets($this->store_id) as $target) { - $this->googleshopping->deleteTarget($target['target_id']); - } - - $setting = $this->model_setting_setting->getSetting('advertise_google', $this->store_id); - - unset($setting['advertise_google_status']); - unset($setting['advertise_google_work']); - unset($setting['advertise_google_access_token']); - unset($setting['advertise_google_refresh_token']); - unset($setting['advertise_google_gmc_account_selected']); - unset($setting['advertise_google_gmc_shipping_taxes_configured']); - unset($setting['advertise_google_can_edit_campaigns']); - - $this->model_setting_setting->editSetting('advertise_google', $setting, $this->store_id); - - $this->session->data['success'] = $this->language->get('success_disconnect'); - } catch (ConnectionException $e) { - $this->session->data['error'] = $e->getMessage(); - - $this->response->redirect($this->url->link('extension/advertise/google/connect', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } catch (\RuntimeException $e) { - $this->session->data['error'] = $e->getMessage(); - } - } else { - $this->session->data['error'] = $this->error['warning']; - } - - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - - public function checklist() { - $this->load->language('extension/advertise/google'); - - $this->document->setTitle($this->language->get('heading_title')); - - if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validatePermission()) { - $this->load->model('setting/setting'); - - $this->model_setting_setting->editSetting('advertise_google', $this->request->post, $this->store_id); - - $this->response->redirect($this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true)); - } - - $data = array(); - - $data['error'] = ''; - - if (isset($this->session->data['error'])) { - $data['error'] = $this->session->data['error']; - unset($this->session->data['error']); - } else if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - $data['breadcrumbs'] = array(); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extensions'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true), - ); - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/advertise/google', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true), - ); - - $data['text_panel_heading'] = sprintf($this->language->get('text_panel_heading'), $this->googleshopping->getStoreName()); - - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=advertise', true); - $data['action'] = $this->url->link('extension/advertise/google/checklist', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'], true); - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $this->response->setOutput($this->load->view('extension/advertise/google_checklist', $data)); - } - - public function popup_product() { - $json = array( - 'body' => '', - 'title' => '', - 'success' => false, - 'required_fields' => [], - 'success_message' => '' - ); - - $this->language->load('extension/advertise/google'); - - $this->load->model('extension/advertise/google'); - - $operand_info = NULL; - $form_data = NULL; - $filter_data = NULL; - $product_ids = array(); - - if ($this->request->post['operand']['type'] == 'single') { - $product_advertise_google_id = $this->request->post['operand']['data']; - - $product_info = $this->model_extension_advertise_google->getProductByProductAdvertiseGoogleId($product_advertise_google_id); - - if ($product_info !== NULL) { - $json['product_id'] = $product_info['product_id']; - - // Required variables: - $operand_info = array( - 'title' => sprintf($this->language->get('text_popup_title_single'), $product_info['name'], $product_info['model']) - ); - - $required_fields = $this->model_extension_advertise_google->getRequiredFieldsByProductIds(array($product_info['product_id']), $this->store_id); - - if ($this->request->post['action'] == 'submit') { - $form_data = array_merge($this->request->post['form'], array( - 'product_id' => $product_info['product_id'] - )); - } - - $options = $this->model_extension_advertise_google->getProductOptionsByProductIds(array($product_info['product_id'])); - - $default_form_data = $this->model_extension_advertise_google->getProductAdvertiseGoogle($product_advertise_google_id); - } - } else if ($this->request->post['operand']['type'] == 'multiple') { - if (!empty($this->request->post['operand']['data']['all_pages'])) { - $filter_data = $this->getFilter($this->request->post['operand']['data']['filter']); - - $total_products = $this->googleshopping->getTotalProducts($filter_data, $this->store_id); - - // Required variables: - $operand_info = array( - 'title' => sprintf($this->language->get('text_popup_title_multiple'), $total_products) - ); - - $required_fields = $this->model_extension_advertise_google->getRequiredFieldsByFilter($filter_data, $this->store_id); - - if ($this->request->post['action'] == 'submit') { - $form_data = $this->request->post['form']; - } - - $options = $this->model_extension_advertise_google->getProductOptionsByFilter($filter_data); - } else { - $product_ids = $this->request->post['operand']['data']['select']; - - $total_products = count($product_ids); - - // Required variables: - $operand_info = array( - 'title' => sprintf($this->language->get('text_popup_title_multiple'), $total_products) - ); - - $required_fields = $this->model_extension_advertise_google->getRequiredFieldsByProductIds($product_ids, $this->store_id); - - if ($this->request->post['action'] == 'submit') { - $form_data = $this->request->post['form']; - } - - $options = $this->model_extension_advertise_google->getProductOptionsByProductIds($product_ids); - } - - $default_form_data = array( - 'google_product_category' => '', - 'condition' => '', - 'adult' => '', - 'multipack' => '', - 'is_bundle' => '', - 'age_group' => '', - 'color' => '', - 'gender' => '', - 'size_type' => '', - 'size_system' => '', - 'size' => '' - ); - } - - if ($operand_info !== NULL) { - $json['title'] = $operand_info['title']; - $json['success_message'] = $this->language->get('success_product'); - - $this->load->config('googleshopping/googleshopping'); - - $json['required_fields'] = $required_fields; - - if ($this->request->post['action'] == 'submit' && $this->validateProduct($required_fields)) { - $form_data['store_id'] = (int)$this->store_id; - - if ($this->request->post['operand']['type'] == 'single') { - $this->model_extension_advertise_google->updateSingleProductFields($form_data); - } else if ($this->request->post['operand']['type'] == 'multiple') { - if (!empty($this->request->post['operand']['data']['all_pages'])) { - $this->model_extension_advertise_google->updateMultipleProductFields($filter_data, $form_data); - } else { - foreach ($product_ids as $product_id) { - $form_data['product_id'] = (int)$product_id; - $this->model_extension_advertise_google->updateSingleProductFields($form_data); - } - } - } - - $json['success'] = true; - } - - $data['error'] = ''; - - if (!empty($this->error['warning'])) { - $data['error'] = $this->error['warning']; - } - - if (isset($this->error['color'])) { - $data['error_color'] = $this->error['color']; - } else { - $data['error_color'] = ''; - } - - if (isset($this->error['size_system'])) { - $data['error_size_system'] = $this->error['size_system']; - } else { - $data['error_size_system'] = ''; - } - - if (isset($this->error['size_type'])) { - $data['error_size_type'] = $this->error['size_type']; - } else { - $data['error_size_type'] = ''; - } - - if (isset($this->error['size'])) { - $data['error_size'] = $this->error['size']; - } else { - $data['error_size'] = ''; - } - - if (isset($this->error['product_category'])) { - $data['error_product_category'] = $this->error['product_category']; - } else { - $data['error_product_category'] = ''; - } - - if (isset($this->error['condition'])) { - $data['error_condition'] = $this->error['condition']; - } else { - $data['error_condition'] = ''; - } - - if (isset($this->error['age_group'])) { - $data['error_age_group'] = $this->error['age_group']; - } else { - $data['error_age_group'] = ''; - } - - if (isset($this->error['gender'])) { - $data['error_gender'] = $this->error['gender']; - } else { - $data['error_gender'] = ''; - } - - if (isset($this->error['adult'])) { - $data['error_adult'] = $this->error['adult']; - } else { - $data['error_adult'] = ''; - } - - if (isset($this->error['multipack'])) { - $data['error_multipack'] = $this->error['multipack']; - } else { - $data['error_multipack'] = ''; - } - - if (isset($this->error['is_bundle'])) { - $data['error_is_bundle'] = $this->error['is_bundle']; - } else { - $data['error_is_bundle'] = ''; - } - - $data['google_product_categories'] = $this->config->get('advertise_google_google_product_categories'); - $data['conditions'] = array( - 'new' => $this->language->get('text_condition_new'), - 'refurbished' => $this->language->get('text_condition_refurbished'), - 'used' => $this->language->get('text_condition_used') - ); - $data['age_groups'] = array( - '' => $this->language->get('text_does_not_apply'), - 'newborn' => $this->language->get('text_age_group_newborn'), - 'infant' => $this->language->get('text_age_group_infant'), - 'toddler' => $this->language->get('text_age_group_toddler'), - 'kids' => $this->language->get('text_age_group_kids'), - 'adult' => $this->language->get('text_age_group_adult') - ); - $data['genders'] = array( - 'unisex' => $this->language->get('text_gender_unisex'), - 'female' => $this->language->get('text_gender_female'), - 'male' => $this->language->get('text_gender_male') - ); - $data['size_systems'] = array( - '' => $this->language->get('text_does_not_apply') - ); - foreach ($this->config->get('advertise_google_size_systems') as $system) { - $data['size_systems'][$system] = $system; - } - - $data['size_types'] = array( - '' => $this->language->get('text_does_not_apply'), - 'regular' => $this->language->get('text_size_type_regular'), - 'petite' => $this->language->get('text_size_type_petite'), - 'plus' => $this->language->get('text_size_type_plus'), - 'big and tall' => $this->language->get('text_size_type_big_and_tall'), - 'maternity' => $this->language->get('text_size_type_maternity') - ); - - $data['options'] = array( - '' => $this->language->get('text_does_not_apply') - ); - - foreach ($options as $option) { - $data['options'][$option['option_id']] = $option['name']; - } - - $data['required_fields'] = json_encode($required_fields); - - if ($this->request->post['action'] == 'submit') { - $form_data = $this->request->post['form']; - } else { - $form_data = $default_form_data; - } - - $data['google_product_category'] = $form_data['google_product_category']; - $data['condition'] = $form_data['condition']; - $data['adult'] = $form_data['adult']; - $data['multipack'] = $form_data['multipack']; - $data['is_bundle'] = $form_data['is_bundle']; - $data['age_group'] = $form_data['age_group']; - $data['color'] = $form_data['color']; - $data['gender'] = $form_data['gender']; - $data['size_type'] = $form_data['size_type']; - $data['size_system'] = $form_data['size_system']; - $data['size'] = $form_data['size']; - - $json['body'] = $this->load->view('extension/advertise/google_popup_product', $data); - } else { - $json['title'] = $this->language->get('error_popup_not_found_title'); - $json['body'] = $this->language->get('error_popup_not_found_body'); - } - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function popup_issues() { - $json = array( - 'body' => '', - 'title' => '' - ); - - $this->language->load('extension/advertise/google'); - - $this->load->model('catalog/product'); - $this->load->model('extension/advertise/google'); - - $product_id = isset($this->request->get['product_id']) ? (int)$this->request->get['product_id'] : 0; - - $product_issues = $this->model_extension_advertise_google->getProductIssues($product_id, $this->store_id); - - if ($product_issues !== NULL) { - $json['title'] = sprintf($this->language->get('text_popup_title_single'), $product_issues['name'], $product_issues['model']); - - $data['product_issues'] = $product_issues['entries']; - - $json['body'] = $this->load->view('extension/advertise/google_popup_issues', $data); - } else { - $json['title'] = $this->language->get('error_popup_not_found_title'); - $json['body'] = $this->language->get('error_popup_not_found_body'); - } - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - public function admin_link(&$route, &$data, &$template) { - if (!$this->user->hasPermission('access', 'extension/advertise/google')) { - return; - } - - foreach ($data['menus'] as &$menu) { - if ($menu['id'] == 'menu-marketing') { - $children = array(); - - $this->load->model('setting/store'); - - $children[] = array( - 'name' => $this->config->get('config_name'), - 'children' => array(), - 'href' => $this->url->link('extension/advertise/google', 'store_id=0&user_token=' . $this->session->data['user_token'], true) - ); - - foreach ($this->model_setting_store->getStores() as $store) { - $children[] = array( - 'name' => $store['name'], - 'children' => array(), - 'href' => $this->url->link('extension/advertise/google', 'store_id=' . $store['store_id'] . '&user_token=' . $this->session->data['user_token'], true) - ); - } - - array_push($menu['children'], array( - 'name' => 'Google Shopping', - 'children' => $children, - 'href' => '' - )); - - return; - } - } - } - - public function addProduct(&$route, &$args, &$output) { - $this->load->model('extension/advertise/google'); - $this->load->model('catalog/product'); - - foreach ($this->model_catalog_product->getProductStores($output) as $store_id) { - $this->model_extension_advertise_google->insertNewProducts(array($output), $store_id); - } - } - - public function copyProduct(&$route, &$args, &$output) { - $this->load->model('extension/advertise/google'); - $this->load->model('catalog/product'); - - $final_product_id = $this->model_extension_advertise_google->getFinalProductId(); - - if (!empty($final_product_id)) { - foreach ($this->model_catalog_product->getProductStores($final_product_id) as $store_id) { - $this->model_extension_advertise_google->insertNewProducts(array($final_product_id), $store_id); - } - } - } - - public function deleteProduct(&$route, &$args, &$output) { - $this->load->model('extension/advertise/google'); - - $this->model_extension_advertise_google->deleteProducts(array((int)$args[0])); - } - - public function install() { - $this->load->model('extension/advertise/google'); - - $this->model_extension_advertise_google->createTables(); - $this->model_extension_advertise_google->createEvents(); - } - - public function uninstall() { - $this->load->model('extension/advertise/google'); - - $this->model_extension_advertise_google->dropTables(); - $this->model_extension_advertise_google->deleteEvents(); - } - - public function category_autocomplete() { - $json = array(); - - if (isset($this->request->get['filter_name'])) { - $this->load->model('extension/advertise/google'); - - $filter_data = array( - 'filter_name' => $this->request->get['filter_name'], - 'sort' => 'name', - 'order' => 'ASC', - 'start' => 0, - 'limit' => $this->config->get('config_limit_autocomplete') - ); - - $results = $this->model_extension_advertise_google->getCategories($filter_data, $this->store_id); - - foreach ($results as $result) { - $json[] = array( - 'category_id' => $result['category_id'], - 'name' => strip_tags(html_entity_decode($result['name'], ENT_QUOTES, 'UTF-8')) - ); - } - } - - $sort_order = array(); - - foreach ($json as $key => $value) { - $sort_order[$key] = $value['name']; - } - - array_multisort($sort_order, SORT_ASC, $json); - - $this->response->addHeader('Content-Type: application/json'); - $this->response->setOutput(json_encode($json)); - } - - protected function getFilter($array) { - if (!empty($array)) { - return array( - 'filter_product_name' => $array['product_name'], - 'filter_product_model' => $array['product_model'], - 'filter_category_id' => $array['category_id'], - 'filter_is_modified' => $array['is_modified'], - 'filter_store_id' => $this->store_id - ); - } - - return array( - 'filter_store_id' => $this->store_id - ); - } - - protected function applyNewSettings($new_settings) { - $this->load->model('setting/setting'); - - $old_settings = $this->model_setting_setting->getSetting('advertise_google', $this->store_id); - - $new_settings = array_merge($old_settings, $new_settings); - - $this->model_setting_setting->editSetting('advertise_google', $new_settings, $this->store_id); - - foreach ($new_settings as $key => $value) { - $this->setting->set($key, $value); - } - } - - protected function product(&$row) { - $this->load->config('googleshopping/googleshopping'); - - $this->load->model('tool/image'); - - if (!empty($row['image']) && file_exists(DIR_IMAGE . $row['image'])) { - $image = $this->model_tool_image->resize($row['image'], 50, 50); - } else { - $image = $this->model_tool_image->resize('no_image.png', 50, 50); - } - - return array( - 'product_advertise_google_id' => (int)$row['product_advertise_google_id'], - 'product_id' => (int)$row['product_id'], - 'image' => $image, - 'name' => htmlentities(html_entity_decode($row['name'], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'), - 'model' => $row['model'], - 'impressions' => (int)$row['impressions'], - 'clicks' => (int)$row['clicks'], - 'conversions' => (int)$row['conversions'], - 'cost' => $this->googleshopping->currencyFormat($row['cost']), - 'conversion_value' => $this->googleshopping->currencyFormat($row['conversion_value']), - 'destination_status' => $row['destination_status'], - 'is_modified' => (bool)$row['is_modified'], - 'has_issues' => (bool)$row['has_issues'], - 'url_issues' => html_entity_decode($this->url->link('extension/advertise/google/popup_issues', 'store_id=' . $this->store_id . '&user_token=' . $this->session->data['user_token'] . '&product_id=' . $row['product_id'], true), ENT_QUOTES, 'UTF-8'), - 'campaigns' => $this->model_extension_advertise_google->getProductCampaigns((int)$row['product_id'], $this->store_id) - ); - } - - protected function getSettingValue($key, $default = null, $checkbox = false) { - if ($checkbox) { - if ($this->request->server['REQUEST_METHOD'] == 'POST' && !isset($this->request->post[$key])) { - return $default; - } else { - return $this->setting->get($key); - } - } - - if (isset($this->request->post[$key])) { - return $this->request->post[$key]; - } else if ($this->setting->has($key)) { - return $this->setting->get($key); - } else { - return $default; - } - } - - protected function getValidationError($key) { - if (isset($this->error[$key])) { - return $this->error[$key]; - } else { - return ''; - } - } - - protected function validateSettings() { - $this->validatePermission(); - - if (empty($this->request->post['advertise_google_status'])) { - return true; - } - - if (!empty($this->request->post['advertise_google_cron_email_status'])) { - if (!filter_var($this->request->post['advertise_google_cron_email'], FILTER_VALIDATE_EMAIL)) { - $this->error['cron_email'] = $this->language->get('error_invalid_email'); - } - } - - if (empty($this->request->post['advertise_google_cron_acknowledge'])) { - $this->error['cron_acknowledge'] = $this->language->get('error_cron_acknowledge'); - } - - if ($this->error && empty($this->error['warning'])) { - $this->error['warning'] = $this->language->get('error_form'); - } - - return !$this->error; - } - - protected function validateShippingAndTaxes() { - $this->validatePermission(); - - if (empty($this->request->post['advertise_google_shipping_taxes']['min_transit_time']) || !is_numeric($this->request->post['advertise_google_shipping_taxes']['min_transit_time']) || (int)$this->request->post['advertise_google_shipping_taxes']['min_transit_time'] < 0) { - $this->error['min_transit_time'] = $this->language->get('error_min_transit_time'); - } else if (empty($this->request->post['advertise_google_shipping_taxes']['max_transit_time']) || !is_numeric($this->request->post['advertise_google_shipping_taxes']['max_transit_time']) || (int)$this->request->post['advertise_google_shipping_taxes']['max_transit_time'] < (int)$this->request->post['advertise_google_shipping_taxes']['min_transit_time']) { - $this->error['max_transit_time'] = $this->language->get('error_max_transit_time'); - } - - switch ($this->request->post['advertise_google_shipping_taxes']['shipping_type']) { - case 'flat' : - if (!isset($this->request->post['advertise_google_shipping_taxes']['flat_rate']) || !is_numeric($this->request->post['advertise_google_shipping_taxes']['flat_rate']) || (float)$this->request->post['advertise_google_shipping_taxes']['flat_rate'] <= 0) { - $this->error['flat_rate'] = $this->language->get('error_flat_rate'); - } - break; - case 'carrier' : - if (empty($this->request->post['advertise_google_shipping_taxes']['carrier'])) { - $this->error['warning'] = $this->language->get('error_carrier'); - } - - if (empty($this->request->post['advertise_google_shipping_taxes']['carrier_postcode'])) { - $this->error['carrier_postcode'] = $this->language->get('error_carrier_postcode'); - } - - if (!isset($this->request->post['advertise_google_shipping_taxes']['carrier_price_percentage']) || !is_numeric($this->request->post['advertise_google_shipping_taxes']['carrier_price_percentage']) || (float)$this->request->post['advertise_google_shipping_taxes']['carrier_price_percentage'] < 0 || (float)$this->request->post['advertise_google_shipping_taxes']['carrier_price_percentage'] > 100) { - $this->error['carrier_price_percentage'] = $this->language->get('error_carrier_price_percentage'); - } - break; - } - - switch ($this->request->post['advertise_google_shipping_taxes']['tax_type']) { - case 'usa' : - if (empty($this->request->post['advertise_google_shipping_taxes']['tax'])) { - $this->error['warning'] = $this->language->get('error_tax'); - } - break; - } - - if (!isset($this->error['warning']) && $this->error) { - $this->error['warning'] = $this->language->get('error_warning'); - } - - return !$this->error; - } - - protected function validateMapping() { - $this->validatePermission(); - - if (!isset($this->error['warning']) && $this->error) { - $this->error['warning'] = $this->language->get('error_warning'); - } - - return !$this->error; - } - - protected function validateProduct($required_fields) { - if (!$this->user->hasPermission('modify', 'extension/advertise/google')) { - $this->error['warning'] = $this->language->get('error_permission'); - } - - if (empty($this->error)) { - foreach ($required_fields as $key => $requirements) { - if (empty($requirements['selected_field']) && (!isset($this->request->post['form'][$key]) || $this->request->post['form'][$key] == '')) { - $this->error[$key] = $this->language->get('error_field_no_value'); - } else if (!empty($requirements['selected_field'])) { - foreach ($requirements['selected_field'] as $dependency => $values) { - if (in_array($this->request->post['form'][$dependency], $values) && (!isset($this->request->post['form'][$key]) || $this->request->post['form'][$key] == '')) { - $this->error[$key] = $this->language->get('error_field_no_value'); - } - } - } - } - } - - if (!isset($this->error['warning']) && $this->error) { - $this->error['warning'] = $this->language->get('error_warning'); - } - - return !$this->error; - } - - protected function validatePermission() { - if (!$this->user->hasPermission('modify', 'extension/advertise/google')) { - $this->error['warning'] = $this->language->get('error_permission'); - } - - return !$this->error; - } - - protected function validateCampaign() { - $this->validatePermission(); - - $this->load->model('extension/advertise/google'); - - $targets = $this->googleshopping->getTargets($this->store_id); - - if (empty($targets)) { - $this->error['warning'] = $this->language->get('error_no_targets'); - } - - if (!isset($this->error['warning']) && $this->error) { - $this->error['warning'] = $this->language->get('error_warning'); - } - - return !$this->error; - } - - protected function validateConnect() { - $this->validatePermission(); - - if (!isset($this->request->post['advertise_google_app_id']) || trim($this->request->post['advertise_google_app_id']) == '') { - $this->error['app_id'] = $this->language->get('error_empty_app_id'); - } else if ($this->model_extension_advertise_google->isAppIdUsed($this->request->post['advertise_google_app_id'], $this->store_id)) { - $this->error['app_id'] = $this->language->get('error_used_app_id'); - } - - if (!isset($this->request->post['advertise_google_app_secret']) || trim($this->request->post['advertise_google_app_secret']) == '') { - $this->error['app_secret'] = $this->language->get('error_empty_app_secret'); - } - - if (!isset($this->error['warning']) && $this->error) { - $this->error['warning'] = $this->language->get('error_warning'); - } - - return !$this->error; - } - - protected function validateTarget() { - $this->validatePermission(); - - if (!isset($this->request->post['budget']) || !is_numeric($this->request->post['budget']) || (float)$this->request->post['budget'] < 5) { - $this->error['budget'] = $this->language->get('error_budget'); - } - - if (empty($this->request->post['feed']) || !is_array($this->request->post['feed'])) { - $this->error['feed'] = $this->language->get('error_empty_feed'); - } else { - foreach ($this->request->post['feed'] as $feed) { - if (empty($feed['language']) || empty($feed['currency'])) { - $this->error['feed'] = $this->language->get('error_invalid_feed'); - break; - } - } - } - - if (empty($this->request->post['country'])) { - $this->error['country'] = $this->language->get('error_empty_country'); - } - - if (empty($this->request->post['campaign_name']) || trim($this->request->post['campaign_name']) == '') { - $this->error['campaign_name'] = $this->language->get('error_empty_campaign_name'); - } else { - $disallowed_names = []; - - $this->load->model('extension/advertise/google'); - - foreach ($this->googleshopping->getTargets($this->store_id) as $existing_target) { - if (isset($this->request->get['advertise_google_target_id']) && $existing_target['target_id'] == $this->request->get['advertise_google_target_id']) { - // Ignore this target as it is currntly being edited - continue; - } - - $disallowed_names[] = strtolower(str_replace(',', ',', trim($existing_target['campaign_name']))); - } - - if (in_array(trim(strtolower($this->request->post['campaign_name'])), $disallowed_names)) { - $this->error['campaign_name'] = $this->language->get('error_campaign_name_in_use'); - } - - if (strtolower(trim($this->request->post['campaign_name'])) == 'total') { - $this->error['campaign_name'] = $this->language->get('error_campaign_name_total'); - } - } - - if (!isset($this->error['warning']) && $this->error) { - $this->error['warning'] = $this->language->get('error_warning'); - } - - return !$this->error; - } -} \ No newline at end of file diff --git a/public/admin/controller/extension/analytics/google.php b/public/admin/controller/extension/analytics/google.php deleted file mode 100644 index 77c39e9..0000000 --- a/public/admin/controller/extension/analytics/google.php +++ /dev/null @@ -1,85 +0,0 @@ -load->language('extension/analytics/google'); - - $this->document->setTitle($this->language->get('heading_title')); - - $this->load->model('setting/setting'); - - if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { - $this->model_setting_setting->editSetting('analytics_google', $this->request->post, $this->request->get['store_id']); - - $this->session->data['success'] = $this->language->get('text_success'); - - $this->response->redirect($this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=analytics', true)); - } - - if (isset($this->error['warning'])) { - $data['error_warning'] = $this->error['warning']; - } else { - $data['error_warning'] = ''; - } - - if (isset($this->error['code'])) { - $data['error_code'] = $this->error['code']; - } else { - $data['error_code'] = ''; - } - - $data['breadcrumbs'] = array(); - - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ); - - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extension'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=analytics', true) - ); - - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/analytics/google', 'user_token=' . $this->session->data['user_token'] . '&store_id=' . $this->request->get['store_id'], true) - ); - - $data['action'] = $this->url->link('extension/analytics/google', 'user_token=' . $this->session->data['user_token'] . '&store_id=' . $this->request->get['store_id'], true); - - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=analytics', true); - - $data['user_token'] = $this->session->data['user_token']; - - if (isset($this->request->post['analytics_google_code'])) { - $data['analytics_google_code'] = $this->request->post['analytics_google_code']; - } else { - $data['analytics_google_code'] = $this->model_setting_setting->getSettingValue('analytics_google_code', $this->request->get['store_id']); - } - - if (isset($this->request->post['analytics_google_status'])) { - $data['analytics_google_status'] = $this->request->post['analytics_google_status']; - } else { - $data['analytics_google_status'] = $this->model_setting_setting->getSettingValue('analytics_google_status', $this->request->get['store_id']); - } - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $this->response->setOutput($this->load->view('extension/analytics/google', $data)); - } - - protected function validate() { - if (!$this->user->hasPermission('modify', 'extension/analytics/google')) { - $this->error['warning'] = $this->language->get('error_permission'); - } - - if (!$this->request->post['analytics_google_code']) { - $this->error['code'] = $this->language->get('error_code'); - } - - return !$this->error; - } -} diff --git a/public/admin/controller/extension/captcha/google.php b/public/admin/controller/extension/captcha/google.php deleted file mode 100644 index e6a98c6..0000000 --- a/public/admin/controller/extension/captcha/google.php +++ /dev/null @@ -1,99 +0,0 @@ -load->language('extension/captcha/google'); - - $this->document->setTitle($this->language->get('heading_title')); - - $this->load->model('setting/setting'); - - if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { - $this->model_setting_setting->editSetting('captcha_google', $this->request->post); - - $this->session->data['success'] = $this->language->get('text_success'); - - $this->response->redirect($this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=captcha', true)); - } - - if (isset($this->error['warning'])) { - $data['error_warning'] = $this->error['warning']; - } else { - $data['error_warning'] = ''; - } - - if (isset($this->error['key'])) { - $data['error_key'] = $this->error['key']; - } else { - $data['error_key'] = ''; - } - - if (isset($this->error['secret'])) { - $data['error_secret'] = $this->error['secret']; - } else { - $data['error_secret'] = ''; - } - - $data['breadcrumbs'] = array(); - - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_home'), - 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) - ); - - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('text_extension'), - 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=captcha', true) - ); - - $data['breadcrumbs'][] = array( - 'text' => $this->language->get('heading_title'), - 'href' => $this->url->link('extension/captcha/google', 'user_token=' . $this->session->data['user_token'], true) - ); - - $data['action'] = $this->url->link('extension/captcha/google', 'user_token=' . $this->session->data['user_token'], true); - - $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=captcha', true); - - if (isset($this->request->post['captcha_google_key'])) { - $data['captcha_google_key'] = $this->request->post['captcha_google_key']; - } else { - $data['captcha_google_key'] = $this->config->get('captcha_google_key'); - } - - if (isset($this->request->post['captcha_google_secret'])) { - $data['captcha_google_secret'] = $this->request->post['captcha_google_secret']; - } else { - $data['captcha_google_secret'] = $this->config->get('captcha_google_secret'); - } - - if (isset($this->request->post['captcha_google_status'])) { - $data['captcha_google_status'] = $this->request->post['captcha_google_status']; - } else { - $data['captcha_google_status'] = $this->config->get('captcha_google_status'); - } - - $data['header'] = $this->load->controller('common/header'); - $data['column_left'] = $this->load->controller('common/column_left'); - $data['footer'] = $this->load->controller('common/footer'); - - $this->response->setOutput($this->load->view('extension/captcha/google', $data)); - } - - protected function validate() { - if (!$this->user->hasPermission('modify', 'extension/captcha/google')) { - $this->error['warning'] = $this->language->get('error_permission'); - } - - if (!$this->request->post['captcha_google_key']) { - $this->error['key'] = $this->language->get('error_key'); - } - - if (!$this->request->post['captcha_google_secret']) { - $this->error['secret'] = $this->language->get('error_secret'); - } - - return !$this->error; - } -} diff --git a/public/admin/language/ru-ru/extension/advertise/google.php b/public/admin/language/ru-ru/extension/advertise/google.php deleted file mode 100644 index 3cc68bc..0000000 --- a/public/admin/language/ru-ru/extension/advertise/google.php +++ /dev/null @@ -1,323 +0,0 @@ - Localisation > Languages / Currencies'; -$_['help_gender'] = 'Specify the gender your product is designed for using the gender attribute. When you provide this information, potential customers can accurately filter products by gender to help narrow their search. Keep in mind that Google also uses the gender information together with the values you provide for Size and Age Group to standardize the sizes that are shown to users.'; -$_['help_google_product_category'] = 'Use the this attribute to indicate the category of your item based on the Google product taxonomy. Categorizing your product helps ensure that your ad is shown with the right search results.'; -$_['help_is_bundle'] = 'Use the Bundle attribute to indicate that you've created a bundle: a main product that you've grouped with other, different products, sold together as one package for a single price. This attribute lets Google show your ad in the right situations by distinguishing your item from manufacturer-created bundles, multipacks, and other products without accessories.'; -$_['help_local_cron'] = 'This method is recommended. Insert this command in your web server CRON tab. Set it up to run every hour.'; -$_['help_multipack'] = 'Use the Multipack attribute to indicate that you've grouped multiple identical products for sale as one item. This attribute lets Google show your ad in the right situations by distinguishing your item from manufacturer-created multipacks, bundles, and other products.'; -$_['help_remote_cron'] = 'Use this method in case Method #1 cannot be used. Use this URL to set up a CRON task via a web-based CRON service. Set it up to run every hour.'; -$_['help_roas'] = 'Target ROAS lets you bid based on a target return on ad spend (ROAS). This Google Ads Smart Bidding strategy helps you get more conversion value or revenue at the target return-on-ad-spend (ROAS) you set. Your bids are automatically optimized at auction-time, allowing you to tailor bids for each auction.'; -$_['help_size'] = 'Use the size attribute to describe the standardized size of your product. When you use this attribute, your ad can appear in results that are filtered by size. The size you submit will also affect how your product variants are shown.'; -$_['help_size_system'] = 'With this attribute you can explain which country's sizing system your product uses. This information helps create accurate filters, which users can use to narrow search results. The sizing system that you submit will affect search, filtering, and how variants are shown in your ad.'; -$_['help_size_type'] = 'Use this attribute to describe the cut of your product. This information helps create accurate filters, which users can use to narrow search results.'; - -// Entry -$_['entry_action'] = 'Action'; -$_['entry_adult'] = 'Adult-Only Content'; -$_['entry_age_group'] = 'Age Group'; -$_['entry_auto_advertise'] = 'Automatically advertise new listings?'; -$_['entry_budget'] = 'Daily Campaign Budget'; -$_['entry_campaign'] = 'Smart Shopping Ad Campaigns'; -$_['entry_campaign_name'] = 'Campaign Name'; -$_['entry_color'] = 'Color Option'; -$_['entry_condition'] = 'Condition'; -$_['entry_country'] = 'Target Country'; -$_['entry_feed'] = 'Product Feeds'; -$_['entry_gender'] = 'Gender'; -$_['entry_google_product_category'] = 'Google Product Category'; -$_['entry_is_bundle'] = 'Bundle'; -$_['entry_max_transit_time'] = 'Maximum Transit Time (days)'; -$_['entry_min_transit_time'] = 'Minimum Transit Time (days)'; -$_['entry_multipack'] = 'Multipack (number of items in a single package)'; -$_['entry_oc_category'] = 'OpenCart Category (autocomplete)'; -$_['entry_roas'] = 'ROAS'; -$_['entry_setup_confirmation'] = 'Setup Confirmation'; -$_['entry_size'] = 'Size Option'; -$_['entry_size_system'] = 'Size System'; -$_['entry_size_type'] = 'Size Type'; -$_['entry_status'] = 'Status'; - -// Texts -$_['text_access_token'] = 'Access token'; -$_['text_acknowledge_add_campaign_1'] = 'I acknowledge that my campaigns will not become active until my product feeds get approved according to the Google Merchant Center requirements.'; -$_['text_acknowledge_add_campaign_2'] = 'I acknowledge that my campaigns will not become active until I set up Shipping and Tax (only in the US) details for my Merchant Center account.'; -$_['text_acknowledge_cron'] = 'I confirm that I have set up an automated CRON task using one of the methods above.'; -$_['text_acknowledge_merchant_tos'] = 'By purchasing Google Shopping ads, I agree to comply with Google's terms and policies, including Google's Merchant Center terms of service, Shopping ads policies, and Google Ads Terms and Conditions.'; -$_['text_action'] = 'Action'; -$_['text_active'] = 'Active'; -$_['text_active_states'] = 'Select active states'; -$_['text_add_target'] = 'New Campaign'; -$_['text_ads_intro'] = '

Important

To have your products accepted by Google Merchant Center, please make sure to follow these requirements:

'; -$_['text_advertise'] = 'Advertise'; -$_['text_age_group_adult'] = 'Adult (teens or older)'; -$_['text_age_group_infant'] = 'Infant (3-12 months old)'; -$_['text_age_group_kids'] = 'Kids (6-13 years old)'; -$_['text_age_group_newborn'] = 'Newborn (0-2 months old)'; -$_['text_age_group_toddler'] = 'Toddler (1-5 years old)'; -$_['text_all'] = 'All'; -$_['text_app_id'] = 'App ID'; -$_['text_app_secret'] = 'App Secret'; -$_['text_approved'] = 'Approved'; -$_['text_campaign_more_info'] = '

Campaign Duration

Campaigns will run until paused. You can pause a campaign at any time.


Campaign Optimization

It usually takes around 30 days for Google to rank products and optimize shopping ad campaigns.


Products in Campaign

Google will create a unique shopping ad for each approved product synced to your Merchant Center account. Ads are optimized based to maximize your sales. Popular products will likely receive more of your budget.


Campaign Duration

Campaigns will run until paused. You can pause a campaign at any time.


Shopping Ad Placement

Your ads may appear on multiple platforms including Google Search, Google Display Network, Youtube, and Gmail.

'; -$_['text_campaigns'] = 'Campaigns'; -$_['text_carrier_postcode'] = 'Origin Postal Code'; -$_['text_carrier_price_percentage'] = 'Price Percentage'; -$_['text_checklist_acknowledge_0'] = '

Видимость каталога товаров

Я подтверждаю, что мой каталог товаров общедоступен без необходимости ввода пароля.

'; -$_['text_checklist_acknowledge_1'] = '

Безопасный процесс оформления заказа

Обработка платежей и транзакций, а также сбор любой конфиденциальной и финансовой информации от пользователя осуществляется через безопасный сервер обработки (защищенный SSL, с действующим сертификатом SSL - https: //).

'; -$_['text_checklist_acknowledge_2'] = '

Политика возврата

Я подтверждаю, что мой веб-сайт предоставляет пользователям четкую и понятную политику возврата.

'; -$_['text_checklist_acknowledge_3'] = '

Условия выставления счетов и оплаты

Я подтверждаю, что мой веб-сайт предоставляет четкие и понятные условия выставления счетов и оплаты.

'; -$_['text_checklist_acknowledge_4'] = '

Достоверная контактная информация

Я подтверждаю, что мой веб-сайт отображает достаточную и точную контактную информацию с как минимум двумя из следующего: номер телефона, физический адрес, адрес электронной почты.

'; -$_['text_checklist_intro'] = '

Важно

Прежде чем вы сможете размещать рекламу в Google, ваш интернет-магазин должен соответствовать требованиям Google Merchant Center. Полный список всех требований и рекомендаций можно найти здесь.'; -$_['text_clicks'] = 'Clicks'; -$_['text_color'] = 'Color'; -$_['text_condition_new'] = 'New'; -$_['text_condition_refurbished'] = 'Refurbished'; -$_['text_condition_used'] = 'Used'; -$_['text_connect_intro'] = 'Your Google Shopping extension is not yet connected. Please go to the Google Shopping for OpenCart website to obtain an App ID and App Secret.'; -$_['text_connected'] = 'Connected with Merchant ID %s'; -$_['text_connecting'] = 'Connecting...'; -$_['text_connection'] = 'Connection'; -$_['text_conversion_value'] = 'Conversion Value'; -$_['text_conversions'] = 'Conversions'; -$_['text_cost'] = 'Cost'; -$_['text_critical'] = 'Critical'; -$_['text_cron_email'] = 'Send Summary to E-Mail'; -$_['text_cron_email_status'] = 'Send E-Mail Summary'; -$_['text_cron_info'] = 'Please make sure to set up a CRON task executing each hour using one of the methods below. Method #1 is recommended. CRON jobs help you with:

• Periodic syncing of your OpenCart catalog with Google Merchant Center
• Automatic fetching of product statuses and product reports'; -$_['text_cron_settings'] = 'CRON Settings'; -$_['text_data_quality_issues'] = 'Data Quality Issues'; -$_['text_debug_log'] = 'Debug Logging'; -$_['text_destination_status'] = 'Status'; -$_['text_disabled'] = 'Disabled'; -$_['text_disapproved'] = 'Disapproved'; -$_['text_disconnect_reminder'] = 'Even if you decide to disconnect this OpenCart extension, you will still have access to your Merchant Center account. It will not get deleted. Disconnecting will do the following:'; -$_['text_disconnecting_please_wait'] = 'Disconnecting...'; -$_['text_does_not_apply'] = '-- Does not apply --'; -$_['text_download_debug_log'] = 'Download Debug Log'; -$_['text_edit_target'] = 'Edit Campaign: %s'; -$_['text_enabled'] = 'Enabled'; -$_['text_error'] = 'Error'; -$_['text_existing_merchant'] = 'Use my own Google Merchant Center account (In case you want to use your active Google Merchant Center account.)'; -$_['text_extension_settings'] = 'Extension Settings'; -$_['text_extensions'] = 'Расширения'; -$_['text_filter'] = 'Filter'; -$_['text_gender_female'] = 'Female'; -$_['text_gender_male'] = 'Male'; -$_['text_gender_unisex'] = 'Unisex'; -$_['text_google_expiration_date'] = 'Google Expiration Date'; -$_['text_heading_merchant_center_account'] = 'Merchant Center Account'; -$_['text_home'] = 'Главная'; -$_['text_image'] = 'Image'; -$_['text_impressions'] = 'Impressions'; -$_['text_info_popup_product'] = 'The information requested here is required to properly list your product on Google Shopping. Click here for more information.'; -$_['text_issues'] = 'Issues'; -$_['text_item_level_issues'] = 'Item Issues'; -$_['text_label_active'] = 'ACTIVE'; -$_['text_label_approved'] = 'APPROVED'; -$_['text_label_critical'] = 'CRITICAL'; -$_['text_label_disapproved'] = 'DISAPPROVED'; -$_['text_label_error'] = 'ERROR'; -$_['text_label_paused'] = 'PAUSED'; -$_['text_label_pending'] = 'PENDING'; -$_['text_label_suggestion'] = 'SUGGESTION'; -$_['text_label_unassigned'] = 'UNASSIGNED'; -$_['text_label_unavailable'] = 'UNAVAILABLE'; -$_['text_learn_more'] = 'Learn more'; -$_['text_loading_please_wait'] = 'Please wait. This may take a few minutes...'; -$_['text_local_cron'] = 'Method #1 - CRON Task:'; -$_['text_mapping_intro'] = 'Select your OpenCart categories which best match the pre-defined Google categories. This helps Google understand what you\'re selling so that they can better connect your ads with search queries from potential customers. If none of your categories match the list below, just click "Proceed" to skip this step.'; -$_['text_mapping_verify_intro'] = 'Some of your products are already mapped to Google categories. Should the new mapping edit all current products, or should it apply only for your future products?'; -$_['text_mapping_verify_title'] = 'Confirm New Mapping'; -$_['text_maximum_five'] = 'Maximum 5 campaigns can be selected. Leaving a campaign unticked will unassign the products from this campaign.'; -$_['text_merchant_intro'] = 'Please select the account you wish to use:'; -$_['text_merchant_website_claim'] = '

Upon clicking Proceed, you will be asked to authorize OpenCart to manage your listing and account in Google Shopping. Your website URL will be claimed by the selected Merchant Center account.

'; -$_['text_na'] = '–'; -$_['text_new_merchant'] = 'Use an account managed by OpenCart (For beginners who do not have a Google Merchant Center account.)'; -$_['text_no'] = 'No'; -$_['text_no_results'] = 'No results found!'; -$_['text_no_targets'] = 'No campaigns found! Click the button below to add your first campaign.'; -$_['text_panel_connect'] = 'Step 1 of 5: Connect the Google Shopping Extension'; -$_['text_panel_heading'] = 'Редактировать Google Shopping | Магазин: %s'; -$_['text_panel_heading_campaign'] = 'Step 3 of 5: Set up Smart Shopping Ad Campaigns'; -$_['text_panel_heading_campaign_2'] = 'Set up Smart Shopping Ad Campaigns'; -$_['text_panel_heading_mapping'] = 'Step 5 of 5: Set up Category Mapping'; -$_['text_panel_heading_mapping_2'] = 'Set up Category Mapping'; -$_['text_panel_heading_merchant'] = 'Step 2 of 5: Set up Google Merchant Center Account'; -$_['text_panel_heading_more_info'] = 'About Campaigns'; -$_['text_panel_heading_preview'] = 'How an Ad Looks Like'; -$_['text_panel_heading_shipping_taxes'] = 'Step 4 of 5: Set up Shipping & Taxes'; -$_['text_panel_heading_shipping_taxes_2'] = 'Set up Shipping & Taxes'; -$_['text_paused'] = 'Paused'; -$_['text_per_day'] = '$%s / day'; -$_['text_popup_error_body'] = 'The following error has occurred while trying to fetch this resource: {error}'; -$_['text_popup_error_title'] = 'Error'; -$_['text_popup_loading_body'] = 'Loading... Please wait...'; -$_['text_popup_loading_title'] = 'Loading form...'; -$_['text_popup_title_multiple'] = 'Editing %s products'; -$_['text_popup_title_single'] = '%s (%s)'; -$_['text_product_category'] = 'Category (incl. sub-categories)'; -$_['text_product_is_modified'] = 'Google Fields Edited'; -$_['text_product_model'] = 'Model'; -$_['text_product_name'] = 'Product'; -$_['text_refresh_token'] = 'Re-create token'; -$_['text_remote_cron'] = 'Method #2 - Remote CRON:'; -$_['text_report_campaign_name'] = 'Campaign Name'; -$_['text_report_clicks'] = 'Clicks'; -$_['text_report_conversion_value'] = 'Conversion Value'; -$_['text_report_conversions'] = 'Conversions'; -$_['text_report_cost'] = 'Cost'; -$_['text_report_date_range'] = 'Campaign Reports for %s'; -$_['text_report_impressions'] = 'Impressions'; -$_['text_report_status'] = 'Status'; -$_['text_reporting_interval'] = 'Reporting Time Interval'; -$_['text_reporting_interval_LAST_14_DAYS'] = 'Last 14 days'; -$_['text_reporting_interval_LAST_30_DAYS'] = 'Last 30 days'; -$_['text_reporting_interval_LAST_7_DAYS'] = 'Last 7 days'; -$_['text_reporting_interval_LAST_BUSINESS_WEEK'] = 'Last business week'; -$_['text_reporting_interval_LAST_WEEK'] = 'Last week'; -$_['text_reporting_interval_LAST_WEEK_SUN_SAT'] = 'Last week (Sunday - Saturday)'; -$_['text_reporting_interval_THIS_MONTH'] = 'This month'; -$_['text_reporting_interval_THIS_WEEK_MON_TODAY'] = 'This week (Monday - Today)'; -$_['text_reporting_interval_THIS_WEEK_SUN_TODAY'] = 'This week (Sunday - Today)'; -$_['text_reporting_interval_TODAY'] = 'Today'; -$_['text_reporting_interval_YESTERDAY'] = 'Yesterday'; -$_['text_select_country'] = '-- Country --'; -$_['text_select_currency'] = '-- Currency --'; -$_['text_select_language'] = '-- Language --'; -$_['text_selection_all'] = 'You have selected all {total} items on all pages. Unselect Everything'; -$_['text_selection_page'] = 'You have selected {selected_page} item(s) on this page. Click here to select all {total} items on all pages.'; -$_['text_shipping_carrier'] = 'Use a distribution center and carrier services'; -$_['text_shipping_custom'] = 'Set this up myself in the Google Merchant Center'; -$_['text_shipping_flat'] = 'Use a flat rate for all orders'; -$_['text_shipping_services'] = 'Shipping Services'; -$_['text_shipping_transit_times'] = 'Shipping Transit Times'; -$_['text_size'] = 'Size'; -$_['text_size_type_big_and_tall'] = 'Big & Tall'; -$_['text_size_type_maternity'] = 'Maternity'; -$_['text_size_type_petite'] = 'Petite'; -$_['text_size_type_plus'] = 'Plus'; -$_['text_size_type_regular'] = 'Regular'; -$_['text_status'] = 'Status'; -$_['text_suggestion'] = 'Suggestion'; -$_['text_tax_custom'] = 'Set this up myself in the Google Merchant Center'; -$_['text_tax_not_usa'] = 'I am not based in the USA'; -$_['text_tax_on_shipping'] = 'Add tax on shipping'; -$_['text_tax_usa'] = 'Use Google's destination-based tax estimation'; -$_['text_taxes'] = 'Taxes (USA only)'; -$_['text_tutorial_cron'] = 'https://isenselabs.com/posts/how-to-auto-sync-opencart-products-with-google-shopping'; -$_['text_usd'] = 'USD'; -$_['text_usd_day'] = 'USD / day'; -$_['text_video_tutorial_url_advertise'] = 'https://youtu.be/ZN7zz8raoVM?t=187'; -$_['text_video_tutorial_url_install'] = 'https://www.youtube.com/watch?v=AvkBLWAUojI'; -$_['text_video_tutorial_url_setup'] = 'https://www.youtube.com/watch?v=ZN7zz8raoVM'; -$_['text_view_issues'] = 'View Issues'; -$_['text_yes'] = 'Yes'; - -// Placeholders -$_['placeholder_access_token'] = 'Paste your access token here'; - -// Tabs -$_['tab_text_ads'] = 'Product Ads / Reports'; -$_['tab_text_reports'] = 'Campaign Reports'; -$_['tab_text_settings'] = 'Settings'; - -// Buttons -$_['button_add_feed'] = 'New Feed'; -$_['button_add_target'] = 'New Campaign'; -$_['button_apply'] = 'Assign Selected Products to Campaigns'; -$_['button_bulk_edit_google_fields'] = 'Bulk Edit'; -$_['button_campaign'] = 'Smart Shopping Ad Campaigns'; -$_['button_close'] = 'Close'; -$_['button_connect'] = 'Connect'; -$_['button_disconnect'] = 'Disconnect'; -$_['button_mapping'] = 'Category Mapping'; -$_['button_proceed'] = 'Продолжить'; -$_['button_product_edit'] = 'Edit Google Fields'; -$_['button_product_set'] = 'Set Google Fields'; -$_['button_save'] = 'Save'; -$_['button_save_future'] = 'Save & Do Nothing'; -$_['button_save_modify'] = 'Save & Modify Current Products'; -$_['button_select_campaigns'] = 'Select Campaigns'; -$_['button_shipping_taxes'] = 'Shipping & Taxes'; -$_['button_video_tutorial_install'] = 'Посмотреть видео инструкцию (на английском)'; -$_['button_video_tutorial_setup'] = 'Посмотреть видео инструкцию (на английском)'; - -// Success -$_['success_advertise_disable'] = 'Success! Advertising has been disabled for the selected products!'; -$_['success_advertise_enable'] = 'Success! Advertising has been enabled for the selected products!'; -$_['success_advertise_listed'] = 'The shopping ads are live! If your products are not yet approved, please allow up to 3 business days for the Merchant Center team to review them.'; -$_['success_advertise_unlisted'] = 'The shopping ads have been stopped. The products you edited no longer belong to any campaigns.'; -$_['success_campaign'] = 'Success! You have set up Smart Shopping Ad Campaigns!'; -$_['success_connect'] = 'Success! You have connected your extension!'; -$_['success_disconnect'] = 'Success! The extension has been disconnected!'; -$_['success_index'] = 'Success! You have modified the extension!'; -$_['success_mapping'] = 'Success! You have set up mapping!'; -$_['success_merchant'] = 'Success! Your Google Merchant Center account has been set up! Your website has been claimed!'; -$_['success_merchant_access'] = 'Success! Your Google Merchant Center account has been set up! Your website has been claimed! You can access the linked Google Merchant Center account from the Google Merchant Center dashboard.'; -$_['success_product'] = 'Success! The product information has been updated.'; -$_['success_shipping_taxes'] = 'Success! The merchant shipping and taxes have been updated.'; -$_['success_target_add'] = 'Success! Your new campaign has been created! It will become active as soon as your product feeds get approved by Google Merchant Center.'; -$_['success_target_delete'] = 'Success! Your campaign has been deleted!'; -$_['success_target_edit'] = 'Success! You have edited your campaign!'; - -// Error -$_['error_adblock'] = "It looks like you are using an ad blocker. In order to use GoogleShopping, please disable your ad blocker for your OpenCart admin panel."; -$_['error_budget'] = 'Please insert the campaign budget. The value must be numeric and no less than 5.'; -$_['error_campaign_name_in_use'] = 'You are already using a campaign with the same name! Please choose another name.'; -$_['error_campaign_name_total'] = '"Total" is a forbidden name for a campaign! Please choose another name.'; -$_['error_carrier'] = 'Please select at least one carrier!'; -$_['error_carrier_postcode'] = 'Please provide the postcode for outgoing shipments.'; -$_['error_carrier_price_percentage'] = 'Please provide a valid price percentage from 0 to 100.'; -$_['error_cron_acknowledge'] = 'Please confirm you have set up a CRON job.'; -$_['error_empty_app_id'] = 'Please insert the App ID!'; -$_['error_empty_app_secret'] = 'Please insert the App Secret!'; -$_['error_empty_campaign_name'] = 'Please set a name for your campaign!'; -$_['error_empty_country'] = 'Please select a country!'; -$_['error_empty_feed'] = 'Please specify at least one campaign feed!'; -$_['error_field_no_value'] = 'Please provide a value!'; -$_['error_flat_rate'] = 'Please insert a flat rate value. The value must be numeric.'; -$_['error_form'] = 'Please check the form for errors and try to save agian.'; -$_['error_invalid_email'] = 'The provided e-mail address is not valid!'; -$_['error_invalid_feed'] = 'All feeds must have a language and currency!'; -$_['error_max_transit_time'] = 'Please insert a maximum transit time (number of days) which is larger than the minimum.'; -$_['error_min_transit_time'] = 'Please insert a minimum transit time (number of days).'; -$_['error_no_targets'] = 'Warning! No Smart Shopping Ad Campaigns have been set up.'; -$_['error_permission'] = 'Warning! You do not have permission to modify the extension Advertise > Google Shopping!'; -$_['error_popup_not_found_body'] = 'The system could not find the product.'; -$_['error_popup_not_found_title'] = 'Not found'; -$_['error_store_url_claim'] = 'Your store URL has been claimed by another app. Please connect your merchant account to re-claim the store URL.'; -$_['error_tax'] = 'Please select at least one taxable state.'; -$_['error_used_app_id'] = 'You have already connected this App with another one of your stores. Please disconnect the other store, or use a different App ID.'; -$_['error_warning'] = 'Warning! Please check the form carefully for errors.'; - -// Warning -$_['warning_budget'] = 'Campaigns with a daily budget of less than $10 may not yield good conversion results. For best results, we suggest a daily budget of at least $10.'; -$_['warning_disabled'] = 'The extension is disabled and all of your campaigns are stopped. Enable the extension to activate the Smart Shopping Ad Campaigns.'; -$_['warning_last_cron_executed'] = 'It seems like your CRON task has not been run recently. Please ensure it is set up correctly. Follow this tutorial to see how to do it.'; -$_['warning_no_active_campaigns'] = 'You have no campaigns running. Click here to activate your campaign.'; -$_['warning_no_advertised_products'] = 'No products are being advertised. To start advertising, you must assign products to campaigns. Follow this tutorial to see how to do it.'; -$_['warning_roas'] = 'Google Ads needs about a couple of weeks after a campaign gets created to work properly with ROAS. Please check back on %s to configure this setting.'; diff --git a/public/admin/language/ru-ru/extension/analytics/google.php b/public/admin/language/ru-ru/extension/analytics/google.php deleted file mode 100644 index e292fd2..0000000 --- a/public/admin/language/ru-ru/extension/analytics/google.php +++ /dev/null @@ -1,17 +0,0 @@ -Google Analytics account and after creating your website profile copy and paste the analytics code into this field.'; -$_['text_default'] = 'Default'; - -// Entry -$_['entry_code'] = 'Google Analytics Code'; -$_['entry_status'] = 'Status'; - -// Error -$_['error_permission'] = 'Warning: You do not have permission to modify Google Analytics!'; -$_['error_code'] = 'Code required!'; diff --git a/public/admin/language/ru-ru/extension/captcha/google.php b/public/admin/language/ru-ru/extension/captcha/google.php deleted file mode 100644 index bd46273..0000000 --- a/public/admin/language/ru-ru/extension/captcha/google.php +++ /dev/null @@ -1,21 +0,0 @@ -Google reCAPTCHA и зарегистрируйте свой магазин.'; - -// Entry -$_['entry_key'] = 'Ключ сайта'; -$_['entry_secret'] = 'Секретный ключ'; -$_['entry_status'] = 'Статус'; - -// Error -$_['error_permission'] = 'У вас недостаточно прав для внесения изменений!'; -$_['error_key'] = 'Необходим ключ сайта!'; -$_['error_secret'] = 'Необходим секретный ключ!'; \ No newline at end of file diff --git a/public/admin/model/extension/advertise/google.php b/public/admin/model/extension/advertise/google.php deleted file mode 100644 index 04f6f3c..0000000 --- a/public/admin/model/extension/advertise/google.php +++ /dev/null @@ -1,697 +0,0 @@ - array( - 'extension/advertise/google/admin_link', - ), - 'admin/model/catalog/product/addProduct/after' => array( - 'extension/advertise/google/addProduct', - ), - 'admin/model/catalog/product/copyProduct/after' => array( - 'extension/advertise/google/copyProduct', - ), - 'admin/model/catalog/product/deleteProduct/after' => array( - 'extension/advertise/google/deleteProduct', - ), - 'catalog/controller/checkout/success/before' => array( - 'extension/advertise/google/before_checkout_success' - ), - 'store/view/common/header/after' => array( - 'extension/advertise/google/google_global_site_tag' - ), - 'store/view/common/success/after' => array( - 'extension/advertise/google/google_dynamic_remarketing_purchase' - ), - 'store/view/product/product/after' => array( - 'extension/advertise/google/google_dynamic_remarketing_product' - ), - 'store/view/product/search/after' => array( - 'extension/advertise/google/google_dynamic_remarketing_searchresults' - ), - 'store/view/product/category/after' => array( - 'extension/advertise/google/google_dynamic_remarketing_category' - ), - 'store/view/common/home/after' => array( - 'extension/advertise/google/google_dynamic_remarketing_home' - ), - 'store/view/checkout/cart/after' => array( - 'extension/advertise/google/google_dynamic_remarketing_cart' - ) - ); - - private $rename_tables = array( - 'advertise_google_target' => 'googleshopping_target', - 'category_to_google_product_category' => 'googleshopping_category', - 'product_advertise_google_status' => 'googleshopping_product_status', - 'product_advertise_google_target' => 'googleshopping_product_target', - 'product_advertise_google' => 'googleshopping_product' - ); - - private $table_columns = array( - 'googleshopping_target' => array( - 'advertise_google_target_id', - 'store_id', - 'campaign_name', - 'country', - 'budget', - 'feeds', - 'status' - ), - 'googleshopping_category' => array( - 'google_product_category', - 'store_id', - 'category_id' - ), - 'googleshopping_product_status' => array( - 'product_id', - 'store_id', - 'product_variation_id', - 'destination_statuses', - 'data_quality_issues', - 'item_level_issues', - 'google_expiration_date' - ), - 'googleshopping_product_target' => array( - 'product_id', - 'store_id', - 'advertise_google_target_id' - ), - 'googleshopping_product' => array( - 'product_advertise_google_id', - 'product_id', - 'store_id', - 'has_issues', - 'destination_status', - 'impressions', - 'clicks', - 'conversions', - 'cost', - 'conversion_value', - 'google_product_category', - 'condition', - 'adult', - 'multipack', - 'is_bundle', - 'age_group', - 'color', - 'gender', - 'size_type', - 'size_system', - 'size', - 'is_modified' - ) - ); - - public function isAppIdUsed($app_id, $store_id) { - $sql = "SELECT `store_id` FROM `" . DB_PREFIX . "setting` WHERE `key`='advertise_google_app_id' AND `value`='" . $this->db->escape($store_id) . "' AND `store_id`!=" . (int)$store_id . " LIMIT 1"; - - $result = $this->db->query($sql); - - if ($result->num_rows > 0) { - try { - $googleshopping = new Googleshopping($this->registry, (int)$result->row['store_id']); - - return $googleshopping->isConnected(); - } catch (\RuntimeException $e) { - return false; - } - } - - return false; - } - - public function getFinalProductId() { - $sql = "SELECT product_id FROM `" . DB_PREFIX . "product` ORDER BY product_id DESC LIMIT 1"; - - $result = $this->db->query($sql); - - if ($result->num_rows > 0) { - return (int)$result->row['product_id']; - } - - return null; - } - - public function isAnyProductCategoryModified($store_id) { - $sql = "SELECT pag.is_modified FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE pag.google_product_category IS NOT NULL AND pag.store_id=" . (int)$store_id . " LIMIT 0,1"; - - return $this->db->query($sql)->num_rows > 0; - } - - public function getAdvertisedCount($store_id) { - $result = $this->db->query("SELECT COUNT(product_id) as total FROM `" . DB_PREFIX . "googleshopping_product_target` WHERE store_id=" . (int)$store_id . " GROUP BY `product_id`"); - - return $result->num_rows > 0 ? (int)$result->row['total'] : 0; - } - - public function getMapping($store_id) { - $sql = "SELECT * FROM `" . DB_PREFIX . "googleshopping_category` WHERE store_id=" . (int)$store_id; - - return $this->db->query($sql)->rows; - } - - public function setCategoryMapping($google_product_category, $store_id, $category_id) { - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_category` SET `google_product_category`='" . $this->db->escape($google_product_category) . "', `store_id`=" . (int)$store_id . ", `category_id`=" . (int)$category_id . " ON DUPLICATE KEY UPDATE `category_id`=" . (int)$category_id; - - $this->db->query($sql); - } - - public function getMappedCategory($google_product_category, $store_id) { - $sql = "SELECT GROUP_CONCAT(cd.name ORDER BY cp.level SEPARATOR '  >  ') AS name, cp.category_id FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "category_description cd ON (cp.path_id = cd.category_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_category` c2gpc ON (c2gpc.category_id = cp.category_id) WHERE cd.language_id=" . (int)$this->config->get('config_language_id') . " AND c2gpc.google_product_category='" . $this->db->escape($google_product_category) . "' AND c2gpc.store_id=" . (int)$store_id; - - $result = $this->db->query($sql); - - if ($result->num_rows > 0) { - return $result->row; - } - - return null; - } - - public function getProductByProductAdvertiseGoogleId($product_advertise_google_id) { - $sql = "SELECT pag.product_id FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE pag.product_advertise_google_id=" . (int)$product_advertise_google_id; - - $result = $this->db->query($sql); - - if ($result->num_rows) { - $this->load->model('catalog/product'); - - return $this->model_catalog_product->getProduct($result->row['product_id']); - } - } - - public function getProductAdvertiseGoogle($product_advertise_google_id) { - $sql = "SELECT pag.* FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE pag.product_advertise_google_id=" . (int)$product_advertise_google_id; - - return $this->db->query($sql)->row; - } - - public function hasActiveTarget($store_id) { - $sql = "SELECT agt.advertise_google_target_id FROM `" . DB_PREFIX . "googleshopping_target` agt WHERE agt.store_id=" . (int)$store_id . " AND agt.status='active' LIMIT 1"; - - return $this->db->query($sql)->num_rows > 0; - } - - public function getRequiredFieldsByProductIds($product_ids, $store_id) { - $this->load->config('googleshopping/googleshopping'); - - $result = array(); - $countries = $this->getTargetCountriesByProductIds($product_ids, $store_id); - - foreach ($countries as $country) { - foreach ($this->config->get('advertise_google_country_required_fields') as $field => $requirements) { - if ( - (!empty($requirements['countries']) && in_array($country, $requirements['countries'])) - || - (is_array($requirements['countries']) && empty($requirements['countries'])) - ) { - $result[$field] = $requirements; - } - } - } - - return $result; - } - - public function getRequiredFieldsByFilter($data, $store_id) { - $this->load->config('googleshopping/googleshopping'); - - $result = array(); - $countries = $this->getTargetCountriesByFilter($data, $store_id); - - foreach ($countries as $country) { - foreach ($this->config->get('advertise_google_country_required_fields') as $field => $requirements) { - if ( - (!empty($requirements['countries']) && in_array($country, $requirements['countries'])) - || - (is_array($requirements['countries']) && empty($requirements['countries'])) - ) { - $result[$field] = $requirements; - } - } - } - - return $result; - } - - public function getTargetCountriesByProductIds($product_ids, $store_id) { - $sql = "SELECT DISTINCT agt.country FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "googleshopping_target` agt ON (agt.advertise_google_target_id = pagt.advertise_google_target_id AND agt.store_id = pagt.store_id) WHERE pagt.product_id IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ") AND pagt.store_id=" . (int)$store_id; - - return array_map(array($this, 'country'), $this->db->query($sql)->rows); - } - - public function getTargetCountriesByFilter($data, $store_id) { - $sql = "SELECT DISTINCT agt.country FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "googleshopping_target` agt ON (agt.advertise_google_target_id = pagt.advertise_google_target_id AND agt.store_id = pagt.store_id) LEFT JOIN `" . DB_PREFIX . "product` p ON (pagt.product_id = p.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = pagt.product_id) WHERE pagt.store_id=" . (int)$store_id . " AND pd.language_id=" . (int)$this->config->get('config_language_id'); - - $this->googleshopping->applyFilter($sql, $data); - - return array_map(array($this, 'country'), $this->db->query($sql)->rows); - } - - public function getProductOptionsByProductIds($product_ids) { - $sql = "SELECT po.option_id, od.name FROM `" . DB_PREFIX . "product_option` po LEFT JOIN `" . DB_PREFIX . "option_description` od ON (od.option_id=po.option_id AND od.language_id=" . (int)$this->config->get('config_language_id') . ") LEFT JOIN `" . DB_PREFIX . "option` o ON (o.option_id = po.option_id) WHERE o.type IN ('select', 'radio') AND po.product_id IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")"; - - return $this->db->query($sql)->rows; - } - - public function getProductOptionsByFilter($data) { - $sql = "SELECT DISTINCT po.option_id, od.name FROM `" . DB_PREFIX . "product_option` po LEFT JOIN `" . DB_PREFIX . "option_description` od ON (od.option_id=po.option_id AND od.language_id=" . (int)$this->config->get('config_language_id') . ") LEFT JOIN `" . DB_PREFIX . "option` o ON (o.option_id = po.option_id) LEFT JOIN `" . DB_PREFIX . "product` p ON (po.product_id = p.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = po.product_id) WHERE o.type IN ('select', 'radio') AND pd.language_id=" . (int)$this->config->get('config_language_id'); - - $this->googleshopping->applyFilter($sql, $data); - - return $this->db->query($sql)->rows; - } - - public function addTarget($target, $store_id) { - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_target` SET `store_id`=" . (int)$store_id . ", `campaign_name`='" . $this->db->escape($target['campaign_name']) . "', `country`='" . $this->db->escape($target['country']) . "', `budget`='" . (float)$target['budget'] . "', `feeds`='" . $this->db->escape(json_encode($target['feeds'])) . "', `date_added`=NOW(), `roas`=" . (int)$target['roas'] . " , `status`='" . $this->db->escape($target['status']) . "'"; - - $this->db->query($sql); - - return $this->db->getLastId(); - } - - public function deleteProducts($product_ids) { - $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_product` WHERE `product_id` IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")"; - - $this->db->query($sql); - - $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_product_target` WHERE `product_id` IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")"; - - $this->db->query($sql); - - $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_product_status` WHERE `product_id` IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")"; - - $this->db->query($sql); - - return true; - } - - public function setAdvertisingBySelect($post_product_ids, $post_target_ids, $store_id) { - if (!empty($post_product_ids)) { - $product_ids = array_map(array($this->googleshopping, 'integer'), $post_product_ids); - - $product_ids_expression = implode(',', $product_ids); - - $this->db->query("DELETE FROM `" . DB_PREFIX . "googleshopping_product_target` WHERE product_id IN (" . $product_ids_expression . ") AND store_id=" . (int)$store_id); - - if (!empty($post_target_ids)) { - $target_ids = array_map(array($this->googleshopping, 'integer'), $post_target_ids); - - $values = array(); - - foreach ($product_ids as $product_id) { - foreach ($target_ids as $target_id) { - $values[] = '(' . $product_id . ',' . $store_id . ',' . $target_id . ')'; - } - } - - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product_target` (`product_id`, `store_id`, `advertise_google_target_id`) VALUES " . implode(',', $values); - - $this->db->query($sql); - } - } - } - - public function setAdvertisingByFilter($data, $post_target_ids, $store_id) { - $sql = "DELETE pagt FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "product` p ON (pagt.product_id = p.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = p.product_id) WHERE pd.language_id=" . (int)$this->config->get('config_language_id'); - - $this->googleshopping->applyFilter($sql, $data); - - $this->db->query($sql); - - if (!empty($post_target_ids)) { - $target_ids = array_map(array($this->googleshopping, 'integer'), $post_target_ids); - - $insert_sql = "SELECT p.product_id, " . (int)$store_id . " as store_id, '{TARGET_ID}' as advertise_google_target_id FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = p.product_id) WHERE pd.language_id=" . (int)$this->config->get('config_language_id'); - - $this->googleshopping->applyFilter($insert_sql, $data); - - foreach ($target_ids as $target_id) { - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product_target` (`product_id`, `store_id`, `advertise_google_target_id`) " . str_replace('{TARGET_ID}', (string)$target_id, $insert_sql); - - $this->db->query($sql); - } - } - } - - public function insertNewProducts($product_ids = array(), $store_id) { - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `google_product_category`) SELECT p.product_id, p2s.store_id, (SELECT c2gpc.google_product_category FROM `" . DB_PREFIX . "product_to_category` p2c LEFT JOIN `" . DB_PREFIX . "category_path` cp ON (p2c.category_id = cp.category_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_category` c2gpc ON (c2gpc.category_id = cp.path_id AND c2gpc.store_id = " . (int)$store_id . ") WHERE p2c.product_id = p.product_id AND c2gpc.google_product_category IS NOT NULL ORDER BY cp.level DESC LIMIT 0,1) as `google_product_category` FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_to_store` p2s ON (p2s.product_id = p.product_id AND p2s.store_id = " . (int)$store_id . ") LEFT JOIN `" . DB_PREFIX . "googleshopping_product` pag ON (pag.product_id = p.product_id AND pag.store_id=p2s.store_id) WHERE pag.product_id IS NULL AND p2s.store_id IS NOT NULL"; - - if (!empty($product_ids)) { - $sql .= " AND p.product_id IN (" . $this->googleshopping->productIdsToIntegerExpression($product_ids) . ")"; - } - - $this->db->query($sql); - } - - public function updateGoogleProductCategoryMapping($store_id) { - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `google_product_category`) SELECT p.product_id, " . (int)$store_id . " as store_id, (SELECT c2gpc.google_product_category FROM `" . DB_PREFIX . "product_to_category` p2c LEFT JOIN `" . DB_PREFIX . "category_path` cp ON (p2c.category_id = cp.category_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_category` c2gpc ON (c2gpc.category_id = cp.path_id AND c2gpc.store_id = " . (int)$store_id . ") WHERE p2c.product_id = p.product_id AND c2gpc.google_product_category IS NOT NULL ORDER BY cp.level DESC LIMIT 0,1) as `google_product_category` FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "googleshopping_product` pag ON (pag.product_id = p.product_id) WHERE pag.product_id IS NOT NULL ON DUPLICATE KEY UPDATE `google_product_category`=VALUES(`google_product_category`)"; - - $this->db->query($sql); - } - - public function updateSingleProductFields($data) { - $values = array(); - - $entry = array(); - $entry['product_id'] = (int)$data['product_id']; - $entry = array_merge($entry, $this->makeInsertData($data)); - - $values[] = "(" . implode(",", $entry) . ")"; - - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `google_product_category`, `condition`, `adult`, `multipack`, `is_bundle`, `age_group`, `color`, `gender`, `size_type`, `size_system`, `size`, `is_modified`) VALUES " . implode(',', $values) . " ON DUPLICATE KEY UPDATE " . $this->makeOnDuplicateKeyData(); - - $this->db->query($sql); - } - - public function updateMultipleProductFields($filter_data, $data) { - $insert_sql = "SELECT p.product_id, {INSERT_DATA} FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = p.product_id) WHERE pd.language_id=" . (int)$this->config->get('config_language_id'); - - $this->googleshopping->applyFilter($insert_sql, $filter_data); - - $insert_data = array(); - $keys[] = "`product_id`"; - - foreach ($this->makeInsertData($data) as $key => $value) { - $insert_data[] = $value . " as `" . $key . "`"; - $keys[] = "`" . $key . "`"; - } - - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (" . implode(", ", $keys) . ") " . str_replace('{INSERT_DATA}', implode(", ", $insert_data), $insert_sql) . " ON DUPLICATE KEY UPDATE " . $this->makeOnDuplicateKeyData(); - - $this->db->query($sql); - } - - protected function makeInsertData($data) { - $insert_data = array(); - - $insert_data['store_id'] = (int)$data['store_id']; - $insert_data['google_product_category'] = "'" . $this->db->escape($data['google_product_category']) . "'"; - $insert_data['condition'] = "'" . $this->db->escape($data['condition']) . "'"; - $insert_data['adult'] = (int)$data['adult']; - $insert_data['multipack'] = (int)$data['multipack']; - $insert_data['is_bundle'] = (int)$data['is_bundle']; - $insert_data['age_group'] = "'" . $this->db->escape($data['age_group']) . "'"; - $insert_data['color'] = (int)$data['color']; - $insert_data['gender'] = "'" . $this->db->escape($data['gender']) . "'"; - $insert_data['size_type'] = "'" . $this->db->escape($data['size_type']) . "'"; - $insert_data['size_system'] = "'" . $this->db->escape($data['size_system']) . "'"; - $insert_data['size'] = (int)$data['size']; - $insert_data['is_modified'] = 1; - - return $insert_data; - } - - protected function makeOnDuplicateKeyData() { - return "`google_product_category`=VALUES(`google_product_category`), `condition`=VALUES(`condition`), `adult`=VALUES(`adult`), `multipack`=VALUES(`multipack`), `is_bundle`=VALUES(`is_bundle`), `age_group`=VALUES(`age_group`), `color`=VALUES(`color`), `gender`=VALUES(`gender`), `size_type`=VALUES(`size_type`), `size_system`=VALUES(`size_system`), `size`=VALUES(`size`), `is_modified`=VALUES(`is_modified`)"; - } - - public function getCategories($data = array(), $store_id) { - $sql = "SELECT cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR '  >  ') AS name, c1.parent_id, c1.sort_order FROM " . DB_PREFIX . "category_path cp LEFT JOIN `" . DB_PREFIX . "category_to_store` c2s ON (c2s.category_id = cp.category_id AND c2s.store_id=" . (int)$store_id . ") LEFT JOIN " . DB_PREFIX . "category c1 ON (cp.category_id = c1.category_id) LEFT JOIN " . DB_PREFIX . "category c2 ON (cp.path_id = c2.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd1 ON (cp.path_id = cd1.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd2 ON (cp.category_id = cd2.category_id) WHERE c2s.store_id IS NOT NULL AND cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'"; - - if (!empty($data['filter_name'])) { - $sql .= " AND cd2.name LIKE '%" . $this->db->escape($data['filter_name']) . "%'"; - } - - $sql .= " GROUP BY cp.category_id"; - - $sort_data = array( - 'name', - 'sort_order' - ); - - if (isset($data['sort']) && in_array($data['sort'], $sort_data)) { - $sql .= " ORDER BY " . $data['sort']; - } else { - $sql .= " ORDER BY sort_order"; - } - - if (isset($data['order']) && ($data['order'] == 'DESC')) { - $sql .= " DESC"; - } else { - $sql .= " ASC"; - } - - if (isset($data['start']) || isset($data['limit'])) { - if ($data['start'] < 0) { - $data['start'] = 0; - } - - if ($data['limit'] < 1) { - $data['limit'] = 20; - } - - $sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit']; - } - - $query = $this->db->query($sql); - - return $query->rows; - } - - public function getProductCampaigns($product_id, $store_id) { - $sql = "SELECT agt.advertise_google_target_id, agt.campaign_name FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "googleshopping_target` agt ON (pagt.advertise_google_target_id = agt.advertise_google_target_id) WHERE pagt.product_id=" . (int)$product_id . " AND pagt.store_id=" . (int)$store_id; - - return $this->db->query($sql)->rows; - } - - public function getProductIssues($product_id, $store_id) { - $this->load->model('localisation/language'); - - $sql = "SELECT pag.color, pag.size, pd.name, p.model FROM `" . DB_PREFIX . "googleshopping_product` pag LEFT JOIN `" . DB_PREFIX . "product` p ON (p.product_id = pag.product_id) LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = pag.product_id AND pd.language_id=" . (int)$this->config->get('config_language_id') . ") WHERE pag.product_id=" . (int)$product_id . " AND pag.store_id=" . (int)$store_id; - - $product_info = $this->db->query($sql)->row; - - if (!empty($product_info)) { - $result = array(); - $result['name'] = $product_info['name']; - $result['model'] = $product_info['model']; - $result['entries'] = array(); - - foreach ($this->model_localisation_language->getLanguages() as $language) { - $language_id = $language['language_id']; - $groups = $this->googleshopping->getGroups($product_id, $language_id, $product_info['color'], $product_info['size']); - - $result['entries'][$language_id] = array( - 'language_name' => $language['name'], - 'issues' => array() - ); - - foreach ($groups as $id => $group) { - $issues = $this->db->query("SELECT * FROM `" . DB_PREFIX . "googleshopping_product_status` WHERE product_id=" . (int)$product_id . " AND store_id=" . (int)$store_id . " AND product_variation_id='" . $this->db->escape($id) . "'")->row; - - $destination_statuses = !empty($issues['destination_statuses']) ? json_decode($issues['destination_statuses'], true) : array(); - $data_quality_issues = !empty($issues['data_quality_issues']) ? json_decode($issues['data_quality_issues'], true) : array(); - $item_level_issues = !empty($issues['item_level_issues']) ? json_decode($issues['item_level_issues'], true) : array(); - $google_expiration_date = !empty($issues['google_expiration_date']) ? date($this->language->get('datetime_format'), $issues['google_expiration_date']) : $this->language->get('text_na'); - - $result['entries'][$language_id]['issues'][] = array( - 'color' => $group['color'] != "" ? $group['color'] : $this->language->get('text_na'), - 'size' => $group['size'] != "" ? $group['size'] : $this->language->get('text_na'), - 'destination_statuses' => $destination_statuses, - 'data_quality_issues' => $data_quality_issues, - 'item_level_issues' => $item_level_issues, - 'google_expiration_date' => $google_expiration_date - ); - } - } - - return $result; - } - - return null; - } - - /* - * Shortly after releasing the extension, - * we learned that the table names are actually - * clashing with third-party extensions. - * Hence, this renaming script was created. - */ - public function renameTables() { - foreach ($this->rename_tables as $old_table => $new_table) { - $new_table_name = DB_PREFIX . $new_table; - $old_table_name = DB_PREFIX . $old_table; - - if ($this->tableExists($old_table_name) && !$this->tableExists($new_table_name) && $this->tableColumnsMatch($old_table_name, $this->table_columns[$new_table])) { - $this->db->query("RENAME TABLE `" . $old_table_name . "` TO `" . $new_table_name . "`"); - } - } - } - - private function tableExists($table) { - return $this->db->query("SHOW TABLES LIKE '" . $table . "'")->num_rows > 0; - } - - private function tableColumnsMatch($table, $columns) { - $num_columns = $this->db->query("SHOW COLUMNS FROM `" . $table . "` WHERE Field IN (" . implode(',', $this->wrap($columns, '"')) . ")")->num_rows; - - return $num_columns == count($columns); - } - - private function wrap($text, $char) { - if (is_array($text)) { - foreach ($text as &$string) { - $string = $char . $string . $char; - } - - return $text; - } else { - return $char . $text . $char; - } - } - - public function createTables() { - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_product` ( - `product_advertise_google_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `product_id` INT(11), - `store_id` INT(11) NOT NULL DEFAULT '0', - `has_issues` TINYINT(1), - `destination_status` ENUM('pending','approved','disapproved') NOT NULL DEFAULT 'pending', - `impressions` INT(11) NOT NULL DEFAULT '0', - `clicks` INT(11) NOT NULL DEFAULT '0', - `conversions` INT(11) NOT NULL DEFAULT '0.0000', - `cost` decimal(15,4) NOT NULL DEFAULT '0.0000', - `conversion_value` decimal(15,4) NOT NULL DEFAULT '0.0000', - `google_product_category` VARCHAR(10), - `condition` ENUM('new','refurbished','used'), - `adult` TINYINT(1), - `multipack` INT(11), - `is_bundle` TINYINT(1), - `age_group` ENUM('newborn','infant','toddler','kids','adult'), - `color` INT(11), - `gender` ENUM('male','female','unisex'), - `size_type` ENUM('regular','petite','plus','big and tall','maternity'), - `size_system` ENUM('AU','BR','CN','DE','EU','FR','IT','JP','MEX','UK','US'), - `size` INT(11), - `is_modified` TINYINT(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`product_advertise_google_id`), - UNIQUE `product_id_store_id` (`product_id`, `store_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8"); - - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_product_status` ( - `product_id` INT(11), - `store_id` INT(11) NOT NULL DEFAULT '0', - `product_variation_id` varchar(64), - `destination_statuses` TEXT NOT NULL, - `data_quality_issues` TEXT NOT NULL, - `item_level_issues` TEXT NOT NULL, - `google_expiration_date` INT(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`product_id`, `store_id`, `product_variation_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8"); - - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_product_target` ( - `product_id` INT(11) NOT NULL, - `store_id` INT(11) NOT NULL DEFAULT '0', - `advertise_google_target_id` INT(11) UNSIGNED NOT NULL, - PRIMARY KEY (`product_id`, `advertise_google_target_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8"); - - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_category` ( - `google_product_category` VARCHAR(10) NOT NULL, - `store_id` INT(11) NOT NULL DEFAULT '0', - `category_id` INT(11) NOT NULL, - INDEX `category_id_store_id` (`category_id`, `store_id`), - PRIMARY KEY (`google_product_category`, `store_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8"); - - $this->db->query("CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "googleshopping_target` ( - `advertise_google_target_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `store_id` INT(11) NOT NULL DEFAULT '0', - `campaign_name` varchar(255) NOT NULL DEFAULT '', - `country` varchar(2) NOT NULL DEFAULT '', - `budget` decimal(15,4) NOT NULL DEFAULT '0.0000', - `feeds` text NOT NULL, - `date_added` DATE, - `roas` INT(11) NOT NULL DEFAULT '0', - `status` ENUM('paused','active') NOT NULL DEFAULT 'paused', - INDEX `store_id` (`store_id`), - PRIMARY KEY (`advertise_google_target_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8"); - } - - public function fixColumns() { - $has_auto_increment = $this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "googleshopping_product` WHERE Field='product_advertise_google_id' AND Extra LIKE '%auto_increment%'")->num_rows > 0; - - if (!$has_auto_increment) { - $this->db->query("ALTER TABLE " . DB_PREFIX . "googleshopping_product MODIFY COLUMN product_advertise_google_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT"); - } - - $has_unique_key = $this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "googleshopping_product` WHERE Key_name='product_id_store_id' AND Non_unique=0")->num_rows == 2; - - if (!$has_unique_key) { - $index_exists = $this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "googleshopping_product` WHERE Key_name='product_id_store_id'")->num_rows > 0; - - if ($index_exists) { - $this->db->query("ALTER TABLE `" . DB_PREFIX . "googleshopping_product` DROP INDEX product_id_store_id;"); - } - - $this->db->query("CREATE UNIQUE INDEX product_id_store_id ON `" . DB_PREFIX . "googleshopping_product` (product_id, store_id)"); - } - - $has_date_added_column = $this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "googleshopping_target` WHERE Field='date_added'")->num_rows > 0; - - if (!$has_date_added_column) { - $this->db->query("ALTER TABLE " . DB_PREFIX . "googleshopping_target ADD COLUMN date_added DATE"); - - $this->db->query("UPDATE " . DB_PREFIX . "googleshopping_target SET date_added = NOW() WHERE date_added IS NULL"); - } - - $has_roas_column = $this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "googleshopping_target` WHERE Field='roas'")->num_rows > 0; - - if (!$has_roas_column) { - $this->db->query("ALTER TABLE " . DB_PREFIX . "googleshopping_target ADD COLUMN roas INT(11) NOT NULL DEFAULT '0'"); - } - } - - public function dropTables() { - $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_target`"); - $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_category`"); - $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_product_status`"); - $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_product_target`"); - $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "googleshopping_product`"); - } - - public function deleteEvents() { - $this->load->model('setting/event'); - - $this->model_setting_event->deleteEventByCode('advertise_google'); - } - - public function createEvents() { - $this->load->model('setting/event'); - - foreach ($this->events as $trigger => $actions) { - foreach ($actions as $action) { - $this->model_setting_event->addEvent('advertise_google', $trigger, $action, 1, 0); - } - } - } - - public function getAllowedTargets() { - $this->load->config('googleshopping/googleshopping'); - - $result = array(); - - foreach ($this->config->get('advertise_google_targets') as $target) { - $result[] = array( - 'country' => array( - 'code' => $target['country'], - 'name' => $this->googleshopping->getCountryName($target['country']) - ), - 'languages' => $this->googleshopping->getLanguages($target['languages']), - 'currencies' => $this->googleshopping->getCurrencies($target['currencies']) - ); - } - - return $result; - } - - protected function country($row) { - return $row['country']; - } -} diff --git a/public/admin/view/image/advertise/google/ad-preview.png b/public/admin/view/image/advertise/google/ad-preview.png deleted file mode 100644 index f652d85..0000000 Binary files a/public/admin/view/image/advertise/google/ad-preview.png and /dev/null differ diff --git a/public/admin/view/stylesheet/googleshopping/stepper.css b/public/admin/view/stylesheet/googleshopping/stepper.css deleted file mode 100644 index 600cec8..0000000 --- a/public/admin/view/stylesheet/googleshopping/stepper.css +++ /dev/null @@ -1,178 +0,0 @@ -@charset "UTF-8"; -:root { - --s-width: 900px; - --s-gutter: 2.5rem; - --c-background: rgb(0, 0, 0); - --c-accent: hsl(213, 74%, 58%); -} - -.stepper { - --s-stepper-bullet: 2rem; - --s-stepper-bullet-half: calc( var(--s-stepper-bullet) / 2 ); - --step-transition: background .5s, color .5s; - --step-content: '✔︎'; - --step-color: hsl(0, 0%, 70%); - --step-bar-bg: var(--c-accent); - --step-bullet-bg: var(--step-bar-bg); - --step-bullet-color: white; - counter-reset: current-step; - display: grid; - grid-template-columns: repeat(auto-fit, minmax(1px, 1fr)); - position: relative; - z-index: 1; - margin: 20px 0; -} -.stepper__input { - counter-increment: steps; - display: none; -} -.stepper__step { - counter-increment: current-step; -} -.stepper__input:checked ~ .stepper__step { - --step-color: hsl(0, 0%, 30%); - --step-bar-bg: hsl(0, 0%, 40%); - --step-bullet-bg: var(--step-bar-bg); - --step-bullet-color: white; /*hsl(0, 0%, 20%);*/ - --step-content: counter(current-step); -} -.stepper__input:checked ~ .stepper__step .stepper__content { - opacity: 0; - pointer-events: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.stepper__input:checked + .stepper__step { - --step-bullet-bg: hsl(213, 70%, 50%); - --step-bullet-color: white; - --step-color: hsl(0, 0%, 30%); -} -.stepper__input:checked + .stepper__step .stepper__button::before { - box-shadow: 0 0 0 2px var(--c-accent); -} -.stepper__input:checked + .stepper__step .stepper__content { - opacity: 1; - pointer-events: auto; - -webkit-user-select: auto; - -moz-user-select: auto; - -ms-user-select: auto; - user-select: auto; -} -.stepper__content { - color: white; - text-align: center; - font-style: italic; - font-weight: 300; - color: var(--step-color); - transition: opacity .5s .05s; - padding: .5rem; -} -.stepper__content::-moz-selection { - color: black; - background: var(--step-bullet-color); -} -.stepper__content::selection { - color: black; - background: var(--step-bullet-color); -} -.stepper__button { - position: relative; - text-align: center; - color: var(--step-color); - display: block; -} -.stepper__button::before { - content: var(--step-content); - display: flex; - justify-content: center; - align-items: center; - margin: 0 auto var(--s-stepper-bullet-half); - height: var(--s-stepper-bullet); - width: var(--s-stepper-bullet); - border-radius: var(--s-stepper-bullet); - transition: var(--step-transition); - background: var(--step-bullet-bg); - color: var(--step-bullet-color); -} -.stepper__button::after { - content: ''; - position: absolute; - width: 100%; - height: calc( var(--s-stepper-bullet-half) / 2 ); - background: var(--step-bar-bg); - transition: var(--step-transition); - top: var(--s-stepper-bullet-half); - left: 50%; - -webkit-transform: translate(0, -50%); - transform: translate(0, -50%); - z-index: -1; -} -.stepper__step:last-child .stepper__button::after { - display: none; -} -.stepper--flexbox { - display: flex; -} -.stepper--flexbox .stepper__step { - flex-grow: 1; - flex-shrink: 0; - flex-basis: 0; -} - -body { - font-family: sans-serif; - margin: 0; - padding: 0; - grid-area: content; -} - -article { - padding: var(--s-gutter) calc(50% - var(--s-width) / 2); - background: #121212; - color: #cccccc; -} -article h1 { - font-weight: 100; - font-size: 2rem; - padding: 0 var(--s-gutter); - margin: 0; -} -article ul, -article li { - margin: 0; - padding: 0; - list-style: none; -} -article li { - padding-left: 1rem; - text-indent: -.7rem; - padding-top: .5rem; -} -article li::before { - content: "• "; - color: var(--c-accent); -} -article ul, -article p { - padding: calc( var(--s-gutter) / 2 ) var(--s-gutter) 0; -} - -.container, .container__item { - margin: 0; - padding: 0; - list-style: none; -} -.container__item { - padding: var(--s-gutter) calc(50% - var(--s-width) / 2); - border-bottom: 2px solid rgba(255, 255, 255, 0.15); -} -.container__item h2 { - padding: calc(var(--s-gutter) / 2) var(--s-gutter) var(--s-gutter); - margin: 0; - text-transform: uppercase; - font-weight: 100; - color: #8a97a8; - font-size: 1.4rem; -} diff --git a/public/admin/view/template/extension/advertise/google.twig b/public/admin/view/template/extension/advertise/google.twig deleted file mode 100644 index f9c1628..0000000 --- a/public/admin/view/template/extension/advertise/google.twig +++ /dev/null @@ -1,88 +0,0 @@ -{{ header }} -{{ column_left }} -
- -
- {% if success %} - - {% endif %} - - {% if error %} - - {% endif %} -
- {% if warning %} - - {% endif %} -
-
-
-
-

 {{ text_panel_heading }}

-
-
-
-
- -
-
{{ tab_settings }}
-
{{ tab_ads }}
-
{{ tab_reports }}
-
-
-
-
-
-
-
- -
-
-
-
- -{{ footer }} \ No newline at end of file diff --git a/public/admin/view/template/extension/analytics/google.twig b/public/admin/view/template/extension/analytics/google.twig deleted file mode 100644 index 93633bc..0000000 --- a/public/admin/view/template/extension/analytics/google.twig +++ /dev/null @@ -1,59 +0,0 @@ -{{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }} - -
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
-
{{ text_signup }} - -
-
- -
- - {% if error_code %} -
{{ error_code }}
- {% endif %} -
-
-
- -
- -
-
-
-
-
-
-
-{{ footer }} \ No newline at end of file diff --git a/public/admin/view/template/extension/captcha/google.twig b/public/admin/view/template/extension/captcha/google.twig deleted file mode 100644 index 5dbeb70..0000000 --- a/public/admin/view/template/extension/captcha/google.twig +++ /dev/null @@ -1,66 +0,0 @@ -{{ header }}{{ column_left }} -
- -
- {% if error_warning %} -
{{ error_warning }} - -
- {% endif %} -
-
-

{{ text_edit }}

-
-
-
-
{{ text_signup }}
-
- -
- - {% if error_key %} -
{{ error_key }}
- {% endif %} -
-
-
- -
- - {% if error_secret %} -
{{ error_secret }}
- {% endif %} -
-
-
- -
- -
-
-
-
-
-
-
-{{ footer }} \ No newline at end of file diff --git a/public/store/controller/extension/advertise/google.php b/public/store/controller/extension/advertise/google.php deleted file mode 100644 index aa42410..0000000 --- a/public/store/controller/extension/advertise/google.php +++ /dev/null @@ -1,380 +0,0 @@ -store_id = (int)getenv("ADVERTISE_GOOGLE_STORE_ID"); - } else { - $this->store_id = (int)$this->config->get('config_store_id'); - } - - $this->loadStore($this->store_id); - } - - public function google_global_site_tag(&$route, &$data, &$output) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If there is no tracker, do nothing - if (!$this->setting->has('advertise_google_conversion_tracker')) { - return; - } - - $tracker = $this->setting->get('advertise_google_conversion_tracker'); - - // Insert the tags before the closing tag - $output = str_replace('', $tracker['google_global_site_tag'] . '', $output); - } - - public function before_checkout_success(&$route, &$data) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If there is no tracker, do nothing - if (!$this->setting->has('advertise_google_conversion_tracker')) { - return; - } - - // In case there is no order, do nothing - if (!isset($this->session->data['order_id'])) { - return; - } - - if (!$this->registry->has('googleshopping')) { - $this->loadLibrary($this->store_id); - } - - $this->load->model('checkout/order'); - $this->load->model('extension/advertise/google'); - - $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']); - - $tracker = $this->setting->get('advertise_google_conversion_tracker'); - $currency = $order_info['currency_code']; - - $total = $this->googleshopping->convertAndFormat($order_info['total'], $currency); - - $search = array( - '{VALUE}', - '{CURRENCY}' - ); - - $replace = array( - $total, - $currency - ); - - $snippet = str_replace($search, $replace, $tracker['google_event_snippet']); - - // Store the snippet to display it in the order success view - $tax = 0; - $shipping = 0; - $coupon = $this->model_extension_advertise_google->getCoupon($order_info['order_id']); - - foreach ($this->model_checkout_order->getOrderTotals($order_info['order_id']) as $order_total) { - if ($order_total['code'] == 'shipping') { - $shipping += $this->googleshopping->convertAndFormat($order_total['value'], $currency); - } - - if ($order_total['code'] == 'tax') { - $tax += $this->googleshopping->convertAndFormat($order_total['value'], $currency); - } - } - - $order_products = $this->model_checkout_order->getOrderProducts($order_info['order_id']); - - foreach ($order_products as &$order_product) { - $order_product['option'] = $this->model_checkout_order->getOrderOptions($order_info['order_id'], $order_product['order_product_id']); - } - - $purchase_data = array( - 'transaction_id' => $order_info['order_id'], - 'value' => $total, - 'currency' => $currency, - 'tax' => $tax, - 'shipping' => $shipping, - 'items' => $this->model_extension_advertise_google->getRemarketingItems($order_products, $order_info['store_id']), - 'ecomm_prodid' => $this->model_extension_advertise_google->getRemarketingProductIds($order_products, $order_info['store_id']) - ); - - if ($coupon !== null) { - $purchase_data['coupon'] = $coupon; - } - - $this->googleshopping->setEventSnippet($snippet); - $this->googleshopping->setPurchaseData($purchase_data); - } - - public function google_dynamic_remarketing_purchase(&$route, &$data, &$output) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If the library has not been loaded, or if there is no snippet, do nothing - if (!$this->registry->has('googleshopping') || $this->googleshopping->getEventSnippet() === null || $this->googleshopping->getPurchaseData() === null) { - return; - } - - $data['send_to'] = $this->googleshopping->getEventSnippetSendTo(); - - $purchase_data = $this->googleshopping->getPurchaseData(); - - $data['transaction_id'] = $purchase_data['transaction_id']; - $data['value'] = $purchase_data['value']; - $data['currency'] = $purchase_data['currency']; - $data['tax'] = $purchase_data['tax']; - $data['shipping'] = $purchase_data['shipping']; - $data['items'] = json_encode($purchase_data['items']); - $data['ecomm_prodid'] = json_encode($purchase_data['ecomm_prodid']); - $data['ecomm_totalvalue'] = $purchase_data['value']; - - $purchase_snippet = $this->load->view('extension/advertise/google_dynamic_remarketing_purchase', $data); - - // Insert the snippet after the output - $output = str_replace('', $this->googleshopping->getEventSnippet() . $purchase_snippet . '', $output); - } - - public function google_dynamic_remarketing_home(&$route, &$data, &$output) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If we are not on the home page, do nothing - if (isset($this->request->get['route']) && $this->request->get['route'] != $this->config->get('action_default')) { - return; - } - - if (!$this->registry->has('googleshopping')) { - $this->loadLibrary($this->store_id); - } - - if (null === $this->googleshopping->getEventSnippetSendTo()) { - return; - } - - $data = array(); - $data['send_to'] = $this->googleshopping->getEventSnippetSendTo(); - - $snippet = $this->load->view('extension/advertise/google_dynamic_remarketing_home', $data); - - // Insert the snippet after the output - $output = str_replace('', $snippet . '', $output); - } - - public function google_dynamic_remarketing_searchresults(&$route, &$data, &$output) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If we are not on the search page, do nothing - if (!isset($this->request->get['route']) || $this->request->get['route'] != 'product/search' || !isset($this->request->get['search'])) { - return; - } - - if (!$this->registry->has('googleshopping')) { - $this->loadLibrary($this->store_id); - } - - if (null === $this->googleshopping->getEventSnippetSendTo()) { - return; - } - - $data = array(); - $data['send_to'] = $this->googleshopping->getEventSnippetSendTo(); - $data['search_term'] = $this->request->get['search']; - - $snippet = $this->load->view('extension/advertise/google_dynamic_remarketing_searchresults', $data); - - // Insert the snippet after the output - $output = str_replace('', $snippet . '', $output); - } - - public function google_dynamic_remarketing_category(&$route, &$data, &$output) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If we are not on the search page, do nothing - if (!isset($this->request->get['route']) || $this->request->get['route'] != 'product/category') { - return; - } - - if (!$this->registry->has('googleshopping')) { - $this->loadLibrary($this->store_id); - } - - if (null === $this->googleshopping->getEventSnippetSendTo()) { - return; - } - - if (isset($this->request->get['path'])) { - $parts = explode('_', $this->request->get['path']); - $category_id = (int)end($parts); - } else if (isset($this->request->get['category_id'])) { - $category_id = (int)$this->request->get['category_id']; - } else { - $category_id = 0; - } - - $this->load->model('extension/advertise/google'); - - $data = array(); - $data['send_to'] = $this->googleshopping->getEventSnippetSendTo(); - $data['description'] = str_replace('"', '\\"', $this->model_extension_advertise_google->getHumanReadableOpenCartCategory($category_id)); - - $snippet = $this->load->view('extension/advertise/google_dynamic_remarketing_category', $data); - - // Insert the snippet after the output - $output = str_replace('', $snippet . '', $output); - } - - public function google_dynamic_remarketing_product(&$route, &$data, &$output) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If we do not know the viewed product, do nothing - if (!isset($this->request->get['product_id']) || !isset($this->request->get['route']) || $this->request->get['route'] != 'product/product') { - return; - } - - $this->load->model('catalog/product'); - - $product_info = $this->model_catalog_product->getProduct((int)$this->request->get['product_id']); - - // If product does not exist, do nothing - if (!$product_info) { - return; - } - - if (!$this->registry->has('googleshopping')) { - $this->loadLibrary($this->store_id); - } - - if (null === $this->googleshopping->getEventSnippetSendTo()) { - return; - } - - $this->load->model('extension/advertise/google'); - - $category_name = $this->model_extension_advertise_google->getHumanReadableCategory($product_info['product_id'], $this->store_id); - - $option_map = $this->model_extension_advertise_google->getSizeAndColorOptionMap($product_info['product_id'], $this->store_id); - - $data = array(); - $data['send_to'] = $this->googleshopping->getEventSnippetSendTo(); - $data['option_map'] = json_encode($option_map); - $data['brand'] = $product_info['manufacturer']; - $data['name'] = $product_info['name']; - $data['category'] = str_replace('"', '\\"', $category_name); - - $snippet = $this->load->view('extension/advertise/google_dynamic_remarketing_product', $data); - - // Insert the snippet after the output - $output = str_replace('', $snippet . '', $output); - } - - public function google_dynamic_remarketing_cart(&$route, &$data, &$output) { - // In case the extension is disabled, do nothing - if (!$this->setting->get('advertise_google_status')) { - return; - } - - // If we are not on the cart page, do nothing - if (!isset($this->request->get['route']) || $this->request->get['route'] != 'checkout/cart') { - return; - } - - if (!$this->registry->has('googleshopping')) { - $this->loadLibrary($this->store_id); - } - - if (null === $this->googleshopping->getEventSnippetSendTo()) { - return; - } - - $this->load->model('catalog/product'); - $this->load->model('extension/advertise/google'); - - $data = array(); - $data['send_to'] = $this->googleshopping->getEventSnippetSendTo(); - $data['ecomm_totalvalue'] = $this->cart->getTotal(); - $data['ecomm_prodid'] = json_encode($this->model_extension_advertise_google->getRemarketingProductIds($this->cart->getProducts(), $this->store_id)); - $data['items'] = json_encode($this->model_extension_advertise_google->getRemarketingItems($this->cart->getProducts(), $this->store_id)); - - $snippet = $this->load->view('extension/advertise/google_dynamic_remarketing_cart', $data); - - // Insert the snippet after the output - $output = str_replace('', $snippet . '', $output); - } - - public function cron($cron_id = null, $code = null, $cycle = null, $date_added = null, $date_modified = null) { - $this->loadLibrary($this->store_id); - - if (!$this->validateCRON()) { - // In case this is not a CRON task - return; - } - - $this->load->language('extension/advertise/google'); - - // Reset taxes to use the store address and zone - $this->tax->setShippingAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); - $this->tax->setPaymentAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); - $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); - - $this->googleshopping->cron(); - } - - protected function validateCRON() { - if (!$this->setting->get('advertise_google_status')) { - // In case the extension is disabled, do nothing - return false; - } - - if (!$this->setting->get('advertise_google_gmc_account_selected')) { - return false; - } - - if (!$this->setting->get('advertise_google_gmc_shipping_taxes_configured')) { - return false; - } - - try { - if (count($this->googleshopping->getTargets($this->store_id)) === 0) { - return false; - } - } catch (\RuntimeException $e) { - return false; - } - - if (isset($this->request->get['cron_token']) && $this->request->get['cron_token'] == $this->config->get('advertise_google_cron_token')) { - return true; - } - - if (defined('ADVERTISE_GOOGLE_ROUTE')) { - return true; - } - - return false; - } -} \ No newline at end of file diff --git a/public/store/controller/extension/analytics/google.php b/public/store/controller/extension/analytics/google.php deleted file mode 100644 index 7bb3ddd..0000000 --- a/public/store/controller/extension/analytics/google.php +++ /dev/null @@ -1,6 +0,0 @@ -config->get('analytics_google_code'), ENT_QUOTES, 'UTF-8'); - } -} diff --git a/public/store/controller/extension/captcha/google.php b/public/store/controller/extension/captcha/google.php deleted file mode 100644 index ee2e60c..0000000 --- a/public/store/controller/extension/captcha/google.php +++ /dev/null @@ -1,38 +0,0 @@ -load->language('extension/captcha/google'); - - if (isset($error['captcha'])) { - $data['error_captcha'] = $error['captcha']; - } else { - $data['error_captcha'] = ''; - } - - $data['site_key'] = $this->config->get('captcha_google_key'); - - $data['route'] = $this->request->get['route']; - - return $this->load->view('extension/captcha/google', $data); - } - - public function validate() { - if (empty($this->session->data['gcapcha'])) { - $this->load->language('extension/captcha/google'); - - if (!isset($this->request->post['g-recaptcha-response'])) { - return $this->language->get('error_captcha'); - } - - $recaptcha = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($this->config->get('captcha_google_secret')) . '&response=' . $this->request->post['g-recaptcha-response'] . '&remoteip=' . $this->request->server['REMOTE_ADDR']); - - $recaptcha = json_decode($recaptcha, true); - - if ($recaptcha['success']) { - $this->session->data['gcapcha'] = true; - } else { - return $this->language->get('error_captcha'); - } - } - } -} diff --git a/public/store/language/ru-ru/extension/captcha/google.php b/public/store/language/ru-ru/extension/captcha/google.php deleted file mode 100644 index 9ec4483..0000000 --- a/public/store/language/ru-ru/extension/captcha/google.php +++ /dev/null @@ -1,12 +0,0 @@ -load->config('googleshopping/googleshopping'); - - $google_category_result = $this->db->query("SELECT google_product_category FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE pag.product_id = " . (int)$product_id . " AND pag.store_id = " . (int)$store_id); - - if ($google_category_result->num_rows > 0) { - $google_category_id = $google_category_result->row['google_product_category']; - $google_categories = $this->config->get('advertise_google_google_product_categories'); - - if (!empty($google_category_id) && isset($google_categories[$google_category_id])) { - return $google_categories[$google_category_id]; - } - } - - $oc_category_result = $this->db->query("SELECT c.category_id FROM `" . DB_PREFIX . "product_to_category` p2c LEFT JOIN `" . DB_PREFIX . "category` c ON (c.category_id = p2c.category_id) WHERE p2c.product_id=" . (int)$product_id . " LIMIT 0,1"); - - if ($oc_category_result->num_rows > 0) { - return $this->getHumanReadableOpenCartCategory((int)$oc_category_result->row['category_id']); - } - - return ""; - } - - public function getHumanReadableOpenCartCategory($category_id) { - $sql = "SELECT GROUP_CONCAT(cd.name ORDER BY cp.level SEPARATOR ' > ') AS path FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "category_description cd ON (cp.path_id = cd.category_id) WHERE cd.language_id=" . (int)$this->config->get('config_language_id') . " AND cp.category_id=" . (int)$category_id; - - $result = $this->db->query($sql); - - if ($result->num_rows > 0) { - return $result->row['path']; - } - - return ""; - } - - public function getSizeAndColorOptionMap($product_id, $store_id) { - $color_id = $this->getOptionId($product_id, $store_id, 'color'); - $size_id = $this->getOptionId($product_id, $store_id, 'size'); - - $groups = $this->googleshopping->getGroups($product_id, $this->config->get('config_language_id'), $color_id, $size_id); - - $colors = $this->googleshopping->getProductOptionValueNames($product_id, $this->config->get('config_language_id'), $color_id); - $sizes = $this->googleshopping->getProductOptionValueNames($product_id, $this->config->get('config_language_id'), $size_id); - - $map = array( - 'groups' => $groups, - 'colors' => count($colors) > 1 ? $colors : null, - 'sizes' => count($sizes) > 1 ? $sizes : null, - ); - - return $map; - } - - public function getCoupon($order_id) { - $sql = "SELECT c.code FROM `" . DB_PREFIX . "coupon_history` ch LEFT JOIN `" . DB_PREFIX . "coupon` c ON (c.coupon_id = ch.coupon_id) WHERE ch.order_id=" . (int)$order_id; - - $result = $this->db->query($sql); - - if ($result->num_rows > 0) { - return $result->row['code']; - } - - return null; - } - - public function getRemarketingProductIds($products, $store_id) { - $ecomm_prodid = array(); - - foreach ($products as $product) { - if (null !== $id = $this->getRemarketingProductId($product, $store_id)) { - $ecomm_prodid[] = $id; - } - } - - return $ecomm_prodid; - } - - public function getRemarketingItems($products, $store_id) { - $items = array(); - - foreach ($products as $product) { - if (null !== $id = $this->getRemarketingProductId($product, $store_id)) { - $items[] = array( - 'google_business_vertical' => 'retail', - 'id' => (string)$id, - 'name' => (string)$product['name'], - 'quantity' => (int)$product['quantity'] - ); - } - } - - return $items; - } - - protected function getRemarketingProductId($product, $store_id) { - $option_map = $this->getSizeAndColorOptionMap($product['product_id'], $store_id); - $found_color = ""; - $found_size = ""; - - foreach ($product['option'] as $option) { - if (is_array($option_map['colors'])) { - foreach ($option_map['colors'] as $product_option_value_id => $color) { - if ($option['product_option_value_id'] == $product_option_value_id) { - $found_color = $color; - } - } - } - - if (is_array($option_map['sizes'])) { - foreach ($option_map['sizes'] as $product_option_value_id => $size) { - if ($option['product_option_value_id'] == $product_option_value_id) { - $found_size = $size; - } - } - } - } - - foreach ($option_map['groups'] as $id => $group) { - if ($group['color'] === $found_color && $group['size'] === $found_size) { - return $id; - } - } - - return null; - } - - protected function getOptionId($product_id, $store_id, $type) { - $sql = "SELECT pag." . $type . " FROM `" . DB_PREFIX . "googleshopping_product` pag WHERE product_id=" . (int)$product_id . " AND store_id=" . (int)$store_id; - - $result = $this->db->query($sql); - - if ($result->num_rows > 0) { - return (int)$result->row[$type]; - } - - return 0; - } -} \ No newline at end of file diff --git a/public/store/view/theme/dominik/template/extension/captcha/google.twig b/public/store/view/theme/dominik/template/extension/captcha/google.twig deleted file mode 100644 index 71c60ec..0000000 --- a/public/store/view/theme/dominik/template/extension/captcha/google.twig +++ /dev/null @@ -1,18 +0,0 @@ - -
- {{ text_captcha }} -
{% if route|slice(0, 9) == 'checkout/' %} - -
- {% if error_captcha %} -
{{ error_captcha }}
- {% endif %} - {% else %} - -
-
- {% if error_captcha %} -
{{ error_captcha }}
- {% endif %}
- {% endif %}
-
diff --git a/public/system/config/googleshopping/googleshopping.php b/public/system/config/googleshopping/googleshopping.php deleted file mode 100644 index 6689aee..0000000 --- a/public/system/config/googleshopping/googleshopping.php +++ /dev/null @@ -1,774 +0,0 @@ - array( - 'countries' => array(), - 'selected_field' => NULL - ), - 'condition' => array( - 'countries' => array(), - 'selected_field' => NULL - ), - 'adult' => array( - 'countries' => array(), - 'selected_field' => NULL - ), - 'multipack' => array( - 'countries' => array('AU', 'BR', 'CZ', 'FR', 'DE', 'IT', 'JP', 'NL', 'ES', 'CH', 'GB', 'US'), - 'selected_field' => NULL - ), - 'is_bundle' => array( - 'countries' => array('AU', 'BR', 'CZ', 'FR', 'DE', 'IT', 'JP', 'NL', 'ES', 'CH', 'GB', 'US'), - 'selected_field' => NULL - ), - 'age_group' => array( - 'countries' => array('BR', 'FR', 'DE', 'JP', 'GB', 'US'), - 'selected_field' => array( - 'google_product_category' => array('1604', '178', '3032', '201', '187') - ) - ), - 'color' => array( - 'countries' => array('BR', 'FR', 'DE', 'JP', 'GB', 'US'), - 'selected_field' => array( - 'google_product_category' => array('1604', '178', '3032', '201', '187') - ) - ), - 'gender' => array( - 'countries' => array('BR', 'FR', 'DE', 'JP', 'GB', 'US'), - 'selected_field' => array( - 'google_product_category' => array('1604', '178', '3032', '201', '187') - ) - ), - 'size' => array( - 'countries' => array('BR', 'FR', 'DE', 'JP', 'GB', 'US'), - 'selected_field' => array( - 'google_product_category' => array('1604', '187') - ) - ), - 'size_type' => array( - 'countries' => array('BR', 'FR', 'DE', 'JP', 'GB', 'US'), - 'selected_field' => array( - 'google_product_category' => array('1604', '187') - ) - ), - 'size_system' => array( - 'countries' => array('BR', 'FR', 'DE', 'JP', 'GB', 'US'), - 'selected_field' => array( - 'google_product_category' => array('1604', '187') - ) - ) -); - -$_['advertise_google_tax_usa_states'] = array( - '21132' => 'Alaska', - '21133' => 'Alabama', - '21135' => 'Arkansas', - '21136' => 'Arizona', - '21137' => 'California', - '21138' => 'Colorado', - '21139' => 'Connecticut', - '21140' => 'District of Columbia', - '21141' => 'Delaware', - '21142' => 'Florida', - '21143' => 'Georgia', - '21144' => 'Hawaii', - '21145' => 'Iowa', - '21146' => 'Idaho', - '21147' => 'Illinois', - '21148' => 'Indiana', - '21149' => 'Kansas', - '21150' => 'Kentucky', - '21151' => 'Louisiana', - '21152' => 'Massachusetts', - '21153' => 'Maryland', - '21154' => 'Maine', - '21155' => 'Michigan', - '21156' => 'Minnesota', - '21157' => 'Missouri', - '21158' => 'Mississippi', - '21159' => 'Montana', - '21160' => 'North Carolina', - '21161' => 'North Dakota', - '21162' => 'Nebraska', - '21163' => 'New Hampshire', - '21164' => 'New Jersey', - '21165' => 'New Mexico', - '21166' => 'Nevada', - '21167' => 'New York', - '21168' => 'Ohio', - '21169' => 'Oklahoma', - '21170' => 'Oregon', - '21171' => 'Pennsylvania', - '21172' => 'Rhode Island', - '21173' => 'South Carolina', - '21174' => 'South Dakota', - '21175' => 'Tennessee', - '21176' => 'Texas', - '21177' => 'Utah', - '21178' => 'Virginia', - '21179' => 'Vermont', - '21180' => 'Washington', - '21182' => 'Wisconsin', - '21183' => 'West Virginia', - '21184' => 'Wyoming' -); - -$_['advertise_google_google_product_categories'] = array( - '0' => 'Other (Not on the list)', - '1604' => 'Apparel & Accessories > Clothing', - '178' => 'Apparel & Accessories > Clothing Accessories > Sunglasses', - '3032' => 'Apparel & Accessories > Handbags, Wallets & Cases > Handbags', - '201' => 'Apparel & Accessories > Jewelry > Watches', - '187' => 'Apparel & Accessories > Shoes', - '784' => 'Media > Books', - '839' => 'Media > DVDs & Videos', - '855' => 'Media > Music & Sound Recordings', - '1279' => 'Software > Video Game Software' -); - -$_['advertise_google_size_systems'] = array('AU','BR','CN','DE','EU','FR','IT','JP','MEX','UK','US'); - -$_['advertise_google_reporting_intervals'] = array( - 'TODAY', - 'YESTERDAY', - 'LAST_7_DAYS', - 'LAST_WEEK', - 'LAST_WEEK_SUN_SAT', - 'LAST_BUSINESS_WEEK', - 'LAST_14_DAYS', - 'LAST_30_DAYS', - 'THIS_WEEK_MON_TODAY', - 'THIS_WEEK_SUN_TODAY', - 'THIS_MONTH' -); - -$_['advertise_google_reporting_intervals_default'] = 'LAST_30_DAYS'; - -// https://support.google.com/adwords/answer/2454022?hl=en&co=ADWORDS.IsAWNCustomer%3Dfalse -$_['advertise_google_countries'] = array( - 'AR' => "Argentina", - 'AU' => "Australia", - 'AT' => "Austria", - 'BE' => "Belgium", - 'BR' => "Brazil", - 'CA' => "Canada", - 'CL' => "Chile", - 'CO' => "Colombia", - 'CZ' => "Czechia", - 'DK' => "Denmark", - 'FR' => "France", - 'DE' => "Germany", - 'HK' => "Hong Kong", - 'IN' => "India", - 'ID' => "Indonesia", - 'IE' => "Ireland", - 'IL' => "Israel", - 'IT' => "Italy", - 'JP' => "Japan", - 'MY' => "Malaysia", - 'MX' => "Mexico", - 'NL' => "Netherlands", - 'NZ' => "New Zealand", - 'NO' => "Norway", - 'PH' => "Philippines", - 'PL' => "Poland", - 'PT' => "Portugal", - 'RU' => "Russia", - 'SA' => "Saudi Arabia", - 'SG' => "Singapore", - 'ZA' => "South Africa", - 'KR' => "South Korea", - 'ES' => "Spain", - 'SE' => "Sweden", - 'CH' => "Switzerland", - 'TW' => "Taiwan", - 'TH' => "Thailand", - 'TR' => "Turkey", - 'UA' => "Ukraine", - 'AE' => "United Arab Emirates", - 'GB' => "United Kingdom", - 'US' => "United States", - 'VN' => "Vietnam" -); - -// https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes -$_['advertise_google_languages'] = array( - 'ab' => "Abkhazian", - 'aa' => "Afar", - 'af' => "Afrikaans", - 'ak' => "Akan", - 'sq' => "Albanian", - 'am' => "Amharic", - 'ar' => "Arabic", - 'an' => "Aragonese", - 'hy' => "Armenian", - 'as' => "Assamese", - 'av' => "Avaric", - 'ae' => "Avestan", - 'ay' => "Aymara", - 'az' => "Azerbaijani", - 'bm' => "Bambara", - 'ba' => "Bashkir", - 'eu' => "Basque", - 'be' => "Belarusian", - 'bn' => "Bengali", - 'bh' => "Bihari languages", - 'bi' => "Bislama", - 'bs' => "Bosnian", - 'br' => "Breton", - 'bg' => "Bulgarian", - 'my' => "Burmese", - 'ca' => "Catalan, Valencian", - 'ch' => "Chamorro", - 'ce' => "Chechen", - 'ny' => "Chichewa, Chewa, Nyanja", - 'zh' => "Chinese", - 'cv' => "Chuvash", - 'kw' => "Cornish", - 'co' => "Corsican", - 'cr' => "Cree", - 'hr' => "Croatian", - 'cs' => "Czech", - 'da' => "Danish", - 'dv' => "Divehi, Dhivehi, Maldivian", - 'nl' => "Dutch, Flemish", - 'dz' => "Dzongkha", - 'en' => "English", - 'eo' => "Esperanto", - 'et' => "Estonian", - 'ee' => "Ewe", - 'fo' => "Faroese", - 'fj' => "Fijian", - 'fl' => "Filipino", - 'fi' => "Finnish", - 'fr' => "French", - 'ff' => "Fulah", - 'gl' => "Galician", - 'ka' => "Georgian", - 'de' => "German", - 'el' => "Greek (modern)", - 'gn' => "Guaraní", - 'gu' => "Gujarati", - 'ht' => "Haitian, Haitian Creole", - 'ha' => "Hausa", - 'he' => "Hebrew (modern)", - 'hz' => "Herero", - 'hi' => "Hindi", - 'ho' => "Hiri Motu", - 'hu' => "Hungarian", - 'ia' => "Interlingua", - 'id' => "Indonesian", - 'ie' => "Interlingue", - 'ga' => "Irish", - 'ig' => "Igbo", - 'ik' => "Inupiaq", - 'io' => "Ido", - 'is' => "Icelandic", - 'it' => "Italian", - 'iu' => "Inuktitut", - 'ja' => "Japanese", - 'jv' => "Javanese", - 'kl' => "Kalaallisut, Greenlandic", - 'kn' => "Kannada", - 'kr' => "Kanuri", - 'ks' => "Kashmiri", - 'kk' => "Kazakh", - 'km' => "Central Khmer", - 'ki' => "Kikuyu, Gikuyu", - 'rw' => "Kinyarwanda", - 'ky' => "Kirghiz, Kyrgyz", - 'kv' => "Komi", - 'kg' => "Kongo", - 'ko' => "Korean", - 'ku' => "Kurdish", - 'kj' => "Kuanyama, Kwanyama", - 'la' => "Latin", - 'lb' => "Luxembourgish, Letzeburgesch", - 'lg' => "Ganda", - 'li' => "Limburgan, Limburger, Limburgish", - 'ln' => "Lingala", - 'lo' => "Lao", - 'lt' => "Lithuanian", - 'lu' => "Luba-Katanga", - 'lv' => "Latvian", - 'gv' => "Manx", - 'mk' => "Macedonian", - 'mg' => "Malagasy", - 'ms' => "Malay", - 'ml' => "Malayalam", - 'mt' => "Maltese", - 'mi' => "Maori", - 'mr' => "Marathi", - 'mh' => "Marshallese", - 'mn' => "Mongolian", - 'na' => "Nauru", - 'nv' => "Navajo, Navaho", - 'nd' => "North Ndebele", - 'ne' => "Nepali", - 'ng' => "Ndonga", - 'nb' => "Norwegian Bokmål", - 'nn' => "Norwegian Nynorsk", - 'no' => "Norwegian", - 'ii' => "Sichuan Yi, Nuosu", - 'nr' => "South Ndebele", - 'oc' => "Occitan", - 'oj' => "Ojibwa", - 'cu' => "Church Slavic, Church Slavonic, Old Church Slavonic, Old Slavonic, Old Bulgarian", - 'om' => "Oromo", - 'or' => "Oriya", - 'os' => "Ossetian, Ossetic", - 'pa' => "Panjabi, Punjabi", - 'pi' => "Pali", - 'fa' => "Persian", - 'pl' => "Polish", - 'ps' => "Pashto, Pushto", - 'pt' => "Portuguese", - 'qu' => "Quechua", - 'rm' => "Romansh", - 'rn' => "Rundi", - 'ro' => "Romanian, Moldavian, Moldovan", - 'ru' => "Russian", - 'sa' => "Sanskrit", - 'sc' => "Sardinian", - 'sd' => "Sindhi", - 'se' => "Northern Sami", - 'sm' => "Samoan", - 'sg' => "Sango", - 'sr' => "Serbian", - 'gd' => "Gaelic, Scottish Gaelic", - 'sn' => "Shona", - 'si' => "Sinhala, Sinhalese", - 'sk' => "Slovak", - 'sl' => "Slovenian", - 'so' => "Somali", - 'st' => "Southern Sotho", - 'es' => "Spanish, Castilian", - 'su' => "Sundanese", - 'sw' => "Swahili", - 'ss' => "Swati", - 'sv' => "Swedish", - 'ta' => "Tamil", - 'te' => "Telugu", - 'tg' => "Tajik", - 'th' => "Thai", - 'ti' => "Tigrinya", - 'bo' => "Tibetan", - 'tk' => "Turkmen", - 'tl' => "Tagalog", - 'tn' => "Tswana", - 'to' => "Tongan (Tonga Islands)", - 'tr' => "Turkish", - 'ts' => "Tsonga", - 'tt' => "Tatar", - 'tw' => "Twi", - 'ty' => "Tahitian", - 'ug' => "Uighur, Uyghur", - 'uk' => "Ukrainian", - 'ur' => "Urdu", - 'uz' => "Uzbek", - 've' => "Venda", - 'vi' => "Vietnamese", - 'vo' => "Volapük", - 'wa' => "Walloon", - 'cy' => "Welsh", - 'wo' => "Wolof", - 'fy' => "Western Frisian", - 'xh' => "Xhosa", - 'yi' => "Yiddish", - 'yo' => "Yoruba", - 'za' => "Zhuang, Chuang", - 'zu' => "Zulu" -); - -$_['advertise_google_currencies'] = array( - "AED" => "United Arab Emirates Dirham", - "AFN" => "Afghanistan Afghani", - "ALL" => "Albania Lek", - "AMD" => "Armenia Dram", - "ANG" => "Netherlands Antilles Guilder", - "AOA" => "Angola Kwanza", - "ARS" => "Argentina Peso", - "AUD" => "Australia Dollar", - "AWG" => "Aruba Guilder", - "AZN" => "Azerbaijan Manat", - "BAM" => "Bosnia and Herzegovina Convertible Marka", - "BBD" => "Barbados Dollar", - "BDT" => "Bangladesh Taka", - "BGN" => "Bulgaria Lev", - "BHD" => "Bahrain Dinar", - "BIF" => "Burundi Franc", - "BMD" => "Bermuda Dollar", - "BND" => "Brunei Darussalam Dollar", - "BOB" => "Bolivia Bolíviano", - "BRL" => "Brazil Real", - "BSD" => "Bahamas Dollar", - "BTN" => "Bhutan Ngultrum", - "BWP" => "Botswana Pula", - "BYN" => "Belarus Ruble", - "BZD" => "Belize Dollar", - "CAD" => "Canada Dollar", - "CDF" => "Congo/Kinshasa Franc", - "CHF" => "Switzerland Franc", - "CLP" => "Chile Peso", - "CNY" => "China Yuan Renminbi", - "COP" => "Colombia Peso", - "CRC" => "Costa Rica Colon", - "CUC" => "Cuba Convertible Peso", - "CUP" => "Cuba Peso", - "CVE" => "Cape Verde Escudo", - "CZK" => "Czech Republic Koruna", - "DJF" => "Djibouti Franc", - "DKK" => "Denmark Krone", - "DOP" => "Dominican Republic Peso", - "DZD" => "Algeria Dinar", - "EGP" => "Egypt Pound", - "ERN" => "Eritrea Nakfa", - "ETB" => "Ethiopia Birr", - "EUR" => "Euro Member Countries", - "FJD" => "Fiji Dollar", - "FKP" => "Falkland Islands (Malvinas) Pound", - "GBP" => "United Kingdom Pound", - "GEL" => "Georgia Lari", - "GGP" => "Guernsey Pound", - "GHS" => "Ghana Cedi", - "GIP" => "Gibraltar Pound", - "GMD" => "Gambia Dalasi", - "GNF" => "Guinea Franc", - "GTQ" => "Guatemala Quetzal", - "GYD" => "Guyana Dollar", - "HKD" => "Hong Kong Dollar", - "HNL" => "Honduras Lempira", - "HRK" => "Croatia Kuna", - "HTG" => "Haiti Gourde", - "HUF" => "Hungary Forint", - "IDR" => "Indonesia Rupiah", - "ILS" => "Israel Shekel", - "IMP" => "Isle of Man Pound", - "INR" => "India Rupee", - "IQD" => "Iraq Dinar", - "IRR" => "Iran Rial", - "ISK" => "Iceland Krona", - "JEP" => "Jersey Pound", - "JMD" => "Jamaica Dollar", - "JOD" => "Jordan Dinar", - "JPY" => "Japan Yen", - "KES" => "Kenya Shilling", - "KGS" => "Kyrgyzstan Som", - "KHR" => "Cambodia Riel", - "KMF" => "Comorian Franc", - "KPW" => "Korea (North) Won", - "KRW" => "Korea (South) Won", - "KWD" => "Kuwait Dinar", - "KYD" => "Cayman Islands Dollar", - "KZT" => "Kazakhstan Tenge", - "LAK" => "Laos Kip", - "LBP" => "Lebanon Pound", - "LKR" => "Sri Lanka Rupee", - "LRD" => "Liberia Dollar", - "LSL" => "Lesotho Loti", - "LYD" => "Libya Dinar", - "MAD" => "Morocco Dirham", - "MDL" => "Moldova Leu", - "MGA" => "Madagascar Ariary", - "MKD" => "Macedonia Denar", - "MMK" => "Myanmar (Burma) Kyat", - "MNT" => "Mongolia Tughrik", - "MOP" => "Macau Pataca", - "MRU" => "Mauritania Ouguiya", - "MUR" => "Mauritius Rupee", - "MVR" => "Maldives (Maldive Islands) Rufiyaa", - "MWK" => "Malawi Kwacha", - "MXN" => "Mexico Peso", - "MYR" => "Malaysia Ringgit", - "MZN" => "Mozambique Metical", - "NAD" => "Namibia Dollar", - "NGN" => "Nigeria Naira", - "NIO" => "Nicaragua Cordoba", - "NOK" => "Norway Krone", - "NPR" => "Nepal Rupee", - "NZD" => "New Zealand Dollar", - "OMR" => "Oman Rial", - "PAB" => "Panama Balboa", - "PEN" => "Peru Sol", - "PGK" => "Papua New Guinea Kina", - "PHP" => "Philippines Piso", - "PKR" => "Pakistan Rupee", - "PLN" => "Poland Zloty", - "PYG" => "Paraguay Guarani", - "QAR" => "Qatar Riyal", - "RON" => "Romania Leu", - "RSD" => "Serbia Dinar", - "RUB" => "Russia Ruble", - "RWF" => "Rwanda Franc", - "SAR" => "Saudi Arabia Riyal", - "SBD" => "Solomon Islands Dollar", - "SCR" => "Seychelles Rupee", - "SDG" => "Sudan Pound", - "SEK" => "Sweden Krona", - "SGD" => "Singapore Dollar", - "SHP" => "Saint Helena Pound", - "SLL" => "Sierra Leone Leone", - "SOS" => "Somalia Shilling", - "SPL*" => "Seborga Luigino", - "SRD" => "Suriname Dollar", - "STN" => "São Tomé and Príncipe Dobra", - "SVC" => "El Salvador Colon", - "SYP" => "Syria Pound", - "SZL" => "Swaziland Lilangeni", - "THB" => "Thailand Baht", - "TJS" => "Tajikistan Somoni", - "TMT" => "Turkmenistan Manat", - "TND" => "Tunisia Dinar", - "TOP" => "Tonga Pa'anga", - "TRY" => "Turkey Lira", - "TTD" => "Trinidad and Tobago Dollar", - "TVD" => "Tuvalu Dollar", - "TWD" => "Taiwan New Dollar", - "TZS" => "Tanzania Shilling", - "UAH" => "Ukraine Hryvnia", - "UGX" => "Uganda Shilling", - "USD" => "United States Dollar", - "UYU" => "Uruguay Peso", - "UZS" => "Uzbekistan Som", - "VEF" => "Venezuela Bolívar", - "VND" => "Viet Nam Dong", - "VUV" => "Vanuatu Vatu", - "WST" => "Samoa Tala", - "XAF" => "Communauté Financière Africaine (BEAC) CFA Franc BEAC", - "XCD" => "East Caribbean Dollar", - "XDR" => "International Monetary Fund (IMF) Special Drawing Rights", - "XOF" => "Communauté Financière Africaine (BCEAO) Franc", - "XPF" => "Comptoirs Français du Pacifique (CFP) Franc", - "YER" => "Yemen Rial", - "ZAR" => "South Africa Rand", - "ZMW" => "Zambia Kwacha", - "ZWD" => "Zimbabwe Dollar" -); - -/* - * These entries are defined based on this help article: - * https://support.google.com/merchants/answer/160637?hl=en - */ -$_['advertise_google_targets'] = array( - array( - 'country' => 'AR', - 'languages' => array('es'), - 'currencies' => array('ARS') - ), - array( - 'country' => 'AU', - 'languages' => array('en', 'zh'), - 'currencies' => array('AUD') - ), - array( - 'country' => 'AT', - 'languages' => array('de', 'en'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'BE', - 'languages' => array('fr', 'nl', 'en'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'BR', - 'languages' => array('pt'), - 'currencies' => array('BRL') - ), - array( - 'country' => 'CA', - 'languages' => array('en', 'fr', 'zh'), - 'currencies' => array('CAD') - ), - array( - 'country' => 'CL', - 'languages' => array('es'), - 'currencies' => array('CLP') - ), - array( - 'country' => 'CO', - 'languages' => array('es'), - 'currencies' => array('COP') - ), - array( - 'country' => 'CZ', - 'languages' => array('cs', 'en'), - 'currencies' => array('CZK') - ), - array( - 'country' => 'DK', - 'languages' => array('da', 'en'), - 'currencies' => array('DKK') - ), - array( - 'country' => 'FR', - 'languages' => array('fr'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'DE', - 'languages' => array('de', 'en'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'HK', - 'languages' => array('zh', 'en'), - 'currencies' => array('HKD') - ), - array( - 'country' => 'IN', - 'languages' => array('en'), - 'currencies' => array('INR') - ), - array( - 'country' => 'ID', - 'languages' => array('id', 'en'), - 'currencies' => array('IDR') - ), - array( - 'country' => 'IE', - 'languages' => array('en'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'IL', - 'languages' => array('he', 'en'), - 'currencies' => array('ILS') - ), - array( - 'country' => 'IT', - 'languages' => array('it'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'JP', - 'languages' => array('ja'), - 'currencies' => array('JPY') - ), - array( - 'country' => 'MY', - 'languages' => array('en', 'zh'), - 'currencies' => array('MYR') - ), - array( - 'country' => 'MX', - 'languages' => array('es', 'en'), - 'currencies' => array('MXN') - ), - array( - 'country' => 'NL', - 'languages' => array('nl', 'en'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'NZ', - 'languages' => array('en'), - 'currencies' => array('NZD') - ), - array( - 'country' => 'NO', - 'languages' => array('no', 'en'), - 'currencies' => array('NOK') - ), - array( - 'country' => 'PH', - 'languages' => array('en'), - 'currencies' => array('PHP') - ), - array( - 'country' => 'PL', - 'languages' => array('pl'), - 'currencies' => array('PLN') - ), - array( - 'country' => 'PT', - 'languages' => array('pt'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'RU', - 'languages' => array('ru'), - 'currencies' => array('RUB') - ), - array( - 'country' => 'SA', - 'languages' => array('ar', 'en'), - 'currencies' => array('SAR') - ), - array( - 'country' => 'SG', - 'languages' => array('en', 'zh'), - 'currencies' => array('SGD') - ), - array( - 'country' => 'ZA', - 'languages' => array('en'), - 'currencies' => array('ZAR') - ), - array( - 'country' => 'KR', - 'languages' => array('ko', 'en'), - 'currencies' => array('KRW') - ), - array( - 'country' => 'ES', - 'languages' => array('es'), - 'currencies' => array('EUR') - ), - array( - 'country' => 'SE', - 'languages' => array('sv', 'en'), - 'currencies' => array('SEK') - ), - array( - 'country' => 'CH', - 'languages' => array('en', 'de', 'fr', 'it'), - 'currencies' => array('CHF') - ), - array( - 'country' => 'TW', - 'languages' => array('zh', 'en'), - 'currencies' => array('TWD') - ), - array( - 'country' => 'TH', - 'languages' => array('th', 'en'), - 'currencies' => array('THB') - ), - array( - 'country' => 'TR', - 'languages' => array('tr', 'en'), - 'currencies' => array('TRY') - ), - array( - 'country' => 'UA', - 'languages' => array('uk', 'ru'), - 'currencies' => array('UAH') - ), - array( - 'country' => 'AE', - 'languages' => array('en'), - 'currencies' => array('AED') - ), - array( - 'country' => 'GB', - 'languages' => array('en'), - 'currencies' => array('GBP') - ), - array( - 'country' => 'US', - 'languages' => array('en', 'es', 'zh'), - 'currencies' => array('USD') - ), - array( - 'country' => 'VN', - 'languages' => array('vi', 'en'), - 'currencies' => array('VND') - ) -); \ No newline at end of file diff --git a/public/system/library/googleshopping/cron.php b/public/system/library/googleshopping/cron.php deleted file mode 100644 index 823d832..0000000 --- a/public/system/library/googleshopping/cron.php +++ /dev/null @@ -1,9 +0,0 @@ -store_id = $store_id; - - $this->load->model('setting/setting'); - - if ($this->store_id === 0) { - $this->store_url = basename(DIR_TEMPLATE) == 'template' ? HTTPS_CATALOG : HTTPS_SERVER; - $this->store_name = $this->config->get('config_name'); - } else { - $this->store_url = $this->model_setting_setting->getSettingValue('config_ssl', $store_id); - $this->store_name = $this->model_setting_setting->getSettingValue('config_name', $store_id); - } - - $this->endpoint_url = self::API_URL . 'index.php?route=%s'; - - $this->loadStore($this->store_id); - - $this->debug_log = new Log(sprintf(self::DEBUG_LOG_FILENAME, $this->store_id)); - } - - public function getStoreUrl() { - return $this->store_url; - } - - public function getStoreName() { - return $this->store_name; - } - - public function getSupportedLanguageId($code) { - $this->load->model('localisation/language'); - - foreach ($this->model_localisation_language->getLanguages() as $language) { - $language_code = current(explode("-", $language['code'])); - - if ($this->compareTrimmedLowercase($code, $language_code) === 0) { - return (int)$language['language_id']; - } - } - - return 0; - } - - public function getSupportedCurrencyId($code) { - $this->load->model('localisation/currency'); - - foreach ($this->model_localisation_currency->getCurrencies() as $currency) { - if ($this->compareTrimmedLowercase($code, $currency['code']) === 0) { - return (int)$currency['currency_id']; - } - } - - return 0; - } - - public function getCountryName($code) { - $this->load->config('googleshopping/googleshopping'); - - $this->load->model('localisation/country'); - - $countries = $this->config->get('advertise_google_countries'); - - // Default value - $result = $countries[$code]; - - // Override with store value, if present - foreach ($this->model_localisation_country->getCountries() as $store_country) { - if ($this->compareTrimmedLowercase($store_country['iso_code_2'], $code) === 0) { - $result = $store_country['name']; - break; - } - } - - return $result; - } - - public function compareTrimmedLowercase($text1, $text2) { - return strcmp(strtolower(trim($text1)), strtolower(trim($text2))); - } - - public function getTargets($store_id) { - $sql = "SELECT * FROM `" . DB_PREFIX . "googleshopping_target` WHERE store_id=" . $store_id; - - return array_map(array($this, 'target'), $this->db->query($sql)->rows); - } - - public function getTarget($advertise_google_target_id) { - $sql = "SELECT * FROM `" . DB_PREFIX . "googleshopping_target` WHERE advertise_google_target_id=" . (int)$advertise_google_target_id; - - return $this->target($this->db->query($sql)->row); - } - - public function editTarget($target_id, $target) { - $sql = "UPDATE `" . DB_PREFIX . "googleshopping_target` SET `campaign_name`='" . $this->db->escape($target['campaign_name']) . "', `country`='" . $this->db->escape($target['country']) . "', `budget`='" . (float)$target['budget'] . "', `feeds`='" . $this->db->escape(json_encode($target['feeds'])) . "', `roas`='" . (int)$target['roas'] . "', `status`='" . $this->db->escape($target['status']) . "' WHERE `advertise_google_target_id`='" . (int)$target_id . "'"; - - $this->db->query($sql); - - return $target; - } - - public function deleteTarget($target_id) { - $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_target` WHERE `advertise_google_target_id`='" . (int)$target_id . "'"; - - $this->db->query($sql); - - $sql = "DELETE FROM `" . DB_PREFIX . "googleshopping_product_target` WHERE `advertise_google_target_id`='" . (int)$target_id . "'"; - - $this->db->query($sql); - - return true; - } - - public function doJob($job) { - $product_count = 0; - - // Initialize push - $init_request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_DATAFEED_INIT, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => array( - 'work_id' => $job['work_id'] - ) - ); - - $response = $this->api($init_request); - - // At this point, the job has been initialized and we can start pushing the datafeed - $page = 0; - - while (null !== $products = $this->getFeedProducts(++$page, $job['language_id'], $job['currency'])) { - $post = array(); - - $post_data = array( - 'product' => $products, - 'work_id' => $job['work_id'], - 'work_step' => $response['work_step'] - ); - - $this->curlPostQuery($post_data, $post); - - $push_request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_DATAFEED_PUSH, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $post - ); - - $response = $this->api($push_request); - - $product_count += count($products); - } - - // Finally, close the file to finish the job - $close_request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_DATAFEED_CLOSE, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => array( - 'work_id' => $job['work_id'], - 'work_step' => $response['work_step'] - ) - ); - - $this->api($close_request); - - return $product_count; - } - - public function getProductVariationIds($page) { - $this->load->config('googleshopping/googleshopping'); - - $sql = "SELECT DISTINCT pag.product_id, pag.color, pag.size FROM `" . DB_PREFIX . "googleshopping_product` pag LEFT JOIN `" . DB_PREFIX . "product` p ON (p.product_id = pag.product_id) LEFT JOIN `" . DB_PREFIX . "product_to_store` p2s ON (p2s.product_id = p.product_id AND p2s.store_id=" . (int)$this->store_id . ") WHERE p2s.store_id IS NOT NULL AND p.status = 1 AND p.date_available <= NOW() AND p.price > 0 ORDER BY p.product_id ASC LIMIT " . (int)(($page - 1) * $this->config->get('advertise_google_report_limit')) . ', ' . (int)$this->config->get('advertise_google_report_limit'); - - $result = array(); - - $this->load->model('localisation/language'); - - foreach ($this->db->query($sql)->rows as $row) { - foreach ($this->model_localisation_language->getLanguages() as $language) { - $groups = $this->getGroups($row['product_id'], $language['language_id'], $row['color'], $row['size']); - - foreach (array_keys($groups) as $id) { - if (!in_array($id, $result)) { - $result[] = $id; - } - } - } - } - - return !empty($result) ? $result : null; - } - - // A copy of the OpenCart SEO URL rewrite method. - public function rewrite($link) { - $url_info = parse_url(str_replace('&', '&', $link)); - - $url = ''; - - $data = array(); - - parse_str($url_info['query'], $data); - - foreach ($data as $key => $value) { - if (isset($data['route'])) { - if (($data['route'] == 'product/product' && $key == 'product_id') || (($data['route'] == 'product/manufacturer/info' || $data['route'] == 'product/product') && $key == 'manufacturer_id') || ($data['route'] == 'information/information' && $key == 'information_id')) { - $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE `query` = '" . $this->db->escape($key . '=' . (int)$value) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'"); - - if ($query->num_rows && $query->row['keyword']) { - $url .= '/' . $query->row['keyword']; - - unset($data[$key]); - } - } elseif ($key == 'path') { - $categories = explode('_', $value); - - foreach ($categories as $category) { - $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE `query` = 'category_id=" . (int)$category . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'"); - - if ($query->num_rows && $query->row['keyword']) { - $url .= '/' . $query->row['keyword']; - } else { - $url = ''; - - break; - } - } - - unset($data[$key]); - } - } - } - - if ($url) { - unset($data['route']); - - $query = ''; - - if ($data) { - foreach ($data as $key => $value) { - $query .= '&' . rawurlencode((string)$key) . '=' . rawurlencode((is_array($value) ? http_build_query($value) : (string)$value)); - } - - if ($query) { - $query = '?' . str_replace('&', '&', trim($query, '&')); - } - } - - return $url_info['scheme'] . '://' . $url_info['host'] . (isset($url_info['port']) ? ':' . $url_info['port'] : '') . str_replace('/index.php', '', $url_info['path']) . $url . $query; - } else { - return $link; - } - } - - protected function convertedTaxedPrice($value, $tax_class_id, $currency) { - return number_format($this->currency->convert($this->tax->calculate($value, $tax_class_id, $this->config->get('config_tax')), $this->config->get('config_currency'), $currency), 2, '.', ''); - } - - protected function getFeedProducts($page, $language_id, $currency) { - $sql = $this->getFeedProductsQuery($page, $language_id); - - $result = array(); - - $this->setRuntimeExceptionErrorHandler(); - - foreach ($this->db->query($sql)->rows as $row) { - try { - if (!empty($row['image']) && is_file(DIR_IMAGE . $row['image']) && is_readable(DIR_IMAGE . $row['image'])) { - $image = $this->resize($row['image'], 250, 250); - } else { - throw new \RuntimeException("Image does not exist or cannot be read."); - } - } catch (\RuntimeException $e) { - $this->output(sprintf("Error for product %s: %s", $row['model'], $e->getMessage())); - - $image = $this->resize('no_image.png', 250, 250); - } - - $url = new \Url($this->store_url, $this->store_url); - - if ($this->config->get('config_seo_url')) { - $url->addRewrite($this); - } - - $price = $this->convertedTaxedPrice($row['price'], $row['tax_class_id'], $currency); - - $special_price = null; - - if ($row['special_price'] !== null) { - $parts = explode('<[S]>', $row['special_price']); - - $special_price = array( - 'value' => $this->convertedTaxedPrice($parts[0], $row['tax_class_id'], $currency), - 'currency' => $currency - ); - - if ($parts[1] >= '1970-01-01') { - $special_price['start'] = $parts[1]; - } - - if ($parts[2] >= '1970-01-01') { - $special_price['end'] = $parts[2]; - } - } - - $campaigns = array(); - $custom_label_0 = ''; - $custom_label_1 = ''; - $custom_label_2 = ''; - $custom_label_3 = ''; - $custom_label_4 = ''; - - if (!empty($row['campaign_names'])) { - $campaigns = explode('<[S]>', $row['campaign_names']); - $i = 0; - - do { - ${'custom_label_' . ($i++)} = trim(strtolower(array_pop($campaigns))); - } while (!empty($campaigns)); - } - - $mpn = !empty($row['mpn']) ? $row['mpn'] : ''; - - if (!empty($row['upc'])) { - $gtin = $row['upc']; - } else if (!empty($row['ean'])) { - $gtin = $row['ean']; - } else if (!empty($row['jan'])) { - $gtin = $row['jan']; - } else if (!empty($row['isbn'])) { - $gtin = $row['isbn']; - } else { - $gtin = ''; - } - - $base_row = array( - 'adult' => !empty($row['adult']) ? 'yes' : 'no', - 'age_group' => !empty($row['age_group']) ? $row['age_group'] : '', - 'availability' => (int)$row['quantity'] > 0 && !$this->config->get('config_maintenance') ? 'in stock' : 'out of stock', - 'brand' => $this->sanitizeText($row['brand'], 70), - 'color' => '', - 'condition' => !empty($row['condition']) ? $row['condition'] : '', - 'custom_label_0' => $this->sanitizeText($custom_label_0, 100), - 'custom_label_1' => $this->sanitizeText($custom_label_1, 100), - 'custom_label_2' => $this->sanitizeText($custom_label_2, 100), - 'custom_label_3' => $this->sanitizeText($custom_label_3, 100), - 'custom_label_4' => $this->sanitizeText($custom_label_4, 100), - 'description' => $this->sanitizeText($row['description'], 5000), - 'gender' => !empty($row['gender']) ? $row['gender'] : '', - 'google_product_category' => !empty($row['google_product_category']) ? $row['google_product_category'] : '', - 'id' => $this->sanitizeText($row['product_id'], 50), - 'identifier_exists' => !empty($row['brand']) && !empty($mpn) ? 'yes' : 'no', - 'image_link' => $this->sanitizeText($image, 2000), - 'is_bundle' => !empty($row['is_bundle']) ? 'yes' : 'no', - 'item_group_id' => $this->sanitizeText($row['product_id'], 50), - 'link' => $this->sanitizeText(html_entity_decode($url->link('product/product', 'product_id=' . $row['product_id'], true), ENT_QUOTES, 'UTF-8'), 2000), - 'mpn' => $this->sanitizeText($mpn, 70), - 'gtin' => $this->sanitizeText($gtin, 14), - 'multipack' => !empty($row['multipack']) && (int)$row['multipack'] >= 2 ? (int)$row['multipack'] : '', // Cannot be 1!!! - 'price' => array( - 'value' => $price, - 'currency' => $currency - ), - 'size' => '', - 'size_system' => !empty($row['size_system']) ? $row['size_system'] : '', - 'size_type' => !empty($row['size_type']) ? $row['size_type'] : '', - 'title' => $this->sanitizeText($row['name'], 150) - ); - - // Provide optional special price - if ($special_price !== null) { - $base_row['special_price'] = $special_price; - } - - $groups = $this->getGroups($row['product_id'], $language_id, $row['color'], $row['size']); - - foreach ($groups as $id => $group) { - $base_row['id'] = $id; - $base_row['color'] = $this->sanitizeText($group['color'], 40); - $base_row['size'] = $this->sanitizeText($group['size'], 100); - - $result[] = $base_row; - } - } - - $this->restoreErrorHandler(); - - return !empty($result) ? $result : null; - } - - public function getGroups($product_id, $language_id, $color_id, $size_id) { - $options = array( - 'color' => $this->getProductOptionValueNames($product_id, $language_id, $color_id), - 'size' => $this->getProductOptionValueNames($product_id, $language_id, $size_id) - ); - - $result = array(); - - foreach ($this->combineOptions($options) as $group) { - $key = $product_id . '-' . md5(json_encode(array('color' => $group['color'], 'size' => $group['size']))); - - $result[$key] = $group; - } - - return $result; - } - - public function getProductOptionValueNames($product_id, $language_id, $option_id) { - $sql = "SELECT DISTINCT pov.product_option_value_id, ovd.name FROM `" . DB_PREFIX . "product_option_value` pov LEFT JOIN `" . DB_PREFIX . "option_value_description` ovd ON (ovd.option_value_id = pov.option_value_id) WHERE pov.product_id=" . (int)$product_id . " AND pov.option_id=" . (int)$option_id . " AND ovd.language_id=" . (int)$language_id; - - $result = $this->db->query($sql); - - if ($result->num_rows > 0) { - $return = array(); - - foreach ($result->rows as $row) { - $text = $this->sanitizeText($row['name'], 100); - $name = implode('/', array_slice(array_filter(array_map('trim', preg_split('~[,/;]+~i', $text))), 0, 3)); - - $return[$row['product_option_value_id']] = $name; - } - - return $return; - } - - return array(''); - } - - public function applyFilter(&$sql, &$data) { - if (!empty($data['filter_product_name'])) { - $sql .= " AND pd.name LIKE '" . $this->db->escape($data['filter_product_name']) . "%'"; - } - - if (!empty($data['filter_product_model'])) { - $sql .= " AND p.model LIKE '" . $this->db->escape($data['filter_product_model']) . "%'"; - } - - if (!empty($data['filter_category_id'])) { - $sql .= " AND p.product_id IN (SELECT p2c_t.product_id FROM `" . DB_PREFIX . "category_path` cp_t LEFT JOIN `" . DB_PREFIX . "product_to_category` p2c_t ON (p2c_t.category_id=cp_t.category_id) WHERE cp_t.path_id=" . (int)$data['filter_category_id'] . ")"; - } - - if (isset($data['filter_is_modified']) && $data['filter_is_modified'] !== "") { - $sql .= " AND p.product_id IN (SELECT pag_t.product_id FROM `" . DB_PREFIX . "googleshopping_product` pag_t WHERE pag_t.is_modified=" . (int)$data['filter_is_modified'] . ")"; - } - - if (!empty($data['filter_store_id'])) { - $sql .= " AND p.product_id IN (SELECT p2s_t.product_id FROM `" . DB_PREFIX . "product_to_store` p2s_t WHERE p2s_t.store_id=" . (int)$data['filter_store_id'] . ")"; - } - } - - public function getProducts($data, $store_id) { - $sql = "SELECT pag.*, p.product_id, p.image, pd.name, p.model FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (p.product_id = pd.product_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_product` pag ON (pag.product_id = p.product_id AND pag.store_id = " . (int)$store_id . ") WHERE pag.store_id IS NOT NULL AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "'"; - - $this->applyFilter($sql, $data); - - $sql .= " GROUP BY p.product_id"; - - $sort_data = array( - 'name', - 'model', - 'impressions', - 'clicks', - 'cost', - 'conversions', - 'conversion_value', - 'has_issues', - 'destination_status' - ); - - if (isset($data['sort']) && in_array($data['sort'], $sort_data)) { - $sql .= " ORDER BY " . $data['sort']; - } else { - $sql .= " ORDER BY name"; - } - - if (isset($data['order']) && ($data['order'] == 'DESC')) { - $sql .= " DESC"; - } else { - $sql .= " ASC"; - } - - if (isset($data['start']) || isset($data['limit'])) { - if ($data['start'] < 0) { - $data['start'] = 0; - } - - if ($data['limit'] < 1) { - $data['limit'] = 20; - } - - $sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit']; - } - - return $this->db->query($sql)->rows; - } - - public function getTotalProducts($data, $store_id) { - $sql = "SELECT COUNT(*) as total FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (p.product_id = pd.product_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_product` pag ON (pag.product_id = p.product_id AND pag.store_id = " . (int)$store_id . ") WHERE pag.store_id IS NOT NULL AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "'"; - - $this->applyFilter($sql, $data); - - return (int)$this->db->query($sql)->row['total']; - } - - public function getProductIds($data, $store_id) { - $result = array(); - - $this->load->model('localisation/language'); - - foreach ($this->getProducts($data, $store_id) as $row) { - $product_id = (int)$row['product_id']; - - if (!in_array($product_id, $result)) { - $result[] = $product_id; - } - } - - return $result; - } - - public function clearProductStatuses($product_ids, $store_id) { - $sql = "UPDATE `" . DB_PREFIX . "googleshopping_product_status` SET `destination_statuses`='', `data_quality_issues`='', `item_level_issues`='', `google_expiration_date`=0 WHERE `product_id` IN (" . $this->productIdsToIntegerExpression($product_ids) . ") AND `store_id`=" . (int)$store_id; - - $this->db->query($sql); - - $sql = "UPDATE `" . DB_PREFIX . "googleshopping_product` SET `has_issues`=0, `destination_status`='pending' WHERE `product_id` IN (" . $this->productIdsToIntegerExpression($product_ids) . ") AND `store_id`=" . (int)$store_id; - - $this->db->query($sql); - } - - public function productIdsToIntegerExpression($product_ids) { - return implode(",", array_map(array($this, 'integer'), $product_ids)); - } - - public function integer(&$product_id) { - if (!is_numeric($product_id)) { - return 0; - } else { - return (int)$product_id; - } - } - - public function cron() { - $this->enableErrorReporting(); - - $this->load->config('googleshopping/googleshopping'); - - $report = array(); - - $report[] = $this->output("Starting CRON task for " . $this->getStoreUrl()); - - try { - $report[] = $this->output("Refreshing access token."); - - $this->isConnected(); - } catch (\RuntimeException $e) { - $report[] = $this->output($e->getMessage()); - } - - $default_config_tax = $this->config->get("config_tax"); - $default_config_store_id = $this->config->get("config_store_id"); - $default_config_language_id = $this->config->get("config_language_id"); - $default_config_seo_url = $this->config->get("config_seo_url"); - - // Do product feed uploads - foreach ($this->getJobs() as $job) { - try { - $report[] = $this->output("Uploading product feed. Work ID: " . $job['work_id']); - - // Set the tax context for the job - if (in_array("US", $job['countries'])) { - // In case the feed is for the US, disable taxes because they are already configured on the merchant level by the extension - $this->config->set("config_tax", 0); - } - - // Set the store and language context for the job - $this->config->set("config_store_id", $this->store_id); - $this->config->set("config_language_id", $job['language_id']); - $this->config->set("config_seo_url", $this->model_setting_setting->getSettingValue("config_seo_url", $this->store_id)); - - // Do the CRON job - $count = $this->doJob($job); - - // Reset the taxes, store, and language to their original state - $this->config->set("config_tax", $default_config_tax); - $this->config->set("config_store_id", $default_config_store_id); - $this->config->set("config_language_id", $default_config_language_id); - $this->config->set("config_seo_url", $default_config_seo_url); - - $report[] = $this->output("Uploaded count: " . $count); - } catch (\RuntimeException $e) { - $report[] = $this->output($e->getMessage()); - } - } - - // Reset the taxes, store, and language to their original state - $this->config->set("config_tax", $default_config_tax); - $this->config->set("config_store_id", $default_config_store_id); - $this->config->set("config_language_id", $default_config_language_id); - $this->config->set("config_seo_url", $default_config_seo_url); - - // Pull product reports - $report[] = $this->output("Fetching product reports."); - - try { - $report_count = 0; - - $page = 0; - - $this->clearReports(); - - while (null !== $product_variation_ids = $this->getProductVariationIds(++$page)) { - foreach (array_chunk($product_variation_ids, (int)$this->config->get('advertise_google_report_limit')) as $chunk) { - $product_reports = $this->getProductReports($chunk); - - if (!empty($product_reports)) { - $this->updateProductReports($product_reports, $this->store_id); - $report_count += count($product_reports); - } - } - } - } catch (\RuntimeException $e) { - $report[] = $this->output($e->getMessage()); - } - - $report[] = $this->output("Fetched report count: " . $report_count); - - // Pull product statuses - $report[] = $this->output("Fetching product statuses."); - - $page = 1; - $status_count = 0; - - do { - $filter_data = array( - 'start' => ($page - 1) * $this->config->get('advertise_google_product_status_limit'), - 'limit' => $this->config->get('advertise_google_product_status_limit') - ); - - $page++; - - $product_variation_target_specific_ids = $this->getProductVariationTargetSpecificIds($filter_data); - - try { - // Fetch latest statuses from the API - if (!empty($product_variation_target_specific_ids)) { - $product_ids = $this->getProductIds($filter_data, $this->store_id); - - $this->clearProductStatuses($product_ids, $this->store_id); - - foreach (array_chunk($product_variation_target_specific_ids, (int)$this->config->get('advertise_google_product_status_limit')) as $chunk) { - $product_statuses = $this->getProductStatuses($chunk); - - if (!empty($product_statuses)) { - $this->updateProductStatuses($product_statuses); - $status_count += count($product_statuses); - } - } - } - } catch (\RuntimeException $e) { - $report[] = $this->output($e->getMessage()); - } - } while (!empty($product_variation_target_specific_ids)); - - $report[] = $this->output("Fetched status count: " . $status_count); - - $report[] = $this->output("CRON finished!"); - - $this->applyNewSetting('advertise_google_cron_last_executed', time()); - - $this->sendEmailReport($report); - } - - public function getProductVariationTargetSpecificIds($data) { - $result = array(); - - $targets = $this->getTargets($this->store_id); - - foreach ($this->getProducts($data, $this->store_id) as $row) { - foreach ($targets as $target) { - foreach ($target['feeds'] as $feed) { - $language_code = $feed['language']; - - $language_id = $this->getSupportedLanguageId($language_code); - - $groups = $this->getGroups($row['product_id'], $language_id, $row['color'], $row['size']); - - foreach (array_keys($groups) as $id) { - $id_parts = array(); - $id_parts[] = 'online'; - $id_parts[] = $language_code; - $id_parts[] = $target['country']['code']; - $id_parts[] = $id; - - $result_id = implode(':', $id_parts); - - if (!in_array($result_id, $result)) { - $result[] = $result_id; - } - } - } - } - } - - return $result; - } - - public function updateProductReports($reports) { - $values = array(); - - foreach ($reports as $report) { - $entry = array(); - $entry['product_id'] = $this->getProductIdFromOfferId($report['offer_id']); - $entry['store_id'] = (int)$this->store_id; - $entry['impressions'] = (int)$report['impressions']; - $entry['clicks'] = (int)$report['clicks']; - $entry['conversions'] = (int)$report['conversions']; - $entry['cost'] = ((int)$report['cost']) / self::MICROAMOUNT; - $entry['conversion_value'] = (float)$report['conversion_value']; - - $values[] = "(" . implode(",", $entry) . ")"; - } - - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `impressions`, `clicks`, `conversions`, `cost`, `conversion_value`) VALUES " . implode(',', $values) . " ON DUPLICATE KEY UPDATE `impressions`=`impressions` + VALUES(`impressions`), `clicks`=`clicks` + VALUES(`clicks`), `conversions`=`conversions` + VALUES(`conversions`), `cost`=`cost` + VALUES(`cost`), `conversion_value`=`conversion_value` + VALUES(`conversion_value`)"; - - $this->db->query($sql); - } - - public function updateProductStatuses($statuses) { - $product_advertise_google = array(); - $product_advertise_google_status = array(); - $product_level_entries = array(); - $entry_statuses = array(); - - foreach ($statuses as $status) { - $product_id = $this->getProductIdFromTargetSpecificId($status['productId']); - $product_variation_id = $this->getProductVariationIdFromTargetSpecificId($status['productId']); - - if (!isset($product_level_entries[$product_id])) { - $product_level_entries[$product_id] = array( - 'product_id' => (int)$product_id, - 'store_id' => (int)$this->store_id, - 'has_issues' => 0, - 'destination_status' => 'pending' - ); - } - - foreach ($status['destinationStatuses'] as $destination_status) { - if (!$destination_status['approvalPending']) { - switch ($destination_status['approvalStatus']) { - case 'approved' : - if ($product_level_entries[$product_id]['destination_status'] == 'pending') { - $product_level_entries[$product_id]['destination_status'] = 'approved'; - } - break; - case 'disapproved' : - $product_level_entries[$product_id]['destination_status'] = 'disapproved'; - break; - } - } - } - - if (!$product_level_entries[$product_id]['has_issues']) { - if (!empty($status['dataQualityIssues']) || !empty($status['itemLevelIssues'])) { - $product_level_entries[$product_id]['has_issues'] = 1; - } - } - - if (!isset($entry_statuses[$product_variation_id])) { - $entry_statuses[$product_variation_id] = array(); - - $entry_statuses[$product_variation_id]['product_id'] = (int)$product_id; - $entry_statuses[$product_variation_id]['store_id'] = (int)$this->store_id; - $entry_statuses[$product_variation_id]['product_variation_id'] = "'" . $this->db->escape($product_variation_id) . "'"; - $entry_statuses[$product_variation_id]['destination_statuses'] = array(); - $entry_statuses[$product_variation_id]['data_quality_issues'] = array(); - $entry_statuses[$product_variation_id]['item_level_issues'] = array(); - $entry_statuses[$product_variation_id]['google_expiration_date'] = (int)strtotime($status['googleExpirationDate']); - } - - $entry_statuses[$product_variation_id]['destination_statuses'] = array_merge( - $entry_statuses[$product_variation_id]['destination_statuses'], - !empty($status['destinationStatuses']) ? $status['destinationStatuses'] : array() - ); - - $entry_statuses[$product_variation_id]['data_quality_issues'] = array_merge( - $entry_statuses[$product_variation_id]['data_quality_issues'], - !empty($status['dataQualityIssues']) ? $status['dataQualityIssues'] : array() - ); - - $entry_statuses[$product_variation_id]['item_level_issues'] = array_merge( - $entry_statuses[$product_variation_id]['item_level_issues'], - !empty($status['itemLevelIssues']) ? $status['itemLevelIssues'] : array() - ); - } - - foreach ($entry_statuses as &$entry_status) { - $entry_status['destination_statuses'] = "'" . $this->db->escape(json_encode($entry_status['destination_statuses'])) . "'"; - $entry_status['data_quality_issues'] = "'" . $this->db->escape(json_encode($entry_status['data_quality_issues'])) . "'"; - $entry_status['item_level_issues'] = "'" . $this->db->escape(json_encode($entry_status['item_level_issues'])) . "'"; - - $product_advertise_google_status[] = "(" . implode(",", $entry_status) . ")"; - } - - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product_status` (`product_id`, `store_id`, `product_variation_id`, `destination_statuses`, `data_quality_issues`, `item_level_issues`, `google_expiration_date`) VALUES " . implode(',', $product_advertise_google_status) . " ON DUPLICATE KEY UPDATE `destination_statuses`=VALUES(`destination_statuses`), `data_quality_issues`=VALUES(`data_quality_issues`), `item_level_issues`=VALUES(`item_level_issues`), `google_expiration_date`=VALUES(`google_expiration_date`)"; - - $this->db->query($sql); - - foreach ($product_level_entries as $entry) { - $entry['destination_status'] = "'" . $this->db->escape($entry['destination_status']) . "'"; - - $product_advertise_google[] = "(" . implode(",", $entry) . ")"; - } - - $sql = "INSERT INTO `" . DB_PREFIX . "googleshopping_product` (`product_id`, `store_id`, `has_issues`, `destination_status`) VALUES " . implode(',', $product_advertise_google) . " ON DUPLICATE KEY UPDATE `has_issues`=VALUES(`has_issues`), `destination_status`=VALUES(`destination_status`)"; - - $this->db->query($sql); - } - - protected function memoryLimitInBytes() { - $memory_limit = ini_get('memory_limit'); - - if (preg_match('/^(\d+)(.)$/', $memory_limit, $matches)) { - if ($matches[2] == 'G') { - $memory_limit = (int)$matches[1] * 1024 * 1024 * 1024; // nnnG -> nnn GB - } else if ($matches[2] == 'M') { - $memory_limit = (int)$matches[1] * 1024 * 1024; // nnnM -> nnn MB - } else if ($matches[2] == 'K') { - $memory_limit = (int)$matches[1] * 1024; // nnnK -> nnn KB - } - } - - return (int)$memory_limit; - } - - protected function enableErrorReporting() { - ini_set('display_errors', 1); - ini_set('display_startup_errors', 1); - error_reporting(E_ALL); - } - - protected function getProductIdFromTargetSpecificId($target_specific_id) { - return (int)preg_replace('/^online:[a-z]{2}:[A-Z]{2}:(\d+)-[a-f0-9]{32}$/', '$1', $target_specific_id); - } - - protected function getProductVariationIdFromTargetSpecificId($target_specific_id) { - return preg_replace('/^online:[a-z]{2}:[A-Z]{2}:(\d+-[a-f0-9]{32})$/', '$1', $target_specific_id); - } - - protected function getProductIdFromOfferId($offer_id) { - return (int)preg_replace('/^(\d+)-[a-f0-9]{32}$/', '$1', $offer_id); - } - - protected function clearReports() { - $sql = "UPDATE `" . DB_PREFIX . "googleshopping_product` SET `impressions`=0, `clicks`=0, `conversions`=0, `cost`=0.0000, `conversion_value`=0.0000 WHERE `store_id`=" . (int)$this->store_id; - - $this->db->query($sql); - } - - protected function getJobs() { - $jobs = array(); - - if ($this->setting->has('advertise_google_work') && is_array($this->setting->get('advertise_google_work'))) { - $this->load->model('extension/advertise/google'); - - foreach ($this->setting->get('advertise_google_work') as $work) { - $supported_language_id = $this->getSupportedLanguageId($work['language']); - $supported_currency_id = $this->getSupportedCurrencyId($work['currency']); - - if (!empty($supported_language_id) && !empty($supported_currency_id)) { - $currency_info = $this->getCurrency($supported_currency_id); - - $jobs[] = array( - 'work_id' => $work['work_id'], - 'countries' => isset($work['countries']) && is_array($work['countries']) ? $work['countries'] : array(), - 'language_id' => $supported_language_id, - 'currency' => $currency_info['code'] - ); - } - } - } - - return $jobs; - } - - protected function output($message) { - $log_message = date('Y-m-d H:i:s - ') . $message; - - if (defined('STDOUT')) { - fwrite(STDOUT, $log_message . PHP_EOL); - } else { - echo $log_message . '

'; - } - - return $log_message; - } - - protected function sendEmailReport(&$report) { - if (!$this->setting->get('advertise_google_cron_email_status')) { - return; //Do nothing - } - - $this->load->language('extension/advertise/google'); - - $subject = $this->language->get('text_cron_email_subject'); - $message = sprintf($this->language->get('text_cron_email_message'), implode('
', $report)); - - $mail = new \Mail(); - - $mail->protocol = $this->config->get('config_mail_protocol'); - $mail->parameter = $this->config->get('config_mail_parameter'); - - $mail->smtp_hostname = $this->config->get('config_mail_smtp_hostname'); - $mail->smtp_username = $this->config->get('config_mail_smtp_username'); - $mail->smtp_password = html_entity_decode($this->config->get('config_mail_smtp_password'), ENT_QUOTES, "UTF-8"); - $mail->smtp_port = $this->config->get('config_mail_smtp_port'); - $mail->smtp_timeout = $this->config->get('config_mail_smtp_timeout'); - - $mail->setTo($this->setting->get('advertise_google_cron_email')); - $mail->setFrom($this->config->get('config_email')); - $mail->setSender($this->config->get('config_name')); - $mail->setSubject(html_entity_decode($subject, ENT_QUOTES, "UTF-8")); - $mail->setText(strip_tags($message)); - $mail->setHtml($message); - - $mail->send(); - } - - protected function getOptionValueName($row) { - $text = $this->sanitizeText($row['name'], 100); - - return implode('/', array_slice(array_filter(array_map('trim', preg_split('~[,/;]+~i', $text))), 0, 3)); - } - - protected function combineOptions($arrays) { - // Based on: https://gist.github.com/cecilemuller/4688876 - $result = array(array()); - - foreach ($arrays as $property => $property_values) { - $tmp = array(); - foreach ($result as $result_item) { - foreach ($property_values as $property_value) { - $tmp[] = array_merge($result_item, array($property => $property_value)); - } - } - $result = $tmp; - } - - return $result; - } - - protected function resize($filename, $width, $height) { - if (!is_file(DIR_IMAGE . $filename) || substr(str_replace('\\', '/', realpath(DIR_IMAGE . $filename)), 0, strlen(DIR_IMAGE)) != str_replace('\\', '/', DIR_IMAGE)) { - throw new \RuntimeException("Invalid image filename: " . DIR_IMAGE . $filename); - } - - $extension = pathinfo($filename, PATHINFO_EXTENSION); - - $image_old = $filename; - $image_new = 'cache/' . utf8_substr($filename, 0, utf8_strrpos($filename, '.')) . '-' . (int)$width . 'x' . (int)$height . '.' . $extension; - - if (!is_file(DIR_IMAGE . $image_new) || (filemtime(DIR_IMAGE . $image_old) > filemtime(DIR_IMAGE . $image_new))) { - list($width_orig, $height_orig, $image_type) = getimagesize(DIR_IMAGE . $image_old); - - if ($width_orig * $height_orig * 4 > $this->memoryLimitInBytes() * 0.4) { - throw new \RuntimeException("Image too large, skipping: " . $image_old); - } - - if (!in_array($image_type, array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF))) { - throw new \RuntimeException("Unexpected image type, skipping: " . $image_old); - } - - $path = ''; - - $directories = explode('/', dirname($image_new)); - - foreach ($directories as $directory) { - $path = $path . '/' . $directory; - - if (!is_dir(DIR_IMAGE . $path)) { - @mkdir(DIR_IMAGE . $path, 0777); - } - } - - if ($width_orig != $width || $height_orig != $height) { - $image = new \Image(DIR_IMAGE . $image_old); - $image->resize($width, $height); - $image->save(DIR_IMAGE . $image_new); - } else { - copy(DIR_IMAGE . $image_old, DIR_IMAGE . $image_new); - } - } - - $image_new = str_replace(array(' ', ','), array('%20', '%2C'), $image_new); // fix bug when attach image on email (gmail.com). it is automatic changing space " " to + - - return $this->store_url . 'image/' . $image_new; - } - - protected function sanitizeText($text, $limit) { - return utf8_substr( - trim( - preg_replace( - '~\s+~', - ' ', - strip_tags( - html_entity_decode(htmlspecialchars_decode($text, ENT_QUOTES), ENT_QUOTES, 'UTF-8') - ) - ) - ), - 0, - $limit - ); - } - - protected function setRuntimeExceptionErrorHandler() { - set_error_handler(function($code, $message, $file, $line) { - if (error_reporting() === 0) { - return false; - } - - switch ($code) { - case E_NOTICE: - case E_USER_NOTICE: - $error = 'Notice'; - break; - case E_WARNING: - case E_USER_WARNING: - $error = 'Warning'; - break; - case E_ERROR: - case E_USER_ERROR: - $error = 'Fatal Error'; - break; - default: - $error = 'Unknown'; - break; - } - - $message = 'PHP ' . $error . ': ' . $message . ' in ' . $file . ' on line ' . $line; - - throw new \RuntimeException($message); - }); - } - - protected function restoreErrorHandler() { - restore_error_handler(); - } - - protected function getFeedProductsQuery($page, $language_id) { - $this->load->config('googleshopping/googleshopping'); - - $sql = "SELECT p.product_id, pd.name, pd.description, p.image, p.quantity, p.price, p.mpn, p.ean, p.jan, p.isbn, p.upc, p.model, p.tax_class_id, IFNULL((SELECT m.name FROM `" . DB_PREFIX . "manufacturer` m WHERE m.manufacturer_id = p.manufacturer_id), '') as brand, (SELECT GROUP_CONCAT(agt.campaign_name SEPARATOR '<[S]>') FROM `" . DB_PREFIX . "googleshopping_product_target` pagt LEFT JOIN `" . DB_PREFIX . "googleshopping_target` agt ON (agt.advertise_google_target_id = pagt.advertise_google_target_id) WHERE pagt.product_id = p.product_id AND pagt.store_id = p2s.store_id GROUP BY pagt.product_id) as campaign_names, (SELECT CONCAT_WS('<[S]>', ps.price, ps.date_start, ps.date_end) FROM `" . DB_PREFIX . "product_special` ps WHERE ps.product_id=p.product_id AND ps.customer_group_id=" . (int)$this->config->get('config_customer_group_id') . " AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) as special_price, pag.google_product_category, pag.condition, pag.adult, pag.multipack, pag.is_bundle, pag.age_group, pag.color, pag.gender, pag.size_type, pag.size_system, pag.size FROM `" . DB_PREFIX . "product` p LEFT JOIN `" . DB_PREFIX . "product_to_store` p2s ON (p2s.product_id = p.product_id AND p2s.store_id=" . (int)$this->store_id . ") LEFT JOIN `" . DB_PREFIX . "product_description` pd ON (pd.product_id = p.product_id) LEFT JOIN `" . DB_PREFIX . "googleshopping_product` pag ON (pag.product_id = p.product_id AND pag.store_id = p2s.store_id) WHERE p2s.store_id IS NOT NULL AND pd.language_id=" . (int)$language_id . " AND pd.name != '' AND pd.description != '' AND pd.name IS NOT NULL AND pd.description IS NOT NULL AND p.image != '' AND p.status = 1 AND p.date_available <= NOW() AND p.price > 0 ORDER BY p.product_id ASC LIMIT " . (int)(($page - 1) * $this->config->get('advertise_google_push_limit')) . ', ' . (int)$this->config->get('advertise_google_push_limit'); - - return $sql; - } - - public function setEventSnippet($snippet) { - $this->event_snippet = $snippet; - } - - public function getEventSnippet() { - return $this->event_snippet; - } - - public function getEventSnippetSendTo() { - $tracker = $this->setting->get('advertise_google_conversion_tracker'); - - if (!empty($tracker['google_event_snippet'])) { - $matches = array(); - - preg_match('~send_to\': \'([a-zA-Z0-9-]*).*\'~', $tracker['google_event_snippet'], $matches); - - return $matches[1]; - } - - return null; - } - - public function setPurchaseData($total) { - $this->purchase_data = $total; - } - - public function getPurchaseData() { - return $this->purchase_data; - } - - public function convertAndFormat($price, $currency) { - $currency_converter = new \Cart\Currency($this->registry); - $converted_price = $currency_converter->convert((float)$price, $this->config->get('config_currency'), $currency); - return (float)number_format($converted_price, 2, '.', ''); - } - - public function getMerchantAuthUrl($data) { - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_MERCHANT_AUTH_URL, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $data - ); - - $response = $this->api($request); - - return $response['url']; - } - - public function isConnected() { - $settings_exist = - $this->setting->has('advertise_google_access_token') && - $this->setting->has('advertise_google_refresh_token') && - $this->setting->has('advertise_google_app_id') && - $this->setting->has('advertise_google_app_secret'); - - if ($settings_exist) { - if ($this->testAccessToken() || $this->getAccessToken()) { - return true; - } - } - - throw new ConnectionException("Access unavailable. Please re-connect."); - } - - public function isStoreUrlClaimed() { - // No need to check the connection here - this method is called immediately after checking it - - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_VERIFY_IS_CLAIMED, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => array( - 'url_website' => $this->store_url - ) - ); - - $response = $this->api($request); - - return $response['is_claimed']; - } - - public function currencyFormat($value) { - return '$' . number_format($value, 2, '.', ','); - } - - public function getCampaignReports() { - $targets = array(); - $statuses = array(); - - foreach ($this->getTargets($this->store_id) as $target) { - $targets[] = $target['campaign_name']; - $statuses[$target['campaign_name']] = $target['status']; - } - $targets[] = 'Total'; - - $cache = new \Cache($this->config->get('cache_engine'), self::CACHE_CAMPAIGN_REPORT); - $cache_key = 'advertise_google.' . $this->store_id . '.campaign_reports.' . md5(json_encode(array_keys($statuses)) . $this->setting->get('advertise_google_reporting_interval')); - - $cache_result = $cache->get($cache_key); - - if (empty($cache_result['result']) || (isset($cache_result['timestamp']) && $cache_result['timestamp'] >= time() + self::CACHE_CAMPAIGN_REPORT)) { - $request = array( - 'endpoint' => sprintf(self::ENDPOINT_REPORT_CAMPAIGN, $this->setting->get('advertise_google_reporting_interval')), - 'use_access_token' => true - ); - - $csv = $this->api($request); - - $lines = explode("\n", trim($csv['campaign_report'])); - - $result = array( - 'date_range' => null, - 'reports' => array() - ); - - // Get date range - $matches = array(); - preg_match('~CAMPAIGN_PERFORMANCE_REPORT \((.*?)\)~', $lines[0], $matches); - $result['date_range'] = $matches[1]; - - $header = explode(',', $lines[1]); - $data = array(); - $total = array(); - $value_keys = array(); - - $campaign_keys = array_flip($targets); - - $expected = array( - 'Campaign' => 'campaign_name', - 'Impressions' => 'impressions', - 'Clicks' => 'clicks', - 'Cost' => 'cost', - 'Conversions' => 'conversions', - 'Total conv. value' => 'conversion_value' - ); - - foreach ($header as $i => $title) { - if (!in_array($title, array_keys($expected))) { - continue; - } - - $value_keys[$i] = $expected[$title]; - } - - // Fill blank values - foreach ($campaign_keys as $campaign_name => $l) { - foreach ($value_keys as $i => $key) { - $result['reports'][$l][$key] = $key == 'campaign_name' ? $campaign_name : '–'; - } - } - - // Fill actual values - for ($j = 2; $j < count($lines); $j++) { - $line_items = explode(',', $lines[$j]); - $l = null; - - // Identify campaign key - foreach ($line_items as $k => $line_item_value) { - if (array_key_exists($k, $value_keys) && array_key_exists($line_item_value, $campaign_keys) && $value_keys[$k] == 'campaign_name') { - $l = $campaign_keys[$line_item_value]; - } - } - - // Fill campaign values - if (!is_null($l)) { - foreach ($line_items as $k => $line_item_value) { - if (!array_key_exists($k, $value_keys)) { - continue; - } - - if (in_array($value_keys[$k], array('cost'))) { - $line_item_value = $this->currencyFormat((float)$line_item_value / self::MICROAMOUNT); - } else if (in_array($value_keys[$k], array('conversion_value'))) { - $line_item_value = $this->currencyFormat((float)$line_item_value); - } else if ($value_keys[$k] == 'conversions') { - $line_item_value = (int)$line_item_value; - } - - $result['reports'][$l][$value_keys[$k]] = $line_item_value; - } - } - } - - $cache->set($cache_key, array( - 'timestamp' => time(), - 'result' => $result - )); - } else { - $result = $cache_result['result']; - } - - // Fill campaign statuses - foreach ($result['reports'] as &$report) { - if ($report['campaign_name'] == 'Total') { - $report['status'] = ''; - } else { - $report['status'] = $statuses[$report['campaign_name']]; - } - } - - $this->applyNewSetting('advertise_google_report_campaigns', $result); - } - - public function getProductReports($product_ids) { - $cache = new \Cache($this->config->get('cache_engine'), self::CACHE_PRODUCT_REPORT); - $cache_key = 'advertise_google.' . $this->store_id . '.product_reports.' . md5(json_encode($product_ids) . $this->setting->get('advertise_google_reporting_interval')); - - $cache_result = $cache->get($cache_key); - - if (!empty($cache_result['result']) && isset($cache_result['timestamp']) && (time() - self::CACHE_PRODUCT_REPORT <= $cache_result['timestamp'])) { - return $cache_result['result']; - } - - $post = array(); - $post_data = array( - 'product_ids' => $product_ids - ); - - $this->curlPostQuery($post_data, $post); - - $request = array( - 'type' => 'POST', - 'endpoint' => sprintf(self::ENDPOINT_REPORT_AD, $this->setting->get('advertise_google_reporting_interval')), - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $post - ); - - $response = $this->api($request); - - $result = array(); - - if (!empty($response['ad_report'])) { - $lines = explode("\n", trim($response['ad_report'])); - - $header = explode(',', $lines[1]); - $data = array(); - $keys = array(); - - $expected = array( - 'Item Id' => 'offer_id', - 'Impressions' => 'impressions', - 'Clicks' => 'clicks', - 'Cost' => 'cost', - 'Conversions' => 'conversions', - 'Total conv. value' => 'conversion_value' - ); - - foreach ($header as $i => $title) { - if (!in_array($title, array_keys($expected))) { - continue; - } - - $data[$i] = 0.0; - $keys[$i] = $expected[$title]; - } - - // We want to omit the last line because it does not include the total number of impressions for all campaigns - for ($j = 2; $j < count($lines) - 1; $j++) { - $line_items = explode(',', $lines[$j]); - - $result[$j] = array(); - - foreach ($line_items as $k => $line_item) { - if (in_array($k, array_keys($data))) { - $result[$j][$keys[$k]] = (float)$line_item; - } - } - } - } - - $cache->set($cache_key, array( - 'result' => $result, - 'timestamp' => time() - )); - - return $result; - } - - public function getProductStatuses($product_ids) { - $post_data = array( - 'product_ids' => $product_ids - ); - - $this->curlPostQuery($post_data, $post); - - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_MERCHANT_PRODUCT_STATUSES, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $post - ); - - $response = $this->api($request); - - return $response['statuses']; - } - - public function getConversionTracker() { - $request = array( - 'endpoint' => self::ENDPOINT_CONVERSION_TRACKER, - 'use_access_token' => true - ); - - $result = $this->api($request); - - // Amend the conversion snippet by replacing the default values with placeholders. - $search = array( - "'value': 0.0", - "'currency': 'USD'" - ); - - $replace = array( - "'value': {VALUE}", - "'currency': '{CURRENCY}'" - ); - - $result['conversion_tracker']['google_event_snippet'] = str_replace($search, $replace, $result['conversion_tracker']['google_event_snippet']); - - return $result['conversion_tracker']; - } - - public function testCampaigns() { - $request = array( - 'endpoint' => self::ENDPOINT_CAMPAIGN_TEST, - 'use_access_token' => true - ); - - $result = $this->api($request); - - return $result['status'] === true; - } - - public function testAccessToken() { - $request = array( - 'endpoint' => self::ENDPOINT_ACCESS_TOKEN_TEST, - 'use_access_token' => true - ); - - try { - $result = $this->api($request); - - return $result['status'] === true; - } catch (AccessForbiddenException $e) { - throw $e; - } catch (\RuntimeException $e) { - // Do nothing - } - - return false; - } - - public function getAccessToken() { - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_ACCESS_TOKEN, - 'use_access_token' => false, - 'content_type' => 'multipart/form-data', - 'data' => array( - 'grant_type' => 'refresh_token', - 'refresh_token' => $this->setting->get('advertise_google_refresh_token'), - 'client_id' => $this->setting->get('advertise_google_app_id'), - 'client_secret' => $this->setting->get('advertise_google_app_secret'), - 'scope' => self::SCOPES - ) - ); - - $access = $this->api($request); - - $this->applyNewSetting('advertise_google_access_token', $access['access_token']); - $this->applyNewSetting('advertise_google_refresh_token', $access['refresh_token']); - - return true; - } - - public function access($data, $code) { - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_ACCESS_TOKEN, - 'use_access_token' => false, - 'content_type' => 'multipart/form-data', - 'data' => array( - 'grant_type' => 'authorization_code', - 'client_id' => $data['app_id'], - 'client_secret' => $data['app_secret'], - 'redirect_uri' => $data['redirect_uri'], - 'code' => $code - ) - ); - - return $this->api($request); - } - - public function authorize($data) { - $query = array(); - - $query['response_type'] = 'code'; - $query['client_id'] = $data['app_id']; - $query['redirect_uri'] = $data['redirect_uri']; - $query['scope'] = self::SCOPES; - $query['state'] = $data['state']; - - return sprintf($this->endpoint_url, 'api/authorize/login') . '&' . http_build_query($query); - } - - public function verifySite() { - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_VERIFY_TOKEN, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => array( - 'url_website' => $this->store_url - ) - ); - - $response = $this->api($request); - - $token = $response['token']; - - $this->createVerificationToken($token); - - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_VERIFY_SITE, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => array( - 'url_website' => $this->store_url - ) - ); - - try { - $this->api($request); - - $this->deleteVerificationToken($token); - } catch (\RuntimeException $e) { - $this->deleteVerificationToken($token); - - throw $e; - } - } - - public function deleteCampaign($name) { - $post = array(); - $data = array( - 'delete' => array( - $name - ) - ); - - $this->curlPostQuery($data, $post); - - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_CAMPAIGN_DELETE, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $post - ); - - $this->api($request); - } - - public function pushTargets() { - $post = array(); - $targets = array(); - - foreach ($this->getTargets($this->store_id) as $target) { - $targets[] = array( - 'campaign_name' => $target['campaign_name_raw'], - 'country' => $target['country']['code'], - 'status' => $this->setting->get('advertise_google_status') ? $target['status'] : 'paused', - 'budget' => (float)$target['budget']['value'], - 'roas' => ((int)$target['roas']) / 100, - 'feeds' => $target['feeds_raw'] - ); - } - - $data = array( - 'target' => $targets - ); - - $this->curlPostQuery($data, $post); - - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_CAMPAIGN_UPDATE, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $post - ); - - $response = $this->api($request); - - $this->applyNewSetting('advertise_google_work', $response['work']); - } - - public function pushShippingAndTaxes() { - $post = array(); - $data = $this->setting->get('advertise_google_shipping_taxes'); - - $this->curlPostQuery($data, $post); - - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_MERCHANT_SHIPPING_TAXES, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $post - ); - - $this->api($request); - } - - public function disconnect() { - $request = array( - 'type' => 'GET', - 'endpoint' => self::ENDPOINT_MERCHANT_DISCONNECT, - 'use_access_token' => true - ); - - $this->api($request); - } - - public function pushCampaignStatus() { - $post = array(); - $targets = array(); - - foreach ($this->getTargets($this->store_id) as $target) { - $targets[] = array( - 'campaign_name' => $target['campaign_name_raw'], - 'status' => $this->setting->get('advertise_google_status') ? $target['status'] : 'paused' - ); - } - - $data = array( - 'target' => $targets - ); - - $this->curlPostQuery($data, $post); - - $request = array( - 'type' => 'POST', - 'endpoint' => self::ENDPOINT_CAMPAIGN_STATUS, - 'use_access_token' => true, - 'content_type' => 'multipart/form-data', - 'data' => $post - ); - - $this->api($request); - } - - public function getAvailableCarriers() { - $request = array( - 'type' => 'GET', - 'endpoint' => self::ENDPOINT_MERCHANT_AVAILABLE_CARRIERS, - 'use_access_token' => true - ); - - $result = $this->api($request); - - return $result['available_carriers']; - } - - public function getLanguages($language_codes) { - $this->load->config('googleshopping/googleshopping'); - - $result = array(); - - foreach ($this->config->get('advertise_google_languages') as $code => $name) { - if (in_array($code, $language_codes)) { - $supported_language_id = $this->getSupportedLanguageId($code); - - $result[] = array( - 'status' => $supported_language_id !== 0, - 'language_id' => $supported_language_id, - 'code' => $code, - 'name' => $this->getLanguageName($supported_language_id, $name) - ); - } - } - - return $result; - } - - public function getLanguageName($language_id, $default) { - $this->load->model('localisation/language'); - - $language_info = $this->model_localisation_language->getLanguage($language_id); - - if (isset($language_info['name']) && trim($language_info['name']) != "") { - return $language_info['name']; - } - - // We do not expect to get to this point, but just in case... - return $default; - } - - public function getCurrencies($currency_codes) { - $result = array(); - - $this->load->config('googleshopping/googleshopping'); - - $result = array(); - - foreach ($this->config->get('advertise_google_currencies') as $code => $name) { - if (in_array($code, $currency_codes)) { - $supported_currency_id = $this->getSupportedCurrencyId($code); - - $result[] = array( - 'status' => $supported_currency_id !== 0, - 'code' => $code, - 'name' => $this->getCurrencyName($supported_currency_id, $name) . ' (' . $code . ')' - ); - } - } - - return $result; - } - - public function getCurrencyName($currency_id, $default) { - $this->load->model('extension/advertise/google'); - - $currency_info = $this->getCurrency($currency_id); - - if (isset($currency_info['title']) && trim($currency_info['title']) != "") { - return $currency_info['title']; - } - - // We do not expect to get to this point, but just in case... - return $default; - } - - public function getCurrency($currency_id) { - $query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "currency WHERE currency_id = '" . (int)$currency_id . "'"); - - return $query->row; - } - - public function debugLog($text) { - if ($this->setting->get('advertise_google_debug_log')) { - $this->debug_log->write($text); - } - } - - protected function target($target) { - $feeds_raw = json_decode($target['feeds'], true); - - $feeds = array_map(function($feed) { - $language = current($this->getLanguages(array($feed['language']))); - $currency = current($this->getCurrencies(array($feed['currency']))); - - return array( - 'text' => $language['name'] . ', ' . $currency['name'], - 'language' => $feed['language'], - 'currency' => $feed['currency'] - ); - }, $feeds_raw); - - return array( - 'target_id' => $target['advertise_google_target_id'], - 'campaign_name' => str_replace(',', ',', trim($target['campaign_name'])), - 'campaign_name_raw' => $target['campaign_name'], - 'country' => array( - 'code' => $target['country'], - 'name' => $this->getCountryName($target['country']) - ), - 'budget' => array( - 'formatted' => sprintf($this->language->get('text_per_day'), number_format((float)$target['budget'], 2)), - 'value' => (float)$target['budget'] - ), - 'feeds' => $feeds, - 'status' => $target['status'], - 'roas' => $target['roas'], - 'roas_status' => $target['date_added'] <= date('Y-m-d', time() - self::ROAS_WAIT_INTERVAL), - 'roas_available_on' => strtotime($target['date_added']) + self::ROAS_WAIT_INTERVAL, - 'feeds_raw' => $feeds_raw - ); - } - - private function curlPostQuery($arrays, &$new = array(), $prefix = null) { - foreach ($arrays as $key => $value) { - $k = isset($prefix) ? $prefix . '[' . $key . ']' : $key; - if (is_array($value)) { - $this->curlPostQuery($value, $new, $k); - } else { - $new[$k] = $value; - } - } - } - - private function createVerificationToken($token) { - $dir = dirname(DIR_SYSTEM); - - if (!is_dir($dir) || !is_writable($dir)) { - throw new \RuntimeException("Not a directory, or no permissions to write to: " . $dir); - } - - if (!file_put_contents($dir . '/' . $token, 'google-site-verification: ' . $token)) { - throw new \RuntimeException("Could not write to: " . $dir . '/' . $token); - } - } - - private function deleteVerificationToken($token) { - $dir = dirname(DIR_SYSTEM); - - if (!is_dir($dir) || !is_writable($dir)) { - throw new \RuntimeException("Not a directory, or no permissions to write to: " . $dir); - } - - $file = $dir . '/' . $token; - - if (is_file($file) && is_writable($file)) { - @unlink($file); - } - } - - private function applyNewSetting($key, $value) { - $sql = "SELECT * FROM `" . DB_PREFIX . "setting` WHERE `code`='advertise_google' AND `key`='" . $this->db->escape($key) . "'"; - $result = $this->db->query($sql); - - if (is_array($value)) { - $encoded = json_encode($value); - $serialized = 1; - } else { - $encoded = $value; - $serialized = 0; - } - - if ($result->num_rows == 0) { - $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` SET `value`='" . $this->db->escape($encoded) . "', `code`='advertise_google', `key`='" . $this->db->escape($key) . "', serialized='" . $serialized . "', store_id='0'"); - - $this->setting->set($key, $value); - } else { - $this->db->query("UPDATE `" . DB_PREFIX . "setting` SET `value`='" . $this->db->escape($encoded) . "', serialized='" . $serialized . "' WHERE `code`='advertise_google' AND `key`='" . $this->db->escape($key) . "'"); - - $this->setting->set($key, $value); - } - } - - private function api($request) { - $this->debugLog("REQUEST: " . json_encode($request)); - - $url = sprintf($this->endpoint_url, $request['endpoint']); - - $headers = array(); - - if (isset($request['content_type'])) { - $headers[] = 'Content-Type: ' . $request['content_type']; - } else { - $headers[] = 'Content-Type: application/json'; - } - - if (!empty($request['use_access_token'])) { - $headers[] = 'Authorization: Bearer ' . $this->setting->get('advertise_google_access_token'); - } - - $curl_options = array(); - - if (isset($request['type']) && $request['type'] == 'POST') { - $curl_options[CURLOPT_POST] = true; - $curl_options[CURLOPT_POSTFIELDS] = $request['data']; - } - - $curl_options[CURLOPT_URL] = $url; - $curl_options[CURLOPT_RETURNTRANSFER] = true; - $curl_options[CURLOPT_HTTPHEADER] = $headers; - - $ch = curl_init(); - curl_setopt_array($ch, $curl_options); - $result = curl_exec($ch); - $info = curl_getinfo($ch); - curl_close($ch); - - $this->debugLog("RESPONSE: " . $result); - - if (!empty($result) && $info['http_code'] == 200) { - $return = json_decode($result, true); - - if ($return['error']) { - throw new \RuntimeException($return['message']); - } else { - return $return['result']; - } - } else if (in_array($info['http_code'], array(400, 401, 403))) { - $return = json_decode($result, true); - - if ($info['http_code'] != 401 && $return['error']) { - throw new \RuntimeException($return['message']); - } else { - throw new ConnectionException("Access unavailable. Please re-connect."); - } - } else if ($info['http_code'] == 402) { - $return = json_decode($result, true); - - if ($return['error']) { - throw new AccessForbiddenException($return['message']); - } else { - throw new ConnectionException("Access unavailable. Please re-connect."); - } - } else { - $this->debugLog("CURL ERROR! CURL INFO: " . print_r($info, true)); - - throw new \RuntimeException("A temporary error was encountered. Please try again later."); - } - } -} diff --git a/public/system/library/googleshopping/library.php b/public/system/library/googleshopping/library.php deleted file mode 100644 index a9c244e..0000000 --- a/public/system/library/googleshopping/library.php +++ /dev/null @@ -1,19 +0,0 @@ -registry = $registry; - } - - public function __get($key) { - return $this->registry->get($key); - } - - public function __set($key, $value) { - $this->registry->set($key, $value); - } -} \ No newline at end of file diff --git a/public/system/library/googleshopping/log.php b/public/system/library/googleshopping/log.php deleted file mode 100644 index 74a5281..0000000 --- a/public/system/library/googleshopping/log.php +++ /dev/null @@ -1,55 +0,0 @@ -= $max_size) { - $mode = 'wb'; - } else { - $mode = 'ab'; - } - - $this->handle = @fopen(DIR_LOGS . $filename, $mode); - } - - /** - * - * - * @param string $message - */ - public function write($message) { - if (is_resource($this->handle)) { - fwrite($this->handle, date('Y-m-d G:i:s') . ' - ' . print_r($message, true) . "\n"); - } - } - - /** - * - * - */ - public function __destruct() { - if (is_resource($this->handle)) { - fclose($this->handle); - } - } -} diff --git a/public/system/library/googleshopping/traits/libraryloader.php b/public/system/library/googleshopping/traits/libraryloader.php deleted file mode 100644 index 61bb7fa..0000000 --- a/public/system/library/googleshopping/traits/libraryloader.php +++ /dev/null @@ -1,11 +0,0 @@ -registry->set('googleshopping', new Googleshopping($this->registry, $store_id)); - } -} \ No newline at end of file diff --git a/public/system/library/googleshopping/traits/storeloader.php b/public/system/library/googleshopping/traits/storeloader.php deleted file mode 100644 index fc1a591..0000000 --- a/public/system/library/googleshopping/traits/storeloader.php +++ /dev/null @@ -1,15 +0,0 @@ -registry->set('setting', new \Config()); - - $this->load->model('setting/setting'); - - foreach ($this->model_setting_setting->getSetting('advertise_google', $store_id) as $key => $value) { - $this->setting->set($key, $value); - } - } -} \ No newline at end of file