first commit

This commit is contained in:
2024-11-05 12:22:50 +01:00
commit e5682a3912
19641 changed files with 2948548 additions and 0 deletions

8
modules/ps_metrics/.env Normal file
View File

@@ -0,0 +1,8 @@
# For metrics app (VITEJS)
VITE_METRICS_API_URL=https://analytics-api.psessentials.net/graphql
# For PHP
PHP_METRICS_API_URL=https://analytics-api.psessentials.net
SEGMENT_API_KEY=iqrIKrNdu66IoCgzyHPeaaUweBKZmJmC
PS_METRICS_CDN_URL=https://storage.googleapis.com/psxmetrics/latest/
USE_LOCAL_VUE_APP=false

View File

@@ -0,0 +1,10 @@
# For metrics app (VITEJS)
VITE_METRICS_API_URL=https://analytics-api.psessentials.net/graphql
# If you change want to change the value of the sandbox, disconnect from billing first.
VITE_BILLING_SANDBOX=
# For PHP
PHP_METRICS_API_URL=https://analytics-api.psessentials.net
SEGMENT_API_KEY=iqrIKrNdu66IoCgzyHPeaaUweBKZmJmC
PS_METRICS_CDN_URL=https://storage.googleapis.com/psxmetrics/latest/
USE_LOCAL_VUE_APP=false

View File

@@ -0,0 +1,5 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
cd _dev
npx --no -- commitlint --edit "${1}"

View File

@@ -0,0 +1,5 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
cd _dev
npm run lint

View File

@@ -0,0 +1,6 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
cd _dev
npx ts-node ./utils/dot-env-check.ts --local ../.env --dist ../.env.dist
npx ts-node ./utils/check-branch-name.ts

View File

@@ -0,0 +1,115 @@
![PrestaShop Metrics preview](.github/pics/metrics-preview.webp)
# PrestaShop Metrics
[![Storybook CI/CD](https://github.com/PrestaShopCorp/ps_metrics/actions/workflows/ci-cd-storybook.yml/badge.svg)](https://github.com/PrestaShopCorp/ps_metrics/actions/workflows/ci-cd-storybook.yml)
[![PHP tests](https://github.com/PrestaShopCorp/ps_metrics/actions/workflows/php.yml/badge.svg)](https://github.com/PrestaShopCorp/ps_metrics/actions/workflows/php.yml)
## About
[PrestaShop Metrics](https://addons.prestashop.com/analytics-statistics/) allow you to drive your ecommerce performance and improve your business efficiency using a data-driven approach. Get a complete view of your business in real time and execute actionable optimization plans from your back-office.
**Take control of your ecommerce statistics**
- An intuitive and easy to use dashboard that saves time, no more switching between different applications
- Synchronization with Google Analytics: Easily install of a Google Analytics Tag and synchronize with your account to retrieve reliable traffic data. Compatible with Google Analytics v4.
- Cross-reference sales, orders, shopping carts and traffic data from the most reliable sources such as Google Analytics or your PrestaShop online store in a single interface
- Compare your activity by periods, visualize the evolution of your performance up to 24 months.
- Connect your store to Google Merchant Center and synchroniwe your entire product catalog in a few clicks. Product attributes such as price and availability will be automatically updated everyday.
**Save time with a revamped interface**
- Your key figures grouped in a way that makes it easier to read and to analyze them
- Traffic detailed by acquisition channel
- Understandable, usable, and relevant data
- Benefit from the customizable reporting tools such as CSV export or email reporting.
**Turn insights into actions**
Make informed decisions, create action plans and improve results through data integration.
## Download & Installation
Modules archives can be found and downloaded:
* On the [PrestaShop Addons Marketplace](https://addons.prestashop.com/analytics-statistics/49583-prestashop-metrics.html) (Latest stable release only)
* On the [releases page](https://github.com/PrestaShopCorp/ps_metrics/releases) of this repository (Stable & beta releases available)
Downloaded archives can be uploaded on PrestaShop instances, as detailed in the [user documentation](https://doc.prestashop.com/display/PS17/Modules+Selection#ModulesSelection-Uploadingamodulemanually).
## Developer
The project is divided in two sub project. The PHP is responsible for all PrestaShop oriented stuff and allow the installation of the module.
Front side is handled by a vuejs application that is hosted via a CDN (on GCP).
The following steps will explain how to build these different part and run the project locally.
### PHP
Retrieve dependencies with composer
```
composer install
```
In some cases, when you add or update php class, you may need to run `composer dump-autoload` in order to refresh the classmap.
### VUEJS
The following commands need to be run in the `_dev/` folder.
To build the application in production mode:
```
npm install
npm run build
```
The output directory is located in `_dev/dist/` directory.
To compiles and watch for new changes (development mode) once `npm install` was done:
```
npm run dev
```
### Tests / lint
**work in progress**
### Storybook
**Integration**
To trigger storybook CI/CD, create a new pull request
Tag with label Storybook Test will trigger the workflow.
Storybook will be available at this following url : [storybook](https://storybook-metrics.psessentials-integration.net)
**Production**
Production storybook CI/CD will automatically be triggered on push on develop.
Storybook will be available at this following url : [storybook](https://storybook-metrics.psessentials.net)
## Docker
**work in progress**
## CDN deploy
Release and pre release will trigger a storage action on [services-deployment](https://github.com/PrestaShopCorp/services-deployment) repository.
This action will build vuejs project and push assets to GCP storage.
On pre-release trigger, a new version will be stored and available at : https://storage.googleapis.com/psxmetrics/v1.1.1 (according to your tag name)
On release, 3 versions (major and minor) will be stored at :
* https://storage.googleapis.com/psxmetrics/latest
* https://storage.googleapis.com/psxmetrics/v1.1.x
* https://storage.googleapis.com/psxmetrics/v1.x.x
## Husky conventions
**work in progress**
## License
This module is released under the Academic Free License 3.0

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>ps_metrics</name>
<displayName><![CDATA[PrestaShop Metrics]]></displayName>
<version><![CDATA[3.4.0]]></version>
<description><![CDATA[Optimize your business with a data-driven approach by gaining a complete view of your business in real time.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[advertising_marketing]]></tab>
<confirmUninstall><![CDATA[Are you sure you want to uninstall this module?]]></confirmUninstall>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,12 @@
services:
ps_accounts.installer:
class: 'PrestaShop\PsAccountsInstaller\Installer\Installer'
public: true
arguments:
- "5.0"
ps_accounts.facade:
class: 'PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts'
public: true
arguments:
- "@ps_accounts.installer"

View File

@@ -0,0 +1 @@
services:

View File

@@ -0,0 +1,5 @@
services:
ps_metrics.config.env:
class: PrestaShop\Module\Ps_metrics\Config\Env
arguments:
- "@ps_metrics.module"

View File

@@ -0,0 +1,16 @@
services:
PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsController:
class: PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsController
arguments:
- "@ps_metrics.module"
PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsResolverController:
class: PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsResolverController
PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsLegacyStatsController:
class: PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsLegacyStatsController
PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsOauthController:
class: PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsOauthController
arguments:
- "@ps_metrics.module"

View File

@@ -0,0 +1,12 @@
services:
ps_metrics.handler.guzzleapi:
class: 'PrestaShop\Module\Ps_metrics\Handler\GuzzleApiResponseExceptionHandler'
public: true
ps_metrics.handler.native.stats:
class: 'PrestaShop\Module\Ps_metrics\Handler\NativeStatsHandler'
public: true
arguments:
- "@ps_metrics.module"
- "@ps_accounts.facade"
- "@ps_metrics.repository.configuration"

View File

@@ -0,0 +1,54 @@
services:
ps_metrics.helper.number:
class: 'PrestaShop\Module\Ps_metrics\Helper\NumberHelper'
public: true
ps_metrics.helper.module:
class: 'PrestaShop\Module\Ps_metrics\Helper\ModuleHelper'
public: true
ps_metrics.helper.tools:
class: 'PrestaShop\Module\Ps_metrics\Helper\ToolsHelper'
public: true
ps_metrics.helper.shop:
class: 'PrestaShop\Module\Ps_metrics\Helper\ShopHelper'
public: true
arguments:
- "@ps_metrics.helper.tools"
ps_metrics.adapter.logger:
class: 'PrestaShop\Module\Ps_metrics\Adapter\LoggerAdapter'
public: true
ps_metrics.helper.segment:
class: 'PrestaShop\Module\Ps_metrics\Helper\SegmentHelper'
public: true
arguments:
- "@ps_metrics.helper.config"
ps_metrics.helper.api:
class: 'PrestaShop\Module\Ps_metrics\Helper\ApiHelper'
public: true
ps_metrics.helper.json:
class: 'PrestaShop\Module\Ps_metrics\Helper\JsonHelper'
public: true
ps_metrics.helper.db:
class: 'PrestaShop\Module\Ps_metrics\Helper\DbHelper'
public: true
ps_metrics.helper.prestashop:
class: 'PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper'
public: true
ps_metrics.helper.multishop:
class: 'PrestaShop\Module\Ps_metrics\Helper\MultishopHelper'
public: true
ps_metrics.helper.config:
class: 'PrestaShop\Module\Ps_metrics\Helper\ConfigHelper'
public: true
arguments:
- "@ps_metrics.config.env"

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,24 @@
services:
ps_metrics.middleware:
class: 'PrestaShop\Module\Ps_metrics\Middleware\Middleware'
public: true
ps_metrics.middleware.sentry:
class: 'PrestaShop\Module\Ps_metrics\Middleware\SentryMiddleware'
public: true
ps_metrics.middleware.response:
class: 'PrestaShop\Module\Ps_metrics\Middleware\ResponseMiddleware'
public: true
ps_metrics.middleware.log:
class: 'PrestaShop\Module\Ps_metrics\Middleware\LogMiddleware'
public: true
arguments:
- "@ps_metrics.adapter.logger"
ps_metrics.middleware.response.default:
class: 'PrestaShop\Module\Ps_metrics\Middleware\CheckResponseMiddleware'
public: true
arguments:
- "@ps_metrics.helper.json"

View File

@@ -0,0 +1,31 @@
services:
ps_metrics.module.install:
class: 'PrestaShop\Module\Ps_metrics\Module\Install'
public: true
arguments:
- "@ps_metrics.module"
- "@ps_metrics.repository.configuration"
- "@ps_metrics.repository.hookmodule"
ps_metrics.module.upgrade:
class: 'PrestaShop\Module\Ps_metrics\Module\Upgrade'
public: true
arguments:
- "@ps_metrics.module"
ps_metrics.module.uninstall:
class: 'PrestaShop\Module\Ps_metrics\Module\Uninstall'
public: true
arguments:
- "@ps_metrics.module"
- "@ps_accounts.facade"
- "@ps_metrics.repository.configuration"
- "@ps_metrics.api.analytics"
ps_metrics.module.gainstaller:
class: 'PrestaShop\Module\Ps_metrics\Module\GAInstaller'
public: true
arguments:
- "@ps_metrics.helper.module"
- "@ps_metrics.helper.tools"
- "@ps_metrics.helper.prestashop"

View File

@@ -0,0 +1,27 @@
services:
ps_metrics.presenter.faq:
class: 'PrestaShop\Module\Ps_metrics\Presenter\FaqPresenter'
public: true
arguments:
- "@ps_metrics.helper.json"
- "@ps_metrics.module"
- "@ps_metrics.helper.prestashop"
- "@ps_metrics.api.http"
ps_metrics.presenter.shopData:
class: PrestaShop\Module\Ps_metrics\Presenter\ShopDataPresenter
arguments:
- "@ps_metrics.module"
- "@ps_metrics.helper.prestashop"
- "@ps_metrics.repository.configuration"
- "@ps_metrics.helper.shop"
- "@ps_metrics.provider.analyticsaccountslist"
- "@ps_metrics.provider.googletag"
- "@ps_metrics.module.gainstaller"
- "@ps_metrics.api.http"
- "@ps_metrics.handler.native.stats"
- "@ps_accounts.facade"
- "@ps_metrics.helper.tools"
- "@ps_metrics.helper.db"
- "@ps_metrics.helper.multishop"
- "@ps_metrics.repository.orders"

View File

@@ -0,0 +1,13 @@
services:
ps_metrics.provider.analyticsaccountslist:
class: 'PrestaShop\Module\Ps_metrics\Provider\AnalyticsAccountsListProvider'
public: true
arguments:
- "@ps_metrics.repository.configuration"
- "@ps_metrics.api.analytics"
ps_metrics.provider.googletag:
class: 'PrestaShop\Module\Ps_metrics\Provider\GoogleTagProvider'
public: true
arguments:
- "@ps_metrics.api.http"

View File

@@ -0,0 +1,82 @@
imports:
- { resource: ../common.yml }
services:
ps_metrics.statstab.manager:
class: 'PrestaShop\Module\Ps_metrics\StatsTabManager'
public: true
arguments:
- "@ps_metrics.module"
- "@ps_accounts.facade"
ps_metrics.legacy.installer:
class: 'PrestaShop\Module\Ps_metrics\LegacyModuleInstaller'
public: true
arguments:
- "@ps_metrics.module"
ps_metrics.repository.configuration:
class: 'PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository'
public: true
arguments:
- "@ps_metrics.helper.prestashop"
ps_metrics.repository.hookmodule:
class: 'PrestaShop\Module\Ps_metrics\Repository\HookModuleRepository'
public: true
ps_metrics.repository.orders:
class: 'PrestaShop\Module\Ps_metrics\Repository\OrderRepository'
public: true
arguments:
- "@ps_metrics.helper.db"
- "@ps_metrics.helper.shop"
ps_metrics.api.client.factory:
class: 'PrestaShop\Module\Ps_metrics\Api\Client\ClientManager'
public: true
arguments:
- "@ps_metrics.middleware.response.default"
- "@ps_metrics.middleware.log"
- "@ps_metrics.middleware.sentry"
- "@ps_metrics.middleware.response"
- "@ps_metrics.handler.guzzleapi"
ps_metrics.api.client.http:
class: 'PrestaShop\Module\Ps_metrics\Api\Client\HttpClient'
public: true
arguments:
- "@ps_metrics.middleware.response.default"
- "@ps_metrics.middleware.log"
- "@ps_metrics.middleware.sentry"
- "@ps_metrics.middleware.response"
- "@ps_metrics.handler.guzzleapi"
ps_metrics.api.client.analytics:
class: 'PrestaShop\Module\Ps_metrics\Api\Client\AnalyticsClient'
public: true
arguments:
- "@ps_accounts.facade"
- "@ps_metrics.middleware.response.default"
- "@ps_metrics.middleware.log"
- "@ps_metrics.middleware.sentry"
- "@ps_metrics.middleware.response"
- "@ps_metrics.handler.guzzleapi"
ps_metrics.api.manager:
class: 'PrestaShop\Module\Ps_metrics\Api\ApiManager'
public: true
ps_metrics.api.analytics:
class: 'PrestaShop\Module\Ps_metrics\Api\AnalyticsApi'
public: true
arguments:
- "@ps_metrics.api.client.analytics"
- "@ps_metrics.helper.config"
ps_metrics.api.http:
class: 'PrestaShop\Module\Ps_metrics\Api\HttpApi'
public: true
arguments:
- "@ps_metrics.api.client.http"
- "@ps_metrics.helper.config"

View File

@@ -0,0 +1,8 @@
services:
ps_metrics.tracker.segment:
class: 'PrestaShop\Module\Ps_metrics\Tracker\Segment'
public: true
arguments:
- "@ps_metrics.helper.segment"
- "@ps_metrics.helper.prestashop"
- "@ps_metrics.helper.shop"

View File

@@ -0,0 +1,4 @@
services:
ps_metrics.validation.processselectaccountanalytics:
class: 'PrestaShop\Module\Ps_metrics\Validation\SelectAccountAnalytics'
public: true

View File

@@ -0,0 +1,20 @@
imports:
- { resource: admin/accounts.yml }
- { resource: admin/adapters.yml }
- { resource: admin/config.yml }
- { resource: admin/controllers.yml }
- { resource: admin/handlers.yml }
- { resource: admin/helpers.yml }
- { resource: admin/middlewares.yml }
- { resource: admin/modules.yml }
- { resource: admin/presenters.yml }
- { resource: admin/providers.yml }
- { resource: admin/trackers.yml }
- { resource: admin/validators.yml }
services:
ps_metrics.module:
class: "Ps_metrics"
factory: ["Module", "getInstanceByName"]
arguments:
- "ps_metrics"

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,34 @@
metrics_page:
path: metrics
methods: [GET]
defaults:
_controller: 'PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsController::renderApp'
_legacy_controller: "AdminMetricsController"
_legacy_link: "AdminMetricsController"
metrics_api_resolver:
path: metrics/api/{query}
methods: [GET, POST]
defaults:
query: ""
_controller: 'PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsResolverController::resolve'
metrics_api_legacy_stats:
path: metrics/legacy/stats
methods: [GET]
defaults:
_controller: 'PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsLegacyStatsController::redirectToLegacyStats'
_legacy_controller: "AdminMetricsLegacyStatsController"
_legacy_link: "AdminMetricsLegacyStatsController"
metrics_oauth:
path: metrics/oauth
methods: [GET, POST]
defaults:
_controller: 'PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsOauthController::oauth'
metrics_graphql:
path: metrics/graphql
methods: [GET, POST]
defaults:
_controller: 'PrestaShop\Module\Ps_metrics\Controller\Admin\MetricsGraphqlController::execute'

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>ps_metrics</name>
<displayName><![CDATA[PrestaShop Metrics]]></displayName>
<version><![CDATA[3.4.0]]></version>
<description><![CDATA[Optimize your business with a data-driven approach by gaining a complete view of your business in real time.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[advertising_marketing]]></tab>
<confirmUninstall><![CDATA[Czy na pewno chcesz odinstalować ten moduł?]]></confirmUninstall>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

BIN
modules/ps_metrics/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

6
modules/ps_metrics/package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "ps_metrics",
"lockfileVersion": 2,
"requires": true,
"packages": {}
}

View File

@@ -0,0 +1,440 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
if (!defined('_PS_VERSION_')) {
exit();
}
require_once __DIR__ . '/vendor/autoload.php';
class Ps_metrics extends Module
{
/** @var bool */
public $bootstrap;
/** @var string */
public $confirmUninstall;
/** @var string */
public $idPsAccounts;
/** @var string */
public $idPsMetrics;
/** @var string */
public $template_dir;
/** @var string */
public $emailSupport;
/** @var string */
public $termsOfServiceUrl;
public function __construct()
{
$this->name = 'ps_metrics';
$this->tab = 'advertising_marketing';
$this->version = '3.4.0';
$this->author = 'PrestaShop';
$this->need_instance = 0;
$this->module_key = '697657ffe038d20741105e95a10b12d1';
$this->bootstrap = false;
$this->idPsAccounts = '49648';
$this->idPsMetrics = '49583';
$this->emailSupport = 'support-ps-metrics@prestashop.com';
$this->termsOfServiceUrl =
'https://www.prestashop.com/en/prestashop-account-privacy';
parent::__construct();
$this->displayName = $this->l('PrestaShop Metrics');
$this->description = $this->l(
'Optimize your business with a data-driven approach by gaining a complete view of your business in real time.'
);
$this->confirmUninstall = $this->l(
'Are you sure you want to uninstall this module?'
);
$this->ps_versions_compliancy = [
'min' => '1.7.5',
'max' => _PS_VERSION_,
];
$this->template_dir =
'../../../../modules/' . $this->name . '/views/templates/admin/';
}
/**
* This method is trigger at the installation of the module
*
* @return bool
*/
public function install()
{
parent::install();
$legacyModuleInstaller = new PrestaShop\Module\Ps_metrics\LegacyModuleInstaller(
$this
);
$installModule = $legacyModuleInstaller->legacyModuleInstaller();
$nativeStats = $legacyModuleInstaller->legacyNativeStatsHandler();
return $this->registerHook('displayAdminAfterHeader') &&
$this->registerHook('actionAdminControllerSetMedia') &&
$this->registerHook('dashboardZoneTwo') &&
$installModule->updateModuleHookPosition('dashboardZoneTwo', 0) &&
$installModule->setConfigurationValues() &&
$nativeStats->install();
}
/**
* Triggered at the uninstall of the module
*
* @return bool
*/
public function uninstall()
{
/** @var PrestaShop\Module\Ps_metrics\Module\Uninstall $uninstallModule */
$uninstallModule = $this->getService('ps_metrics.module.uninstall');
/** @var PrestaShop\Module\Ps_metrics\Tracker\Segment $segment */
$segment = $this->getService('ps_metrics.tracker.segment');
if (!empty($segment)) {
$segment->setMessage('[MTR] Uninstall Module');
$segment->track();
}
/** @var PrestaShop\Module\Ps_metrics\Handler\NativeStatsHandler $nativeStats */
$nativeStats = $this->getService('ps_metrics.handler.native.stats');
return $uninstallModule->resetConfigurationValues() &&
$uninstallModule->unsubscribePsEssentials() &&
$nativeStats->uninstall() &&
parent::uninstall();
}
/**
* Activate current module.
*
* @param bool $force_all If true, enable module for all shop
*
* @return bool
*/
public function enable($force_all = false)
{
parent::enable($force_all);
$legacyModuleInstaller = new PrestaShop\Module\Ps_metrics\LegacyModuleInstaller(
$this
);
$segment = $legacyModuleInstaller->legacyModuleInstallerSegment();
if (!empty($segment)) {
$segment->setMessage('[MTR] Enable Module');
$segment->track();
}
return true;
}
/**
* Desactivate current module.
*
* @param bool $force_all If true, disable module for all shop
*
* @return bool
*/
public function disable($force_all = false)
{
parent::disable($force_all);
/** @var PrestaShop\Module\Ps_metrics\Tracker\Segment $segment */
$segment = $this->getService('ps_metrics.tracker.segment');
if (!empty($segment)) {
$segment->setMessage('[MTR] Disable Module');
$segment->track();
}
return true;
}
/**
* hookDashboardZoneTwo
*
* @return string
*/
public function hookDashboardZoneTwo()
{
$assets = $this->loadAssets();
Media::addJsDef($assets);
return $this->display(
__FILE__,
'/views/templates/hook/HookDashboardZoneTwo.tpl'
);
}
/**
* Load the configuration form.
*
* @return string
* @return void
*/
public function getContent()
{
$link = $this->context->link;
\Tools::redirectAdmin(
$link->getAdminLink('MetricsController', true, [
'route' => 'metrics_page',
]) . '#/settings'
);
}
/**
* hook Backoffice top pages
*
* @return string|false
*/
public function hookDisplayAdminAfterHeader()
{
/** @var PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->getService('ps_metrics.helper.prestashop');
if (!Module::isEnabled($this->name)) {
return false;
}
if ($prestashopHelper->getControllerName() === 'AdminStats') {
return $this->display(
__FILE__,
'/views/templates/hook/HookDashboardZoneTwo.tpl'
);
}
if ($prestashopHelper->getControllerName() === 'AdminOrders') {
$assets = $this->loadAssets('AdminOrders', false);
$twig = $this->loadInstance('twig');
return $twig->render(
'@Modules/ps_metrics/views/templates/hook/HookBlockLegacyPages.html.twig',
$assets
);
}
return false;
}
/**
* Load an instance of the service
*
* @param string $instance_name
*
* @return mixed
*/
private function loadInstance($instance_name)
{
/** @var Symfony\Component\DependencyInjection\ContainerInterface $instance */
$instance = PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance();
return $instance->get($instance_name);
}
/**
* Hook set media for old stats pages for loading dashboard box
*
* @return void
*/
public function hookActionAdminControllerSetMedia()
{
/** @var PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->getService('ps_metrics.helper.prestashop');
if (!Module::isEnabled($this->name)) {
return;
}
if ($prestashopHelper->getControllerName() === 'AdminStats') {
$assets = $this->loadAssets('AdminStats');
Media::addJsDef($assets);
}
if ($prestashopHelper->getControllerName() === 'AdminOrders') {
$assets = $this->loadAssets('AdminOrders', false);
}
}
/**
* Load VueJs App Dashboard and set JS variable for Vue
*
* @param string $currentPage
* @param bool $legacy
*
* @return array
*/
private function loadAssets($currentPage = 'dashboard', $legacy = true)
{
$assets = $this->buildAssets($currentPage);
if ($legacy) {
$this->context->smarty->assign(
'pathMetricsApp',
$assets['pathMetricsApp']
);
$this->context->smarty->assign(
'pathMetricsAssets',
$assets['pathMetricsAssets']
);
$this->context->smarty->assign(
'pathMetricsAppSourceMap',
$assets['pathMetricsAppSourceMap']
);
} else {
$twig = $this->loadInstance('twig');
$twig->addGlobal('pathMetricsApp', $assets['pathMetricsApp']);
$twig->addGlobal('pathMetricsAssets', $assets['pathMetricsAssets']);
$twig->addGlobal(
'pathMetricsAppSourceMap',
$assets['pathMetricsAppSourceMap']
);
$twig->addGlobal(
'nativeStatsModulesEnabled',
$assets['nativeStatsModulesEnabled']
);
}
return $assets;
}
/**
* Build assets to set them in smarty or Twig
*
* @param string $currentPage
*
* @return array
*/
private function buildAssets($currentPage = 'dashboard')
{
/** @var PrestaShop\Module\Ps_metrics\Helper\ConfigHelper $configHelper */
$configHelper = $this->getService('ps_metrics.helper.config');
/** @var PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->getService('ps_metrics.helper.prestashop');
/** @var PrestaShop\Module\Ps_metrics\Helper\ConfigHelper $configHelper */
$configHelper = $this->getService('ps_metrics.helper.config');
/** @var PrestaShop\Module\Ps_metrics\Helper\ToolsHelper $toolsHelper */
$toolsHelper = $this->getService('ps_metrics.helper.tools');
/** @var PrestaShop\Module\Ps_metrics\Handler\NativeStatsHandler $nativeStats */
$nativeStats = $this->getService('ps_metrics.handler.native.stats');
/** @var PrestaShop\Module\Ps_metrics\Helper\ModuleHelper $moduleHelper */
$moduleHelper = $this->getService('ps_metrics.helper.module');
$pathMetricsApp = $configHelper->getUseLocalVueApp()
? $this->_path . '_dev/dist/js/metrics.js'
: $configHelper->getPsMetricsCdnUrl() . 'js/metrics.js';
$pathMetricsAssets = $configHelper->getUseLocalVueApp()
? $this->_path . '_dev/dist/css/style.css'
: $configHelper->getPsMetricsCdnUrl() . 'css/style.css';
$pathMetricsAppSourceMap = null;
if (
file_exists(
_PS_MODULE_DIR_ . $this->name . '/_dev/dist/js/metrics.js.map'
)
) {
$pathMetricsAppSourceMap = $configHelper->getUseLocalVueApp()
? $this->_path . '_dev/dist/js/metrics.js.map'
: $configHelper->getPsMetricsCdnUrl() . 'js/metrics.js.map';
}
$link = $this->context->link;
return [
'pathMetricsApp' => $pathMetricsApp,
'pathMetricsAppSourceMap' => $pathMetricsAppSourceMap,
'pathMetricsAssets' => $pathMetricsAssets,
'contextPsAccounts' => $this->loadPsAccountsAssets(),
'oAuthGoogleErrorMessage' => $toolsHelper->getValue(
'google_message_error'
),
'metricsApiUrl' => $prestashopHelper->getLinkWithoutToken(
'MetricsResolverController',
'metrics_api_resolver'
),
'adminToken' => $prestashopHelper->getTokenFromAdminLink(
'MetricsResolverController',
'metrics_api_resolver'
),
'metricsModule' => $moduleHelper->buildModuleInformations(
'ps_metrics'
),
'eventBusModule' => $moduleHelper->buildModuleInformations(
'ps_eventbus'
),
'accountsModule' => $moduleHelper->buildModuleInformations(
'ps_accounts'
),
'graphqlEndpoint' => $link->getAdminLink(
'MetricsGraphqlController',
true,
['route' => 'metrics_graphql']
),
'isoCode' => $prestashopHelper->getLanguageIsoCode(),
'currencyIsoCode' => $prestashopHelper->getCurrencyIsoCode(),
'currentPage' => $currentPage,
'fullscreen' => false,
'nativeStatsModulesEnabled' => $nativeStats->nativeStatsIsEnabled(),
];
}
/**
* Retrieve service
*
* @param string $serviceName
*
* @return mixed
*/
public function getService($serviceName)
{
return $this->get($serviceName);
}
/**
* See https://github.com/PrestaShopCorp/prestashop-accounts-installer
*
* @return array
*/
public function loadPsAccountsAssets()
{
if (\Module::isInstalled('ps_accounts')) {
/** @var PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts $accounts */
$accounts = $this->get('ps_accounts.facade');
$psAccounts = $accounts->getPsAccountsService();
$this->context->smarty->assign(
'urlAccountsVueCdn',
$psAccounts->getAccountsVueCdn()
);
return $accounts->getPsAccountsPresenter()->present($this->name);
}
return [];
}
}

View File

@@ -0,0 +1,179 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Adapter;
use PrestaShopLogger;
use Psr\Log\LoggerInterface;
/**
* Class that bridge the PrestaShop implementation of Logger with Psr Logger interface.
*/
class LoggerAdapter implements LoggerInterface
{
/**
* Detailed debug information
*/
const DEBUG = 100;
/**
* Interesting events
*
* Examples: User logs in, SQL logs.
*/
const INFO = 200;
/**
* Uncommon events
*/
const NOTICE = 250;
/**
* Exceptional occurrences that are not errors
*
* Examples: Use of deprecated APIs, poor use of an API,
* undesirable things that are not necessarily wrong.
*/
const WARNING = 300;
/**
* Runtime errors
*/
const ERROR = 400;
/**
* Critical conditions
*
* Example: Application component unavailable, unexpected exception.
*/
const CRITICAL = 500;
/**
* Action must be taken immediately
*
* Example: Entire website down, database unavailable, etc.
* This should trigger the SMS alerts and wake you up.
*/
const ALERT = 550;
/**
* Urgent alert.
*/
const EMERGENCY = 600;
/**
* {@inheritdoc}
*/
public function emergency($message, array $context = [])
{
$this->log(static::EMERGENCY, $message, $context);
}
/**
* {@inheritdoc}
*/
public function alert($message, array $context = [])
{
$this->log(static::ALERT, $message, $context);
}
/**
* {@inheritdoc}
*/
public function critical($message, array $context = [])
{
$this->log(static::CRITICAL, $message, $context);
}
/**
* {@inheritdoc}
*/
public function error($message, array $context = [])
{
$this->log(static::ERROR, $message, $context);
}
/**
* {@inheritdoc}
*/
public function warning($message, array $context = [])
{
$this->log(static::WARNING, $message, $context);
}
/**
* {@inheritdoc}
*/
public function notice($message, array $context = [])
{
$this->log(static::NOTICE, $message, $context);
}
/**
* {@inheritdoc}
*/
public function info($message, array $context = [])
{
$this->log(static::INFO, $message, $context);
}
/**
* {@inheritdoc}
*/
public function debug($message, array $context = [])
{
$this->log(static::DEBUG, $message, $context);
}
/**
* {@inheritdoc}
*/
public function log($level, $message, array $context = [])
{
switch ($level) {
case static::EMERGENCY:
case static::ALERT:
case static::CRITICAL:
$severity = 4;
break;
case static::ERROR:
$severity = 3;
break;
case static::WARNING:
$severity = 2;
break;
case static::NOTICE:
case static::INFO:
case static::DEBUG:
default:
$severity = 1;
}
$errorCode = !empty($context['error_code']) ? (int) $context['error_code'] : null;
$objectType = !empty($context['object_type']) ? $context['object_type'] : null;
$objectId = !empty($context['object_id']) ? (int) $context['object_id'] : null;
$allowDuplicate = !empty($context['allow_duplicate']) && (bool) $context['allow_duplicate'];
$idEmployee = !empty($context['id_employee']) ? (int) $context['id_employee'] : null;
unset($context['error_code'], $context['object_type'], $context['object_id'], $context['allow_duplicate'], $context['id_employee']);
PrestaShopLogger::addLog($message, $severity, $errorCode, $objectType, $objectId, $allowDuplicate, $idEmployee);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,163 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Api;
use PrestaShop\Module\Ps_metrics\Api\Client\AnalyticsClient;
use PrestaShop\Module\Ps_metrics\Helper\ConfigHelper;
class AnalyticsApi
{
/**
* @var AnalyticsClient
*/
private $client;
/**
* AnalyticsApi constructor.
*
* @param AnalyticsClient $analyticsClient
* @param ConfigHelper $configHelper
*/
public function __construct(
AnalyticsClient $analyticsClient,
ConfigHelper $configHelper
) {
$this->client = $analyticsClient;
$this->client->setUrl($configHelper->getApiBaseUrl());
$this->client->setMiddlewares();
$this->client->setHeader($this->client->getHeader());
}
/**
* @return false|string
*/
private function getShopId()
{
return $this->client->getShopId();
}
/**
* get reportings by date
*
* @param array $data
*
* @return array
*/
public function getReportingByDate(array $data)
{
$this->client->setRoute('/shops/' . $this->getShopId() . '/reportings');
$reportings = $this->client->post([
'json' => $data,
]);
return !empty($reportings['error']) ? [] : $reportings;
}
/**
* getAccountsList
*
* @return array
*/
public function getAccountsList()
{
$this->client->setRoute(
'/shops/' . $this->getShopId() . '/accounts/list'
);
$accounts = $this->client->get();
return !empty($accounts['error']) ? [] : $accounts['body'];
}
/**
* setAccountSelection
*
* @param array $data
*
* @return array|false
*/
public function setAccountSelection(array $data)
{
$this->client->setRoute(
'/shops/' . $this->getShopId() . '/accounts/selection'
);
$accountSelected = $this->client->post([
'json' => $data,
]);
return !empty($accountSelected['error'])
? false
: $accountSelected['body'];
}
/**
* unsubscribe
*
* @return bool
*/
public function unsubscribe()
{
$this->client->setRoute(
'/shops/' . $this->getShopId() . '/accounts/unsubscribe'
);
$unsubscribed = $this->client->post();
return empty($unsubscribed['error']);
}
/**
* refreshGA
*
* @return array
*/
public function refreshGA()
{
$this->client->setRoute(
'/shops/' . $this->getShopId() . '/accounts/refresh'
);
return $this->client->post();
}
/**
* authUrl
*
* @param array $data
*
* @return array
*/
public function generateAuthUrl(array $data)
{
$this->client->setRoute(
'/shops/' . $this->getShopId() . '/google/generate-auth-url'
);
$generated = $this->client->post([
'json' => $data,
]);
return !empty($generated['error']) ? [] : $generated['body'];
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Api\Client;
use PrestaShop\Module\Ps_metrics\Handler\GuzzleApiResponseExceptionHandler;
use PrestaShop\Module\Ps_metrics\Middleware\CheckResponseMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\LogMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\ResponseMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\SentryMiddleware;
use PrestaShop\PsAccountsInstaller\Installer\Exception\InstallerException;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
class AnalyticsClient extends ClientFactory
{
/**
* @var PsAccounts
*/
private $psAccountsService;
/**
* AnalyticsClient constructor.
*
* @param PsAccounts $psAccounts
* @param CheckResponseMiddleware $checkResponseMiddleware
* @param LogMiddleware $logMiddleware
* @param SentryMiddleware $sentryMiddleware
* @param ResponseMiddleware $responseMiddleWare
* @param GuzzleApiResponseExceptionHandler $guzzleApiResponseExceptionHandler
*/
public function __construct(
PsAccounts $psAccounts,
CheckResponseMiddleware $checkResponseMiddleware,
LogMiddleware $logMiddleware,
SentryMiddleware $sentryMiddleware,
ResponseMiddleWare $responseMiddleWare,
GuzzleApiResponseExceptionHandler $guzzleApiResponseExceptionHandler
) {
parent::__construct($checkResponseMiddleware, $logMiddleware, $sentryMiddleware, $responseMiddleWare, $guzzleApiResponseExceptionHandler);
$this->psAccountsService = $psAccounts;
}
/**
* @return string[]
*/
public function getHeader()
{
try {
$psAccountsService = $this->psAccountsService->getPsAccountsService();
$refreshToken = $psAccountsService->getOrRefreshToken();
} catch (InstallerException $e) {
$refreshToken = '';
}
return [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $refreshToken,
];
}
/**
* @return string|false
*/
public function getShopId()
{
$psAccountsService = $this->psAccountsService->getPsAccountsService();
return $psAccountsService->getShopUuidV4();
}
}

View File

@@ -0,0 +1,261 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Api\Client;
/*
* 2007-2021 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2021 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Ring\Exception\RingException;
use PrestaShop\Module\Ps_metrics\Handler\GuzzleApiResponseExceptionHandler;
use PrestaShop\Module\Ps_metrics\Middleware\CheckResponseMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\LogMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\Middleware;
use PrestaShop\Module\Ps_metrics\Middleware\ResponseMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\SentryMiddleware;
class ClientFactory
{
/**
* @var array
*/
private $header;
/**
* @var string
*/
private $url;
/**
* @var string
*/
private $route = '';
/**
* @var Middleware
*/
private $middlewareManager;
/**
* @var CheckResponseMiddleware
*/
private $checkResponseMiddleware;
/**
* @var LogMiddleware
*/
private $logMiddleware;
/**
* @var SentryMiddleware
*/
private $sentryMiddleware;
/**
* @var ResponseMiddleware
*/
private $responseMiddleWare;
/**
* @var GuzzleApiResponseExceptionHandler
*/
private $guzzleApiResponseExceptionHandler;
/**
* ClientFactory constructor.
*
* @param CheckResponseMiddleware $checkResponseMiddleware
* @param LogMiddleware $logMiddleware
* @param SentryMiddleware $sentryMiddleware
* @param ResponseMiddleware $responseMiddleWare
* @param GuzzleApiResponseExceptionHandler $guzzleApiResponseExceptionHandler
*/
public function __construct(
CheckResponseMiddleware $checkResponseMiddleware,
LogMiddleware $logMiddleware,
SentryMiddleware $sentryMiddleware,
ResponseMiddleWare $responseMiddleWare,
GuzzleApiResponseExceptionHandler $guzzleApiResponseExceptionHandler
) {
$this->checkResponseMiddleware = $checkResponseMiddleware;
$this->logMiddleware = $logMiddleware;
$this->sentryMiddleware = $sentryMiddleware;
$this->responseMiddleWare = $responseMiddleWare;
$this->guzzleApiResponseExceptionHandler = $guzzleApiResponseExceptionHandler;
}
/**
* @return mixed
*/
public function get()
{
$client = new Client([
'base_url' => $this->getUrl() . $this->getRoute(),
'defaults' => [
'timeout' => 10,
'exceptions' => false,
'headers' => $this->getHeader(),
],
]);
try {
$response = $client->get();
} catch (RequestException $e) {
//for localhost/docker request guzzle can't access
$response = $this->guzzleApiResponseExceptionHandler->get($e->getMessage());
} catch (RingException $e) {
$response = $this->guzzleApiResponseExceptionHandler->get($e->getMessage());
}
return $this->getMiddlewareManager()->execute($response);
}
/**
* @param array $options
*
* @return mixed
*/
public function post($options = [])
{
$client = new Client([
'base_url' => $this->getUrl(),
'defaults' => [
'timeout' => 10,
'exceptions' => false,
'headers' => $this->getHeader(),
],
]);
try {
$response = $client->post($this->getRoute(), $options);
} catch (RequestException $e) {
//for localhost/docker request guzzle can't access
$response = $this->guzzleApiResponseExceptionHandler->get($e->getMessage());
} catch (RingException $e) {
$response = $this->guzzleApiResponseExceptionHandler->get($e->getMessage());
}
return $this->getMiddlewareManager()->execute($response);
}
/**
* @return mixed
*/
public function getUrl()
{
return $this->url;
}
/**
* @param string $url
*
* @return void
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* @return mixed
*/
public function getRoute()
{
return $this->route;
}
/**
* @param string $route
*
* @return void
*/
public function setRoute($route)
{
$this->route = $route;
}
/**
* @return mixed
*/
public function getHeader()
{
return $this->header;
}
/**
* @param mixed $header
*
* @return void
*/
public function setHeader($header)
{
$this->header = $header;
}
/**
* @return mixed
*/
public function getMiddlewareManager()
{
return $this->middlewareManager;
}
/**
* @param mixed $middlewareManager
*
* @return void
*/
public function setMiddlewareManager($middlewareManager)
{
$this->middlewareManager = $middlewareManager;
}
/**
* @return void
*/
public function setMiddlewares()
{
$middlewareManager = $this->checkResponseMiddleware;
$middlewareManager
->linkWith($this->logMiddleware)
->linkWith($this->sentryMiddleware)
->linkWith($this->responseMiddleWare);
$this->setMiddlewareManager($middlewareManager);
}
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Api\Client;
use PrestaShop\Module\Ps_metrics\Handler\GuzzleApiResponseExceptionHandler;
use PrestaShop\Module\Ps_metrics\Middleware\CheckResponseMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\LogMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\ResponseMiddleware;
use PrestaShop\Module\Ps_metrics\Middleware\SentryMiddleware;
/**
* 2007-2021 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2021 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class HttpClient extends ClientFactory
{
/**
* AnalyticsClient constructor.
*
* @param CheckResponseMiddleware $checkResponseMiddleware
* @param LogMiddleware $logMiddleware
* @param SentryMiddleware $sentryMiddleware
* @param ResponseMiddleware $responseMiddleWare
* @param GuzzleApiResponseExceptionHandler $guzzleApiResponseExceptionHandler
*/
public function __construct(
CheckResponseMiddleware $checkResponseMiddleware,
LogMiddleware $logMiddleware,
SentryMiddleware $sentryMiddleware,
ResponseMiddleWare $responseMiddleWare,
GuzzleApiResponseExceptionHandler $guzzleApiResponseExceptionHandler
) {
parent::__construct($checkResponseMiddleware, $logMiddleware, $sentryMiddleware, $responseMiddleWare, $guzzleApiResponseExceptionHandler);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,176 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Api;
use PrestaShop\Module\Ps_metrics\Api\Client\HttpClient;
use PrestaShop\Module\Ps_metrics\Helper\ConfigHelper;
class HttpApi
{
/**
* @var HttpClient
*/
private $client;
/**
* @var ConfigHelper
*/
private $configHelper;
/**
* HttpApi constructor.
*
* @param HttpClient $httpClient
*/
public function __construct(
HttpClient $httpClient,
ConfigHelper $configHelper
) {
$this->client = $httpClient;
$this->client->setMiddlewares();
$this->configHelper = $configHelper;
}
/**
* @param string $moduleKey
* @param string $isoCode
* @param string $psVersion
*
* @return mixed
*/
public function getFaq($moduleKey, $isoCode, $psVersion)
{
$url =
'https://api.addons.prestashop.com/request/faq/' .
$moduleKey .
'/' .
$isoCode .
'/' .
$psVersion;
$this->client->setUrl($url);
$faq = $this->client->get();
return !empty($faq['error']) ? null : $faq['body'];
}
/**
* @param string $moduleId
* @param string $isoCode
* @param string $psVersion
* @param string $format
*
* @return mixed
*/
public function getLastedVersion(
$moduleId,
$isoCode,
$psVersion,
$format = 'json'
) {
$url =
'https://api.addons.prestashop.com/?version=' .
$psVersion .
'&iso_lang=' .
$isoCode .
'&iso_code=' .
$isoCode .
'&format=' .
$format .
'&method=listing&action=module&id_module=' .
$moduleId;
$this->client->setUrl($url);
$module = $this->client->get();
return empty($module['error']) &&
!empty($module['body']['modules'][0]['version'])
? $module['body']['modules'][0]['version']
: false;
}
/**
* @param string $isoCode
*
* @return mixed
*/
public function getPlansDetails($isoCode)
{
$this->client->setUrl(
$this->configHelper->getApiBaseUrl() .
'/plans/description/' .
$isoCode
);
$plans = $this->client->get();
return !empty($plans['error'] || empty($plans['body']))
? null
: $plans['body']['plans_description'];
}
/**
* @param string $url
*
* @return mixed
*/
public function getSourcePage($url)
{
$this->client->setUrl($url);
$source = $this->client->get();
return !empty($source['error']) ? null : $source['body'];
}
/**
* Convert amount from currency to another currency
*
* @param float $amount
* @param string $currency_target
* @param string $currency_source
*
* @return float
*/
public function convertToCurrency(
$amount,
$currency_target,
$currency_source = 'EUR'
) {
if ($currency_source === $currency_target) {
return $amount;
}
$this->client->setUrl(
$this->configHelper->getApiBaseUrl() .
'/currencies?currency=' .
$currency_source
);
$datas = $this->client->get();
$rate =
!empty($datas['body']) && !empty($datas['body'][$currency_target])
? $datas['body'][$currency_target]
: 1;
// 1 USD = 0.8 EUR (by exemple)
// 100 USD / 0.8 = 120 EUR
return round($amount / $rate, 2);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,55 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Config;
use Dotenv\Dotenv;
/**
* This class allows to retrieve config data that can be overwritten by a .env file.
* Otherwise it returns by default from the Config class.
*/
class Env
{
public function __construct(\Ps_metrics $module)
{
if (file_exists(_PS_MODULE_DIR_ . $module->name . '/.env')) {
$dotenv = Dotenv::create(_PS_MODULE_DIR_ . $module->name . '/');
$dotenv->load();
}
}
/**
* @param string $key
*
* @return string
*/
public function get($key)
{
if (!empty($_ENV[$key])) {
return $_ENV[$key];
}
//TODO implement config class
//return constant(Config::class . '::' . $key);
return '';
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,169 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Controller\Admin;
use PrestaShop\Module\Ps_metrics\Handler\NativeStatsHandler;
use PrestaShop\Module\Ps_metrics\Helper\ConfigHelper;
use PrestaShop\Module\Ps_metrics\Helper\ModuleHelper;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\ToolsHelper;
use PrestaShop\PsAccountsInstaller\Installer\Exception\InstallerException;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use PrestaShop\PsAccountsInstaller\Installer\Installer;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\Response;
class MetricsController extends FrameworkBundleAdminController
{
/**
* @var \Ps_metrics
*/
public $module;
public function __construct(\Ps_metrics $module)
{
$this->module = $module;
}
/**
* Initialize the content by adding Boostrap and loading the TPL
*
* @return Response
*/
public function renderApp(): Response
{
$accountsService = null;
try {
/** @var PsAccounts $accounts */
$accounts = $this->get('ps_accounts.facade');
$accountsService = $accounts->getPsAccountsService();
} catch (InstallerException $e) {
$accountsService = false;
}
if (empty($accountsService)) {
/** @var Installer $accountsInstaller */
$accountsInstaller = $this->get('ps_accounts.installer');
$accountsInstaller->install();
}
/** @var ToolsHelper $toolsHelper */
$toolsHelper = $this->get('ps_metrics.helper.tools');
/** @var PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->get('ps_metrics.helper.prestashop');
if (
!empty($accountsService) &&
empty($accountsService->getShopUuidV4()) &&
$toolsHelper->getValue('settings_redirect', 0) === 0
) {
$link = $prestashopHelper->getLink();
$toolsHelper->redirectAdmin(
$link->getAdminLink('MetricsController', true, [
'route' => 'metrics_page',
'settings_redirect' => 1,
]) . '#/settings'
);
}
/** @var NativeStatsHandler $nativeStats */
$nativeStats = $this->get('ps_metrics.handler.native.stats');
$nativeStats->installIfIsOnboarded();
$fullscreen = false;
/** @var ConfigHelper $configHelper */
$configHelper = $this->get('ps_metrics.helper.config');
if ('true' === $toolsHelper->getValue('fullscreen')) {
$fullscreen = true;
}
/** @var ModuleHelper $moduleHelper */
$moduleHelper = $this->get('ps_metrics.helper.module');
$pathMetricsApp = $configHelper->getUseLocalVueApp()
? $this->module->getPathUri() . '_dev/dist/js/metrics.js'
: $configHelper->getPsMetricsCdnUrl() . 'js/metrics.js';
$pathMetricsAssets = $configHelper->getUseLocalVueApp()
? $this->module->getPathUri() . '_dev/dist/css/style.css'
: $configHelper->getPsMetricsCdnUrl() . 'css/style.css';
$pathMetricsAppSourceMap = null;
if (
file_exists(
_PS_MODULE_DIR_ .
$this->module->name .
'/_dev/dist/js/metrics.js.map'
)
) {
$pathMetricsAppSourceMap = $configHelper->getUseLocalVueApp()
? $this->module->getPathUri() . '_dev/dist/js/metrics.js.map'
: $configHelper->getPsMetricsCdnUrl() . 'js/metrics.js.map';
}
$link = $prestashopHelper->getLink();
return $this->render(
'@Modules/ps_metrics/views/templates/admin/metrics.html.twig',
[
'layoutTitle' => $this->trans(
'PrestaShop Metrics',
'Admin.Navigation.Menu'
),
'showContentHeader' => false,
'pathMetricsApp' => $pathMetricsApp,
'pathMetricsAppSourceMap' => $pathMetricsAppSourceMap,
'pathMetricsAssets' => $pathMetricsAssets,
'contextPsAccounts' => $this->module->loadPsAccountsAssets(),
'metricsApiUrl' => $prestashopHelper->getLinkWithoutToken(
'MetricsResolverController',
'metrics_api_resolver'
),
'adminToken' => $toolsHelper->getValue('_token'),
'oAuthGoogleErrorMessage' => $toolsHelper->getValue(
'google_message_error'
),
'fullscreen' => $fullscreen,
'metricsModule' => $moduleHelper->buildModuleInformations(
'ps_metrics'
),
'eventBusModule' => $moduleHelper->buildModuleInformations(
'ps_eventbus'
),
'accountsModule' => $moduleHelper->buildModuleInformations(
'ps_accounts'
),
'graphqlEndpoint' => $link->getAdminLink(
'MetricsGraphqlController',
true,
['route' => 'metrics_graphql']
),
'isoCode' => $prestashopHelper->getLanguageIsoCode(),
'currencyIsoCode' => $prestashopHelper->getCurrencyIsoCode(),
'currentPage' => $toolsHelper->getValue('redirect'),
]
);
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Controller\Admin;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
class MetricsLegacyStatsController extends FrameworkBundleAdminController
{
/**
* @return void
*/
public function redirectToLegacyStats(): void
{
\Tools::redirectAdmin($this->getAdminLink('AdminStats', [], true));
}
}

View File

@@ -0,0 +1,163 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Controller\Admin;
use PrestaShop\Module\Ps_metrics\Api\AnalyticsApi;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\ToolsHelper;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
class MetricsOauthController extends FrameworkBundleAdminController
{
/**
* @var \Ps_metrics
*/
public $module;
public function __construct(\Ps_metrics $module)
{
$this->module = $module;
}
/**
* Main method
*
* @return void
*/
public function oauth(): void
{
/** @var ToolsHelper $toolsHelper */
$toolsHelper = $this->get('ps_metrics.helper.tools');
/** @var ConfigurationRepository $configurationRepository */
$configurationRepository = $this->get(
'ps_metrics.repository.configuration'
);
if ('PS' === $toolsHelper->getValue('from')) {
$this->redirectToGoogleAuthentication();
}
$configurationRepository->saveActionGoogleLinked(true);
if (false === $this->isGoogleAuthenticationDone()) {
$configurationRepository->saveActionGoogleLinked(false);
}
/** @var PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->get('ps_metrics.helper.prestashop');
$link = $prestashopHelper->getLink();
$toolsHelper->redirectAdmin(
$link->getAdminLink('MetricsController', true, [
'route' => 'metrics_page',
'google_message_error' => $toolsHelper->getValue('message'),
'countProperty' => $toolsHelper->getValue('count'),
]) . '#/settings'
);
}
/**
* Connexion to Google OAuth by redirecting to psessentials service
*
* @return void
*/
private function redirectToGoogleAuthentication(): void
{
/** @var AnalyticsApi $apiAnalytics */
$apiAnalytics = $this->get('ps_metrics.api.analytics');
/** @var ToolsHelper $toolsHelper */
$toolsHelper = $this->get('ps_metrics.helper.tools');
/** @var PsAccounts $psAccountsFacade */
$psAccountsFacade = $this->get('ps_accounts.facade');
$psAccountsService = $psAccountsFacade->getPsAccountsService();
/** @var PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->get('ps_metrics.helper.prestashop');
$link = $prestashopHelper->getLink();
$serviceResult = $apiAnalytics->generateAuthUrl([
'state' => $this->getGoogleApiState(
\Tools::getHttpHost(true) .
$link->getAdminLink('MetricsOauthController', true, [
'route' => 'metrics_oauth',
'from' => 'PS',
]),
$psAccountsService->getShopUuidV4()
),
]);
if (empty($serviceResult)) {
$toolsHelper->redirectAdmin(
$link->getAdminLink('MetricsController', true, [
'route' => 'metrics_page',
'google_message_error' => $toolsHelper->getValue('message'),
'countProperty' => $toolsHelper->getValue('count'),
'redirect' => 'settings',
]) . '#/settings'
);
}
$toolsHelper->redirect($serviceResult['authorizeUrl']);
}
/**
* The service psessentials returns a param "status=ok" when the connection is done and valid
*
* @return bool
*/
private function isGoogleAuthenticationDone(): bool
{
/** @var ToolsHelper $toolsHelper */
$toolsHelper = $this->get('ps_metrics.helper.tools');
if ('ok' === $toolsHelper->getValue('status')) {
return true;
}
return false;
}
/**
* Google State is a base64 json encoded
*
* @param string $shopRedirectUri
* @param string|false $shopId
*
* @return string
*/
private function getGoogleApiState($shopRedirectUri, $shopId): string
{
// the use of base64_encode is necessary for the api
return base64_encode(
'{"redirectUri":"' .
$shopRedirectUri .
'","shopId":"' .
$shopId .
'"}'
);
}
}

View File

@@ -0,0 +1,508 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Controller\Admin;
use PrestaShop\Module\Ps_metrics\Api\AnalyticsApi;
use PrestaShop\Module\Ps_metrics\Handler\NativeStatsHandler;
use PrestaShop\Module\Ps_metrics\Helper\JsonHelper;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\ShopHelper;
use PrestaShop\Module\Ps_metrics\Module\Uninstall;
use PrestaShop\Module\Ps_metrics\Module\Upgrade;
use PrestaShop\Module\Ps_metrics\Presenter\FaqPresenter;
use PrestaShop\Module\Ps_metrics\Presenter\ShopDataPresenter;
use PrestaShop\Module\Ps_metrics\Provider\AnalyticsAccountsListProvider;
use PrestaShop\Module\Ps_metrics\Provider\GoogleTagProvider;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
use PrestaShop\Module\Ps_metrics\Validation\SelectAccountAnalytics;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class MetricsResolverController extends FrameworkBundleAdminController
{
/**
* @var Request
*/
private $request = null;
/**
* Api endpoint
*
* @param Request $request
* @param string $query
*
* @return Response
*
* @throws \Exception
*/
public function resolve(Request $request, string $query): Response
{
try {
$this->request = $request;
if (is_callable([$this, $query])) {
return call_user_func([$this, $query]);
}
} catch (\Throwable $th) {
throw new \Exception('#001 Message : ' . $th->getMessage());
}
return new Response('Not found', 404);
}
/**
* Get shop datas api
*
* @return Response
*/
public function getShopData(): Response
{
/** @var ShopDataPresenter $shopData */
$shopData = $this->get('ps_metrics.presenter.shopData');
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
return new Response(
$jsonHelper->jsonEncode($shopData->getShopData()),
200,
['Content-Type' => 'application/json']
);
}
/**
* Retrieve category tree
*
* @return Response
*/
public function getCategoryTree(): Response
{
$categoryTree = [];
$context = \Context::getContext();
if (null !== $context) {
$categoryTree = \Category::getNestedCategories(\Category::getRootCategory()->id, (int) $context->language->id, false);
}
if (null === $categoryTree) {
$categoryTree = [];
}
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
return new Response(
$jsonHelper->jsonEncode($categoryTree),
200,
['Content-Type' => 'application/json']
);
}
/**
* Get faq from addons
*
* @return Response
*/
public function getFaq(): Response
{
/** @var FaqPresenter $faq */
$faq = $this->get('ps_metrics.presenter.faq');
return new Response($faq->getFaq(), 200, [
'Content-Type' => 'application/json',
]);
}
/**
* Generate product link
*
* @return Response
*/
public function retrieveProductsLinksFromList(): Response
{
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
$products = explode(',', $this->request->request->get('products', ''));
$links = [];
foreach ($products as $product) {
$links[$product] =
$this->getAdminLink(
'AdminProducts',
['id_product' => $product, 'updateproduct' => 1],
true
) . '#tab-step3';
}
return new Response($jsonHelper->jsonEncode($links), 200, [
'Content-Type' => 'application/json',
]);
}
/**
* Upgrade a module
*
* @return Response
*/
public function upgradeModule(): Response
{
/** @var Upgrade $upgrade */
$upgrade = $this->get('ps_metrics.module.upgrade');
return new Response($upgrade->upgradeMetrics(), 200, [
'Content-Type' => 'application/json',
]);
}
/**
* Get all existing Google Tags in Front End shop and retrieve them
*
* @return Response
*/
public function getExistingGoogleTags(): Response
{
/** @var ConfigurationRepository $configurationRepository */
$configurationRepository = $this->get(
'ps_metrics.repository.configuration'
);
/** @var ShopHelper $shopHelper */
$shopHelper = $this->get('ps_metrics.helper.shop');
/** @var PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->get('ps_metrics.helper.prestashop');
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
/** @var GoogleTagProvider $googleTagProvider */
$googleTagProvider = $this->get('ps_metrics.provider.googletag');
// If google Tag is already set as linked, we avoid to retrieve the Google Tag
// Only the PSL will tell us if we should retrieve TAGS again
if (true === $configurationRepository->getGoogleTagLinkedValue()) {
return new Response('true');
}
$currentShop = $shopHelper->getShopUrl($prestashopHelper->getShopId());
$googleTagProvider->setBaseUrl($currentShop['url']);
return new Response(
$jsonHelper->jsonEncode([
'analytics' => $googleTagProvider->findGoogleTagsAnalytics(),
'manager' => $googleTagProvider->findGoogleTagsManager(),
]),
200,
['Content-Type' => 'application/json']
);
}
/**
* Select a Google Account for psessentials
* Need webPropertyId and viewId. Returns 201 if done
*
* @return Response
*/
public function selectAccountAnalytics(): Response
{
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
/** @var AnalyticsApi $apiAnalytics */
$apiAnalytics = $this->get('ps_metrics.api.analytics');
/** @var SelectAccountAnalytics $serviceProcessSelectAccountAnalytics */
$serviceProcessSelectAccountAnalytics = $this->get(
'ps_metrics.validation.processselectaccountanalytics'
);
$validateData = $serviceProcessSelectAccountAnalytics->validate([
'webPropertyId' => $this->request->request->get(
'webPropertyId',
''
),
'viewId' => $this->request->request->get('viewId', ''),
]);
if (false === $validateData) {
return new Response(
$jsonHelper->jsonEncode(['success' => false]),
200,
['Content-Type' => 'application/json']
);
}
$serviceResult = $apiAnalytics->setAccountSelection([
'webPropertyId' => $this->request->request->get(
'webPropertyId',
''
),
'viewId' => $this->request->request->get('viewId', ''),
]);
if (false === $serviceResult) {
return new Response(
$jsonHelper->jsonEncode([
'success' => false,
]),
200,
['Content-Type' => 'application/json']
);
}
return new Response(
$jsonHelper->jsonEncode([
'success' => true,
]),
200,
['Content-Type' => 'application/json']
);
}
/**
* Google Analytics Logout must enable disabled modules, unsubscribe from PsEssentials
* Also, it must reset configuration's values
*
* @return Response
*/
public function ajaxProcessLogOut(): Response
{
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
/** @var Uninstall $uninstallGoogleAccount */
$uninstallGoogleAccount = $this->get('ps_metrics.module.uninstall');
if (false === $uninstallGoogleAccount->unsubscribePsEssentials()) {
return new Response(
$jsonHelper->jsonEncode([
'success' => false,
'googleLinked' => true,
]),
200,
['Content-Type' => 'application/json']
);
}
if (false === $uninstallGoogleAccount->resetConfigurationValues()) {
return new Response(
$jsonHelper->jsonEncode([
'success' => false,
'googleLinked' => true,
]),
200,
['Content-Type' => 'application/json']
);
}
return new Response(
$jsonHelper->jsonEncode([
'success' => true,
'googleLinked' => false,
]),
200,
['Content-Type' => 'application/json']
);
}
/**
* Toggle dashboard modules
*
* @return Response
*/
public function ajaxProcessToggleDashboardModules(): Response
{
/** @var NativeStatsHandler $nativeStats */
$nativeStats = $this->get('ps_metrics.handler.native.stats');
$nativeStats->toggleNativeStats();
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
return new Response(
$jsonHelper->jsonEncode([
'success' => true,
'modulesIsEnabled' => $nativeStats->nativeStatsIsEnabled(),
]),
200,
['Content-Type' => 'application/json']
);
}
/**
* Google Analytics Logout must enable disabled modules, unsubscribe from PsEssentials
* Also, it must reset configuration's values
*
* @return Response
*/
public function ajaxProcessRefreshGA(): Response
{
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
/** @var AnalyticsApi $apiAnalytics */
$apiAnalytics = $this->get('ps_metrics.api.analytics');
$serviceResult = $apiAnalytics->refreshGA();
if (!empty($serviceResult['error'])) {
return new Response(
$jsonHelper->jsonEncode([
'success' => false,
'message' => $serviceResult['error'],
]),
200,
['Content-Type' => 'application/json']
);
}
return new Response(
$jsonHelper->jsonEncode([
'success' => true,
]),
200,
['Content-Type' => 'application/json']
);
}
/**
* Google Analytics Property List
*
* @return Response
*/
public function ajaxProcessListProperty(): Response
{
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
/** @var AnalyticsAccountsListProvider $analyticsAccountListProvider */
$analyticsAccountListProvider = $this->get(
'ps_metrics.provider.analyticsaccountslist'
);
$serviceResult = $analyticsAccountListProvider->getAccountsList();
if (empty($serviceResult)) {
return new Response(
$jsonHelper->jsonEncode([
'success' => false,
'listProperty' => [],
'error' => 'No property list on this account',
]),
200,
['Content-Type' => 'application/json']
);
}
return new Response(
$jsonHelper->jsonEncode([
'success' => true,
'listProperty' => $serviceResult,
]),
200,
['Content-Type' => 'application/json']
);
}
/**
* Init Billing Free
*
* @return Response
*/
public function ajaxProcessBillingFree(): Response
{
/** @var JsonHelper $jsonHelper */
$jsonHelper = $this->get('ps_metrics.helper.json');
/** @var PsAccounts $accounts */
$accounts = $this->get('ps_accounts.facade');
$billingService = $accounts->getPsBillingService();
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip_address = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
//whether ip is from proxy
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
//whether ip is from remote address
$ip_address = $_SERVER['REMOTE_ADDR'];
}
/** @var \Ps_metrics $module */
$module = \Module::getInstanceByName('ps_metrics');
/*
in some case, $ip_address contain list of ip address...
and cause some billings problems
*/
$ip_address = explode(',', $ip_address)[0];
$result = $billingService->subscribeToFreePlan(
$module->name,
'metrics-free',
false,
trim($ip_address)
);
if (empty($result)) {
return new Response(
$jsonHelper->jsonEncode([
'success' => false,
]),
200,
['Content-Type' => 'application/json']
);
}
return new Response(
$jsonHelper->jsonEncode([
'success' => true,
'billing' => $result,
]),
200,
['Content-Type' => 'application/json']
);
}
/**
* Change shop context
*
* @return Response
*/
public function ajaxProcessChangeShopContext(): Response
{
/** @var PrestaShopHelper $prestashopHelper */
$prestashopHelper = $this->get('ps_metrics.helper.prestashop');
$link = $prestashopHelper->getLink();
\Tools::redirectAdmin(
$link->getAdminLink('MetricsController', true, [
'route' => 'metrics_page',
]) . '#/settings'
);
return new Response();
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,115 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Handler;
class GuzzleApiResponseExceptionHandler
{
/**
* @var string
*/
private $reasonPhrase;
/**
* @var mixed
*/
private $body;
/**
* @var int
*/
private $statusCode;
/**
* @return string
*/
public function getReasonPhrase(): string
{
return $this->reasonPhrase;
}
/**
* @param string $reasonPhrase
*
* @return void
*/
public function setReasonPhrase(string $reasonPhrase): void
{
$this->reasonPhrase = $reasonPhrase;
}
/**
* @return mixed
*/
public function getBody()
{
return $this->body;
}
/**
* @param mixed $body
*
* @return void
*/
public function setBody($body): void
{
$this->body = $body;
}
/**
* @return int
*/
public function getStatusCode(): int
{
return $this->statusCode;
}
/**
* @param int $statusCode
*
* @return void
*/
public function setStatusCode(int $statusCode): void
{
$this->statusCode = $statusCode;
}
/**
* GuzzleApiResponseExceptionHandler constructor.
*/
public function __construct()
{
}
/**
* @param string $errorMessage
*
* @return $this
*/
public function get(string $errorMessage): self
{
$this->setStatusCode(500);
$this->setBody(null);
$this->setReasonPhrase($errorMessage);
return $this;
}
}

View File

@@ -0,0 +1,372 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Handler;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
use PrestaShop\Module\Ps_metrics\Tracker\Segment;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use PrestaShopDatabaseException;
use PrestaShopException;
class NativeStatsHandler
{
const METRICS_STATS_CONTROLLER = 'AdminMetricsController';
const NATIVE_STATS_CONTROLLER = 'AdminStats';
const NATIVE_STATS_CONTROLLER_COPY = 'AdminMetricsLegacyStatsController';
/**
* @var \Ps_metrics
*/
private $module;
/**
* @var PsAccounts
*/
private $psAccountsFacade;
/**
* @var ConfigurationRepository
*/
private $configurationRepository;
/**
* @var array
*/
private $moduleList = [
'dashactivity',
'dashtrends',
'dashgoals',
'dashproducts',
];
/**
* NativeStatsHandler constructor.
*
* @param \Ps_metrics $module
* @param PsAccounts $psAccountsFacade
* @param ConfigurationRepository $configurationRepository
*/
public function __construct(
\Ps_metrics $module,
PsAccounts $psAccountsFacade,
ConfigurationRepository $configurationRepository
) {
$this->module = $module;
$this->psAccountsFacade = $psAccountsFacade;
$this->configurationRepository = $configurationRepository;
}
/**
* Run when installing the module
*
* @return bool
*/
public function install(): bool
{
if (\Module::isInstalled('ps_accounts')) {
$psAccountsService = $this->psAccountsFacade->getPsAccountsService();
if ($psAccountsService->isAccountLinked()) {
return $this->replaceLegacyMetricsController() &&
$this->disableNativeStatsModules();
}
}
return $this->installMetricsControllerSideBySideWithNativeStats();
}
/**
* Run this install on the settings controller
* It will check if the user is onboarded for the first time and disable native stats if it is the case
*
* @return bool
*/
public function installIfIsOnboarded(): bool
{
if (!\Module::isInstalled('ps_accounts')) {
return false;
}
$psAccountsService = $this->psAccountsFacade->getPsAccountsService();
if (!$psAccountsService->isAccountLinked()) {
return false;
}
if ($this->configurationRepository->getFirstTimeOnboarded()) {
return false;
}
$this->configurationRepository->saveFirstTimeOnboarded(true);
return $this->replaceLegacyMetricsController() &&
$this->disableNativeStatsModules();
}
/**
* Active or disable native stats
*
* @return bool
*/
public function toggleNativeStats(): bool
{
if ($this->nativeStatsIsEnabled()) {
return $this->replaceLegacyMetricsController() &&
$this->disableNativeStatsModules();
}
return $this->installMetricsControllerSideBySideWithNativeStats() &&
$this->enableNativeStatsModules();
}
/**
* Run when uninstalling the module
*
* @return bool
*/
public function uninstall(): bool
{
$legacyStatsTab = new \Tab(
\Tab::getIdFromClassName(self::NATIVE_STATS_CONTROLLER)
);
if (!$legacyStatsTab->active) {
$legacyStatsTab->active = true;
$legacyStatsTab->save();
}
return $this->deleteAllStatsController() &&
$this->enableNativeStatsModules();
}
/**
* Replace legacy stats controller by metrics controller
*
* @return bool
*/
private function replaceLegacyMetricsController(): bool
{
$this->deleteAllStatsController();
$legacyStatsTab = new \Tab(
\Tab::getIdFromClassName(self::NATIVE_STATS_CONTROLLER)
);
$legacyStatsTab->active = false;
$tab = new \Tab();
$tab->name = $legacyStatsTab->name;
$tab->class_name = self::METRICS_STATS_CONTROLLER;
$tab->active = true;
$tab->module = $this->module->name;
$tab->icon = 'assessment';
$tab->id_parent = $legacyStatsTab->id_parent;
return $legacyStatsTab->save() && $tab->add();
}
/**
* Install metrics controller side by side with native stats controller
*
* @return bool
*/
private function installMetricsControllerSideBySideWithNativeStats(): bool
{
$this->deleteAllStatsController();
$legacyStatsTab = new \Tab(
\Tab::getIdFromClassName(self::NATIVE_STATS_CONTROLLER)
);
$legacyStatsTab->active = true;
$nativeStatsTab = new \Tab();
$nativeStatsTab->name = $legacyStatsTab->name;
$nativeStatsTab->class_name = self::NATIVE_STATS_CONTROLLER_COPY;
$nativeStatsTab->active = true;
$nativeStatsTab->module = $this->module->name;
$nativeStatsTab->id_parent = (int) $legacyStatsTab->id;
$metricsTab = new \Tab();
$metricsTab->name = array_fill_keys(
\Language::getIDs(false),
$this->module->displayName
);
$metricsTab->class_name = self::METRICS_STATS_CONTROLLER;
$metricsTab->active = true;
$metricsTab->module = $this->module->name;
$metricsTab->id_parent = (int) $legacyStatsTab->id;
return $legacyStatsTab->save() &&
$nativeStatsTab->add() &&
$metricsTab->add();
}
/**
* Delete all stats controller
*
* @return bool
*
* @throws PrestaShopException
* @throws PrestaShopDatabaseException
*/
private function deleteAllStatsController(): bool
{
$metricsTab = new \Tab(
\Tab::getIdFromClassName(self::METRICS_STATS_CONTROLLER)
);
$nativeStatsTab = new \Tab(
\Tab::getIdFromClassName(self::NATIVE_STATS_CONTROLLER_COPY)
);
if ($metricsTab->id) {
$metricsTab->delete();
}
if ($nativeStatsTab->id) {
$nativeStatsTab->delete();
}
return true;
}
/**
* Enable back dashboard modules
*
* @return bool
*/
public function enableNativeStatsModules(): bool
{
// retrieve module list to enable
$moduleListToEnable = $this->configurationRepository->getDashboardModulesToToggleAsArray();
// if the module list is empty, do nothing
if (empty($moduleListToEnable) || !is_array($moduleListToEnable)) {
return true;
}
foreach ($moduleListToEnable as $moduleName) {
$module = \Module::getInstanceByName($moduleName);
if (false !== $module) {
$module->enable();
}
}
// now that modules has been enabled back again, reset the list from database
$this->configurationRepository->saveDashboardModulesToToggle();
/** @var Segment $segment */
$segment = $this->module->getService('ps_metrics.tracker.segment');
if (!empty($segment)) {
$segment->setMessage('[MTR] Enable native stats');
$segment->track();
}
return true;
}
/**
* Disable dashboard modules
*
* @return bool
*/
public function disableNativeStatsModules(): bool
{
// get module to disable
$modulesToDisable = $this->getNativeStatsModulesToToggle();
$disabledModuleList = [];
foreach ($modulesToDisable as $moduleName => $isEnabled) {
// only disable modules that is currently enable
if ($isEnabled) {
$module = \Module::getInstanceByName($moduleName);
if (false !== $module) {
$module->disable();
array_push($disabledModuleList, $moduleName);
}
}
}
// save to database the list of module that has been disable by metrics in order to be able
// to turn it on if needed
$this->configurationRepository->saveDashboardModulesToToggle(
$disabledModuleList
);
/** @var Segment $segment */
$segment = $this->module->getService('ps_metrics.tracker.segment');
$segment->setMessage('[MTR] Disable native stats');
$segment->track();
return true;
}
/**
* Get the current state of dashboard modules
* We presuming that modules is enabled if the disabled module list in database is empty
*
* @return bool
*/
public function nativeStatsModulesIsEnabled(): bool
{
$modulesToToggle = $this->configurationRepository->getDashboardModulesToToggleAsArray();
if (!is_array($modulesToToggle) && '' === $modulesToToggle) {
return true;
}
return false;
}
/**
* Check if native stats is enabled or disabled
*
* @return bool
*
* @throws PrestaShopException
* @throws PrestaShopDatabaseException
*/
public function nativeStatsIsEnabled(): bool
{
$nativeStatsTab = new \Tab(
\Tab::getIdFromClassName(self::NATIVE_STATS_CONTROLLER)
);
return (bool) $nativeStatsTab->active;
}
/**
* Create a list of module from the default list in order to know which modules is
* currently enabled or disabled on the shop
*
* @return array
*/
private function getNativeStatsModulesToToggle(): array
{
$modules = [];
foreach ($this->moduleList as $moduleName) {
$isModuleEnabled = \Module::isEnabled($moduleName);
$modules[$moduleName] = $isModuleEnabled;
}
return $modules;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,46 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
class ApiHelper
{
/**
* @param array $period
*
* @return array
*/
public function getLastedPeriodRange(array $period): array
{
$startDate = strtotime($period['startDate']);
$endDate = strtotime($period['endDate']);
$dateDiffSeconds = ($endDate - $startDate);
//if diff < 1 day, set 1 day
$dateDiffSeconds = ($dateDiffSeconds < 86400) ? 8640 : $dateDiffSeconds;
return [
'startDate' => date('Y-m-d', $startDate - $dateDiffSeconds),
'endDate' => $period['startDate'],
];
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
use PrestaShop\Module\Ps_metrics\Config\Env;
class ConfigHelper
{
/**
* @var Env
*/
private $env;
/**
* __construct
*
* @param Env $env
*
* @return void
*/
public function __construct(Env $env)
{
$this->env = $env;
}
/**
* Get webservice url
*
* @return string
*/
public function getApiBaseUrl(): string
{
return $this->env->get('PHP_METRICS_API_URL');
}
/**
* Get segment api key
*
* @return string
*/
public function getSegmentApiKey(): string
{
return $this->env->get('SEGMENT_API_KEY');
}
/**
* Get metrics cdn url
*
* @return string
*/
public function getPsMetricsCdnUrl(): string
{
return $this->env->get('PS_METRICS_CDN_URL');
}
/**
* Get metrics cdn enabled
*
* @return bool
*/
public function getUseLocalVueApp(): bool
{
return ('false' === $this->env->get('USE_LOCAL_VUE_APP')) ? false : true;
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
use Db;
class DbHelper
{
/**
* Retrieve cache data if exist or request a "dbRequestType"
*
* @param string $dbRequestType
* @param string $sql
*
* @return mixed
*/
private function request(string $dbRequestType, string $sql)
{
return Db::getInstance()->{$dbRequestType}($sql);
}
/**
* Executes return the result of $sql as array by requesting
*
* @param string $sql
*
* @return array
*/
public function executeS(string $sql): array
{
return $this->request('executeS', $sql);
}
/**
* Returns a value from the first row, first column of a SELECT query
*
* @param string $sql
*
* @return mixed
*/
public function getValue(string $sql)
{
return $this->request('getValue', $sql);
}
/**
* Returns an associative array containing the first row of the query This function automatically adds "LIMIT 1" to the query.
*
* @param string $sql
*
* @return array
*/
public function getRow(string $sql): array
{
return $this->request('getRow', $sql);
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
class JsonHelper
{
/**
* Encode the data to json and check and force the return to empty string if false
*
* @param mixed $data
*
* @return string
*/
public function jsonEncode($data): string
{
$json = json_encode($data);
if (empty($data)) {
$json = json_encode($data, JSON_FORCE_OBJECT);
}
if (false !== $json) {
return $json;
}
return '';
}
/**
* Check if the json is valid and returns an empty data if not
*
* @param string|false $json
* @param bool $assoc
*
* @return array $data
*/
public function jsonDecode($json, bool $assoc = true): array
{
if ($json) {
$data = json_decode($json, $assoc);
if (JSON_ERROR_NONE === json_last_error()) {
return $data;
}
}
return [];
}
/**
* Check if string is JSON
*
* @param string $string
*
* @return bool
*/
public function isJson(string $string): bool
{
json_decode($string);
return json_last_error() == JSON_ERROR_NONE;
}
}

View File

@@ -0,0 +1,178 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
use ModuleCore;
class ModuleHelper
{
/**
* @param string $moduleName
*
* @return bool
*/
public function isInstalled(string $moduleName): bool
{
return \ModuleCore::isInstalled($moduleName);
}
/**
* @param string $moduleName
*
* @return bool
*/
public function isEnabled(string $moduleName): bool
{
return \ModuleCore::isEnabled($moduleName);
}
/**
* @param string $moduleName
*
* @return false|ModuleCore
*/
public function getInstanceByName(string $moduleName): mixed
{
return ModuleCore::getInstanceByName($moduleName);
}
/**
* returns the installation link of the module if it is not installed. If installed, returns an empty string
*
* @param string $moduleName
*
* @return string
*/
public function getInstallLink(string $moduleName): string
{
if (true === $this->isInstalled($moduleName)) {
return '';
}
$router = $this->get('router');
return substr(\Tools::getShopDomainSsl(true) . __PS_BASE_URI__, 0, -1) .
$router->generate('admin_module_manage_action', [
'action' => 'install',
'module_name' => $moduleName,
]);
}
/**
* Override of native function to always retrieve Symfony container instead of legacy admin container on legacy context.
*
* @param string $serviceName
*
* @return mixed
*/
private function get(string $serviceName)
{
$container = \PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance();
if (empty($container)) {
throw new \PrestaShopException('Symfony container is null or invalid');
}
return $container->get($serviceName);
}
/**
* returns the enable link of the module if it is not enabled. If enabled, returns an empty string
*
* @param string $moduleName
*
* @return string
*/
public function getEnableLink(string $moduleName): string
{
if (true === $this->isEnabled($moduleName)) {
return '';
}
$router = $this->get('router');
return substr(\Tools::getShopDomainSsl(true) . __PS_BASE_URI__, 0, -1) .
$router->generate('admin_module_manage_action', [
'action' => 'enable',
'module_name' => $moduleName,
]);
}
/**
* returns the update link of the module if it is not enabled. If enabled, returns an empty string
*
* @param string $moduleName
*
* @return string
*/
public function getUpdateLink(string $moduleName): string
{
$router = $this->get('router');
return substr(\Tools::getShopDomainSsl(true) . __PS_BASE_URI__, 0, -1) .
$router->generate('admin_module_manage_action', [
'action' => 'upgrade',
'module_name' => $moduleName,
]);
}
/**
* get ps_analytics module version
*
* @param string $moduleName
*
* @return string
*/
public function getModuleVersion(string $moduleName): string
{
if (false === $this->isInstalled($moduleName)) {
return '0.0.0';
}
$module = \Module::getInstanceByName($moduleName);
if (false === $module) {
return '0.0.0';
}
return $module->version;
}
/**
* Build informations about module
*
* @param string $moduleName
*
* @return array
*/
public function buildModuleInformations(string $moduleName): array
{
return [
'isInstalled' => $this->isInstalled($moduleName),
'isEnabled' => $this->isEnabled($moduleName),
'linkEnable' => $this->getEnableLink($moduleName),
'linkInstall' => $this->getInstallLink($moduleName),
'linkUpdate' => $this->getUpdateLink($moduleName),
'version' => $this->getModuleVersion($moduleName),
];
}
}

View File

@@ -0,0 +1,172 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
/**
* Class MultishopHelper used to get information from PrestaShop Multishop Context
*/
class MultishopHelper
{
/**
* @var bool
*/
private $isMultishopActive = false;
/**
* @var int
*/
private $context = null;
/**
* @var int
*/
private $selectedShopId = null;
public function __construct()
{
$this->isMultishopActive = \Shop::isFeatureActive();
$this->context = \Shop::getContext();
$context = \Context::getContext();
if (!empty($context) && !empty($context->shop)) {
$this->selectedShopId = (int) $context->shop->id;
}
}
/**
* Shop context
*
* @return int
*/
public function getShopContext(): int
{
return $this->context;
}
/**
* Get multishop active feature is enabled
*
* @return bool
*/
public function isMultishopActive(): bool
{
return $this->isMultishopActive;
}
/**
* ID of selected shop
*
* @return int
*/
public function getSelectedShopId(): int
{
return $this->selectedShopId;
}
/**
* Current shop
*
* @return array|bool
*/
public function getSelectedShop()
{
return \Shop::getShop($this->getSelectedShopId());
}
/**
* Check if shop context is shop
*
* @return bool
*/
public function isShopContext(): bool
{
if ($this->isMultishopActive() && $this->getShopContext() !== \Shop::CONTEXT_SHOP) {
return false;
}
return true;
}
/**
* Check if shop context is group
*
* @return bool
*/
public function isGroupContext(): bool
{
if ($this->isMultishopActive() && $this->getShopContext() !== \Shop::CONTEXT_GROUP) {
return false;
}
return true;
}
/**
* Check if shop context is all
*
* @return bool
*/
public function isAllContext(): bool
{
if ($this->isMultishopActive() && $this->getShopContext() !== \Shop::CONTEXT_ALL) {
return false;
}
return true;
}
/**
* Get all active shops for all shops or for a group
*
* @return array
*/
public function getAllShopsOrGroupShops(): array
{
if ($this->isMultishopActive() && $this->isGroupContext()) {
$allShops = \Shop::getShops(true, $this->getSelectedShopId());
} else {
$allShops = \Shop::getShops(false);
}
foreach ($allShops as &$shop) {
$shop['group'] = \Shop::getGroupFromShop($shop['id_shop'], false);
}
return $allShops;
}
/**
* get Shop context as string
*
* @return string
*/
public function getShopContextLitteral(): string
{
if ($this->isShopContext()) {
return 'SHOP';
} elseif ($this->isGroupContext()) {
return 'GROUP';
}
return 'ALL';
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
class NumberHelper
{
/**
* Prevent division by 0
*
* @param int|float $number
* @param int|float $byNumber
*
* @return int|float
*/
public function division($number, $byNumber)
{
if (0 === $number) {
return 0;
}
if (0 === $byNumber) {
$byNumber = 1;
}
return $number / $byNumber;
}
/**
* @param float $all
* @param float $find
*
* @return float|int
*/
public function percent($all, $find)
{
// To prevent division by 0
if ($all != 0 && $find == 0) {
return 100;
}
if ($all == 0) {
return 0;
}
// Get the percentage of abandoned carts
$percent = 100 - ($find / $all) * 100;
return round($percent, 2);
}
}

View File

@@ -0,0 +1,217 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
use Employee;
/**
* Class PrestaShopHelper used to get information from PrestaShop Context
*/
class PrestaShopHelper
{
/**
* @var \Context
*/
private $context;
/**
* PrestaShopHelper constructor.
*
* @return void
*/
public function __construct()
{
$context = \Context::getContext();
if (empty($context)) {
throw new \PrestaShopException('Context is null or invalid');
}
$this->context = $context;
}
/**
* Get the isoCode from the context language, if null, send 'en' as default value
*
* @return string
*/
public function getLanguageIsoCode(): string
{
return $this->context->language !== null ? $this->context->language->iso_code : 'en';
}
/**
* Get current language
*
* @return mixed
*/
public function getLanguage(): mixed
{
return $this->context->language;
}
/**
* Get current language code
*
* @return string
*/
public function getLanguageCode(): string
{
return $this->context->language !== null ? $this->context->language->language_code : 'en';
}
/**
* Get currency code
*
* @return string
*/
public function getCurrencyIsoCode(): string
{
return $this->context->currency !== null ? $this->context->currency->iso_code : 'EUR';
}
/**
* Get current locale
*
* @return string
*
* @todo implement currentLocale for version > 1.7.3.X
*/
public function getCurrentLocale(): string
{
return $this->getLanguageIsoCode();
}
/**
* Get controller name
*
* @return string
*/
public function getControllerName(): string
{
/** @var \AdminControllerCore $adminController */
$adminController = $this->context->controller;
return (!empty($adminController->controller_name)) ? $adminController->controller_name : '';
}
/**
* Get context link
*
* @return \Link
*/
public function getLink()
{
return $this->context->link;
}
/**
* Get shop id
*
* @return int
*/
public function getShopId(): int
{
return (int) $this->context->shop->id;
}
/**
* Get shop domain
*
* @return string
*/
public function getShopDomain(): string
{
return $this->context->shop->domain;
}
/**
* Get employee from context
*
* @return \Employee
*
* @throws \PrestaShopException
*/
public function getEmployee()
{
$employee = $this->context->employee;
if (empty($employee)) {
throw new \PrestaShopException('Employee is null or invalid');
}
return $employee;
}
/**
* @return int
*/
public function getEmployeeIdLang(): int
{
return (int) $this->getEmployee()->id_lang;
}
/**
* @return string
*/
public function getEmployeeEmail(): string
{
return $this->getEmployee()->email;
}
/**
* Get controller link without token
*
* @param string $controller
* @param string $route
*
* @return string
*/
public function getLinkWithoutToken($controller, $route): string
{
$controllerLink = $this->getLink()->getAdminLink($controller, true, ['route' => $route]);
$pos = strpos($controllerLink, '?');
if (false === $pos) {
return $controllerLink;
}
return substr($controllerLink, 0, $pos);
}
/**
* Get token from controller link
*
* @param string $controller
* @param string $route
*
* @return string
*/
public function getTokenFromAdminLink($controller, $route): string
{
$controllerLink = $this->getLink()->getAdminLink($controller, true, ['route' => $route]);
parse_str((string) parse_url($controllerLink, PHP_URL_QUERY), $result);
return $result['_token'];
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
use Segment;
class SegmentHelper
{
/**
* @var ConfigHelper
*/
private $configHelper;
/**
* SegmentHelper constructor.
*
* @param ConfigHelper $configHelper
*
* @return void
*/
public function __construct(ConfigHelper $configHelper)
{
$this->configHelper = $configHelper;
}
/**
* Init segment
*
* @return void
*/
public function init(): void
{
Segment::init($this->configHelper->getSegmentApiKey());
}
/**
* @param array $message
*
* @return void
*/
public function track($message): void
{
Segment::track($message);
}
/**
* Flush segment
*
* @return void
*/
public function flush(): void
{
Segment::flush();
}
}

View File

@@ -0,0 +1,167 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
class ShopHelper
{
/**
* @var ToolsHelper
*/
private $toolsHelper;
/**
* Shop Helper constructor.
*
* @param ToolsHelper $toolsHelper
*
* @return void
*/
public function __construct(ToolsHelper $toolsHelper)
{
$this->toolsHelper = $toolsHelper;
}
/**
* @param int $shopId
*
* @return array
*/
public function getShop($shopId): array
{
$shop = \Shop::getShop($shopId);
if (!is_array($shop)) {
return [];
}
return $shop;
}
/**
* @param bool $active
* @param int|null $id_shop_group
* @param false $get_as_list_id
*
* @return array
*/
public function getShops(bool $active = true, $id_shop_group = null, bool $get_as_list_id = false): array
{
return \Shop::getShops($active, $id_shop_group, $get_as_list_id);
}
/**
* @return int|null
*/
public function getContextShopGroupID()
{
return \Shop::getContextShopGroupID();
}
/**
* @return int
*/
public function getContext(): int
{
return \Shop::getContext();
}
/**
* @param bool $share
* @param string|null $alias
*
* @return string
*/
public function addSqlRestriction(bool $share = false, string $alias = null): string
{
$share_ = ($share) ? 1 : 0;
return \Shop::addSqlRestriction($share_, $alias);
}
/**
* @return int|null
*/
public function getShopId()
{
return \Shop::getContextShopID();
}
/**
* Get one Shop Url
*
* @param int $shopId
*
* @return array
*/
public function getShopUrl($shopId)
{
$shop = $this->getShop($shopId);
$protocol = $this->getShopsProtocolInformations();
return [
'id_shop' => $shop['id_shop'],
'domain' => $shop[$protocol['domain_type']],
'url' => $protocol['protocol'] . $shop[$protocol['domain_type']] . $shop['uri'],
];
}
/**
* Get all shops Urls
*
* @return array
*/
public function getShopsUrl()
{
$shopList = $this->getShops();
$protocol = $this->getShopsProtocolInformations();
$urlList = [];
foreach ($shopList as $shop) {
$urlList[] = [
'id_shop' => $shop['id_shop'],
'url' => $protocol['protocol'] . $shop[$protocol['domain_type']] . $shop['uri'],
];
}
return $urlList;
}
/**
* getShopsProtocol
*
* @return array
*/
protected function getShopsProtocolInformations()
{
if (true === $this->toolsHelper->usingSecureMode()) {
return [
'domain_type' => 'domain_ssl',
'protocol' => 'https://',
];
}
return [
'domain_type' => 'domain',
'protocol' => 'http://',
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Helper;
use Tools;
class ToolsHelper
{
/**
* @param bool $http
*
* @return string
*/
public function getShopDomainSsl(bool $http): string
{
return Tools::getShopDomainSsl($http);
}
/**
* @return bool
*/
public function usingSecureMode(): bool
{
return Tools::usingSecureMode();
}
/**
* @param string $value
* @param false|mixed $default_value
*
* @return false|mixed
*/
public function getValue(string $value, $default_value = false)
{
return Tools::getValue($value, $default_value);
}
/**
* @param string $url
*
* @return void
*/
public function redirectAdmin(string $url): void
{
Tools::redirectAdmin($url);
}
/**
* @param string $url
*
* @return void
*/
public function redirect(string $url): void
{
Tools::redirect($url);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,119 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics;
use PrestaShop\Module\Ps_metrics\Config\Env;
use PrestaShop\Module\Ps_metrics\Handler\NativeStatsHandler;
use PrestaShop\Module\Ps_metrics\Helper\ConfigHelper;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\SegmentHelper;
use PrestaShop\Module\Ps_metrics\Helper\ShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\ToolsHelper;
use PrestaShop\Module\Ps_metrics\Module\Install;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
use PrestaShop\Module\Ps_metrics\Repository\HookModuleRepository;
use PrestaShop\Module\Ps_metrics\Tracker\Segment;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use PrestaShop\PsAccountsInstaller\Installer\Installer;
class LegacyModuleInstaller
{
/**
* @var \Ps_metrics
*/
private $module;
/**
* @var ConfigurationRepository
*/
private $configurationRepository;
public function __construct(\Ps_metrics $module)
{
$this->module = $module;
$this->configurationRepository = (new ConfigurationRepository(
(new PrestaShopHelper())
));
}
/**
* The service container is not available during the install process.
* This method is used to manually instantiate PrestaShop\Module\Ps_metrics\Module\Install required
* at module install
*
* Code to delete once the issue was fixed on PrestaShop side
*
* @return Install
*/
public function legacyModuleInstaller()
{
return new Install(
$this->module,
$this->configurationRepository,
(new HookModuleRepository())
);
}
/**
* The service container is not available during the install process.
* This method is used to manually instantiate PrestaShop\Module\Ps_metrics\Helper\SegmentHelper required
* at module install
*
* Code to delete once the issue was fixed on PrestaShop side
*
* @return Segment
*/
public function legacyModuleInstallerSegment()
{
return new Segment(
(new SegmentHelper(
(new ConfigHelper(
(new Env($this->module))
))
)),
(new PrestaShopHelper()),
(new ShopHelper(
(new ToolsHelper())
))
);
}
/**
* The service container is not available during the install process.
* This method is used to manually instantiate PrestaShop\Module\Ps_metrics\Helper\SegmentHelper required
* at module install
*
* Code to delete once the issue was fixed on PrestaShop side
*
* @return NativeStatsHandler
*/
public function legacyNativeStatsHandler()
{
return new NativeStatsHandler(
$this->module,
(new PsAccounts(
(new Installer('5.0'))
)),
$this->configurationRepository
);
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Middleware;
use PrestaShop\Module\Ps_metrics\Helper\JsonHelper;
class CheckResponseMiddleware extends Middleware
{
/**
* @var JsonHelper
*/
private $jsonHelper;
/**
* CheckResponseAnalyticsMiddleware constructor.
*
* @param JsonHelper $jsonHelper
*
* @return void
*/
public function __construct(JsonHelper $jsonHelper)
{
$this->jsonHelper = $jsonHelper;
}
/**
* @param mixed $response
*
* @return array
*/
public function execute($response): array
{
$responseFormatted = [
'code' => $response->getStatusCode(),
'body' => [],
'error' => '',
];
if (
200 != $response->getStatusCode() &&
201 != $response->getStatusCode()
) {
$responseFormatted['error'] = $response->getReasonPhrase();
}
if (!empty($response->getBody())) {
$content = $response->getBody()->getContents();
if (!empty($content) && $this->jsonHelper->isJson($content)) {
$responseFormatted['body'] = $this->jsonHelper->jsonDecode($content, true);
} else {
$responseFormatted['body'] = $content;
}
}
return parent::execute($responseFormatted);
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Middleware;
use PrestaShop\Module\Ps_metrics\Adapter\LoggerAdapter;
class LogMiddleware extends Middleware
{
/**
* @var LoggerAdapter
*/
private $loggerAdapter;
public function __construct(LoggerAdapter $loggerAdapter)
{
$this->loggerAdapter = $loggerAdapter;
}
/**
* @param array $response
*
* @return array
*/
public function execute($response): array
{
if (!empty($response['error'])) {
$this->loggerAdapter->error($response['error'], ['error_code' => $response['code']]);
}
// Do nothing for the moment
return parent::execute($response);
}
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Middleware;
abstract class Middleware
{
/**
* @var Middleware
*/
private $next;
/**
* @param Middleware $next
*
* @return Middleware
*/
public function linkWith(Middleware $next): Middleware
{
$this->next = $next;
return $next;
}
/**
* @param array $response
*
* @return array
*/
public function execute($response): array
{
if (empty($this->next)) {
return $response;
}
return $this->next->execute($response);
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Middleware;
class ResponseMiddleware extends Middleware
{
/**
* @param array $response
*
* @return array
*/
public function execute($response): array
{
return parent::execute($response);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Middleware;
class SentryMiddleware extends Middleware
{
/**
* @param array $response
*
* @return array
*/
public function execute($response): array
{
// do nothing for the moment
return parent::execute($response);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,187 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Module;
use PrestaShop\Module\Ps_metrics\Helper\ModuleHelper;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\ToolsHelper;
class GAInstaller
{
/**
* @var string
*/
private $moduleName = 'ps_googleanalytics';
/**
* @var ModuleHelper
*/
private $moduleHelper;
/**
* @var ToolsHelper
*/
private $toolsHelper;
/**
* @var PrestashopHelper
*/
private $prestashopHelper;
/**
* @var \Symfony\Component\DependencyInjection\ContainerInterface|null
*/
protected $container;
/**
* GAInstaller constructor.
*
* @param ModuleHelper $moduleHelper
* @param ToolsHelper $toolsHelper
* @param PrestaShopHelper $prestashopHelper
*
* @return void
*/
public function __construct(
ModuleHelper $moduleHelper,
ToolsHelper $toolsHelper,
PrestaShopHelper $prestashopHelper
) {
$this->moduleHelper = $moduleHelper;
$this->toolsHelper = $toolsHelper;
$this->prestashopHelper = $prestashopHelper;
}
/**
* Check if google analytics module is installed or not
*
* @return bool
*/
public function isInstalled(): bool
{
return $this->moduleHelper->isInstalled($this->moduleName);
}
/**
* Check if google analytics module is enabled or not
*
* @return bool
*/
public function isEnabled(): bool
{
return $this->moduleHelper->isEnabled($this->moduleName);
}
/**
* returns the installation link of the ps_googleanalytics module if it is not installed. If installed, returns an empty string
*
* @return string
*/
public function getInstallLink(): string
{
if (true === $this->moduleHelper->isInstalled($this->moduleName)) {
return '';
}
$router = $this->get('router');
return substr($this->toolsHelper->getShopDomainSsl(true) . __PS_BASE_URI__, 0, -1) . $router->generate('admin_module_manage_action', [
'action' => 'install',
'module_name' => $this->moduleName,
]);
}
/**
* Override of native function to always retrieve Symfony container instead of legacy admin container on legacy context.
*
* @param string $serviceName
*
* @return mixed
*/
private function get(string $serviceName)
{
if (null === $this->container) {
$container = \PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance();
if (empty($container)) {
throw new \PrestaShopException('Symfony container is null or invalid');
}
$this->container = $container;
}
return $this->container->get($serviceName);
}
/**
* returns the enable link of the ps_googleanalytics module if it is not enabled. If enabled, returns an empty string
*
* @return string
*/
public function getEnableLink(): string
{
if (true === $this->moduleHelper->isEnabled($this->moduleName)) {
return '';
}
$router = $this->get('router');
return substr($this->toolsHelper->getShopDomainSsl(true) . __PS_BASE_URI__, 0, -1) . $router->generate('admin_module_manage_action', [
'action' => 'enable',
'module_name' => $this->moduleName,
]);
}
/**
* returns the configuration link of the ps_googleanalytics module if it is not configured. If configured, returns an empty string
*
* @return string
*/
public function getConfigLink(): string
{
$link = $this->prestashopHelper->getLink();
return $link->getAdminLink('AdminModules', true, [], [
'configure' => $this->moduleName,
]);
}
/**
* get ps_analytics module version
*
* @return string
*/
public function getModuleVersion(): string
{
if (false === $this->isInstalled()) {
return '0.0.0';
}
$module = \Module::getInstanceByName($this->moduleName);
if (false === $module) {
return '0.0.0';
}
return $module->version;
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Module;
use Hook;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
use PrestaShop\Module\Ps_metrics\Repository\HookModuleRepository;
use Ps_metrics;
class Install
{
/**
* @var Ps_metrics
*/
private $module;
/**
* @var ConfigurationRepository
*/
private $configurationRepository;
/**
* @var HookModuleRepository
*/
private $hookModuleRepository;
/**
* Install constructor.
*
* @param Ps_metrics $module
* @param ConfigurationRepository $configurationRepository
* @param HookModuleRepository $hookModuleRepository
*
* @return void
*/
public function __construct(Ps_metrics $module, ConfigurationRepository $configurationRepository, HookModuleRepository $hookModuleRepository)
{
$this->module = $module;
$this->configurationRepository = $configurationRepository;
$this->hookModuleRepository = $hookModuleRepository;
}
/**
* updateModuleHookPosition
*
* @param string $hookName
* @param int $position
*
* @return bool
*/
public function updateModuleHookPosition(string $hookName, int $position): bool
{
$hookId = Hook::getIdByName($hookName);
if (false == $hookId) {
return false;
}
return $this->hookModuleRepository->setModuleHookPosition($hookId, $this->module->id, $position);
}
/**
* setConfigurationValues
*
* @return bool
*/
public function setConfigurationValues(): bool
{
return $this->configurationRepository->saveActionGoogleLinked(false) &&
$this->configurationRepository->saveGoogleTagLinked(false) &&
$this->configurationRepository->saveDashboardModulesToToggle() &&
$this->configurationRepository->saveFirstTimeOnboarded(false);
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Module;
use Module;
use PrestaShop\Module\Ps_metrics\Api\AnalyticsApi;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use Ps_metrics;
class Uninstall
{
/**
* @var Ps_metrics|Module
*/
private $module;
/**
* @var ConfigurationRepository
*/
private $configurationRepository;
/**
* @var AnalyticsApi
*/
private $analyticsApi;
/**
* @var PsAccounts
*/
private $psAccountsFacade;
/**
* Uninstall constructor.
*
* @param Module $module
* @param ConfigurationRepository $configurationRepository
* @param AnalyticsApi $analyticsApi
*/
public function __construct(
Module $module,
PsAccounts $psAccountsFacade,
ConfigurationRepository $configurationRepository,
AnalyticsApi $analyticsApi
) {
$this->module = $module;
$this->psAccountsFacade = $psAccountsFacade;
$this->configurationRepository = $configurationRepository;
$this->analyticsApi = $analyticsApi;
}
/**
* resetConfigurationValues
*
* @return bool
*/
public function resetConfigurationValues(): bool
{
return $this->configurationRepository->saveActionGoogleLinked(false) &&
$this->configurationRepository->saveFirstTimeOnboarded(false);
}
/**
* unsubscribePsEssentials
*
* @return bool
*/
public function unsubscribePsEssentials(): bool
{
// if the user is not onboarded, don't process unsubscribe
if (!$this->isOnboardedWithAccountAndGoogle()) {
return true;
}
return $this->analyticsApi->unsubscribe();
}
/**
* Check if the user is onboarded on prestashop account and google
*
* @return bool
*/
private function isOnboardedWithAccountAndGoogle(): bool
{
if (false === \Module::isInstalled('ps_accounts')) {
return false;
}
$shopUuidV4 = $this->psAccountsFacade->getPsAccountsService()->getShopUuidV4();
if (
false === $shopUuidV4 &&
false === $this->configurationRepository->getGoogleLinkedValue()
) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Module;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
use Ps_metrics;
class Upgrade
{
/**
* @var Ps_metrics
*/
private $module;
/**
* Install constructor.
*
* @param Ps_metrics $module
*
* @return void
*/
public function __construct(Ps_metrics $module)
{
$this->module = $module;
}
/**
* Upgrade metrics module
*
* @return bool
*/
public function upgradeMetrics(): bool
{
if (true === \Module::needUpgrade($this->module)) {
/** @var ModuleManagerBuilder $moduleManagerBuilder */
$moduleManagerBuilder = ModuleManagerBuilder::getInstance();
$moduleManager = $moduleManagerBuilder->build();
return $moduleManager->upgrade($this->module->name);
}
return true;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,81 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Presenter;
use PrestaShop\Module\Ps_metrics\Api\HttpApi;
use PrestaShop\Module\Ps_metrics\Helper\JsonHelper;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use Ps_metrics;
class FaqPresenter
{
/**
* @var JsonHelper
*/
private $jsonHelper;
/**
* @var Ps_metrics
*/
private $module;
/**
* @var PrestaShopHelper
*/
private $prestashopHelper;
/**
* @var HttpApi
*/
private $httpApi;
/**
* Presenter constructor.
*
* @param JsonHelper $jsonHelper
* @param Ps_metrics $module
* @param PrestaShopHelper $prestashopHelper
* @param HttpApi $httpApi
*
* @return void
*/
public function __construct(
JsonHelper $jsonHelper,
Ps_metrics $module,
PrestaShopHelper $prestashopHelper,
HttpApi $httpApi
) {
$this->jsonHelper = $jsonHelper;
$this->module = $module;
$this->prestashopHelper = $prestashopHelper;
$this->httpApi = $httpApi;
}
/**
* Get faq content from addons
*
* @return string
*/
public function getFaq(): string
{
return $this->jsonHelper->jsonEncode($this->httpApi->getFaq($this->module->module_key, $this->prestashopHelper->getLanguageIsoCode(), _PS_VERSION_));
}
}

View File

@@ -0,0 +1,415 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Presenter;
use PrestaShop\Module\Ps_metrics\Api\HttpApi;
use PrestaShop\Module\Ps_metrics\Handler\NativeStatsHandler;
use PrestaShop\Module\Ps_metrics\Helper\DbHelper;
use PrestaShop\Module\Ps_metrics\Helper\MultishopHelper;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\ShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\ToolsHelper;
use PrestaShop\Module\Ps_metrics\Module\GAInstaller;
use PrestaShop\Module\Ps_metrics\Provider\AnalyticsAccountsListProvider;
use PrestaShop\Module\Ps_metrics\Provider\GoogleTagProvider;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
use PrestaShop\Module\Ps_metrics\Repository\OrderRepository;
use PrestaShop\PsAccountsInstaller\Installer\Exception\InstallerException;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use Ps_metrics;
class ShopDataPresenter
{
/**
* @var Ps_metrics
*/
private $module;
/**
* @var PrestaShopHelper
*/
private $prestashopHelper;
/**
* @var ConfigurationRepository
*/
private $configurationRepository;
/**
* @var ShopHelper
*/
private $shopHelper;
/**
* @var AnalyticsAccountsListProvider
*/
private $analyticsAccountsListProvider;
/**
* @var GoogleTagProvider
*/
private $googleTagProvider;
/**
* @var GAInstaller
*/
private $gaInstaller;
/**
* @var HttpApi
*/
private $httpApi;
/**
* @var NativeStatsHandler;
*/
private $nativeStats;
/**
* @var PsAccounts
*/
private $psAccountsFacade;
/**
* @var ToolsHelper
*/
private $toolsHelper;
/**
* @var DbHelper
*/
private $dbHelper;
/**
* @var MultishopHelper
*/
private $multishopHelper;
/**
* @var OrderRepository
*/
private $orderRepository;
/**
* Presenter constructor.
*
* @param Ps_metrics $module
* @param PrestaShopHelper $prestashopHelper
* @param ConfigurationRepository $configurationRepository
* @param ShopHelper $shopHelper
* @param AnalyticsAccountsListProvider $analyticsAccountsListProvider
* @param GoogleTagProvider $googleTagProvider
* @param GAInstaller $gaInstaller
* @param HttpApi $httpApi
* @param NativeStatsHandler $nativeStats
* @param PsAccounts $psAccountsFacade
* @param ToolsHelper $toolsHelper
* @param DbHelper $dbHelper
* @param MultishopHelper $multishopHelper
* @param OrderRepository $orderRepository
*
* @return void
*/
public function __construct(
Ps_metrics $module,
PrestaShopHelper $prestashopHelper,
ConfigurationRepository $configurationRepository,
ShopHelper $shopHelper,
AnalyticsAccountsListProvider $analyticsAccountsListProvider,
GoogleTagProvider $googleTagProvider,
GAInstaller $gaInstaller,
HttpApi $httpApi,
NativeStatsHandler $nativeStats,
PsAccounts $psAccountsFacade,
ToolsHelper $toolsHelper,
DbHelper $dbHelper,
MultishopHelper $multishopHelper,
OrderRepository $orderRepository
) {
$this->module = $module;
$this->prestashopHelper = $prestashopHelper;
$this->configurationRepository = $configurationRepository;
$this->shopHelper = $shopHelper;
$this->analyticsAccountsListProvider = $analyticsAccountsListProvider;
$this->googleTagProvider = $googleTagProvider;
$this->gaInstaller = $gaInstaller;
$this->httpApi = $httpApi;
$this->nativeStats = $nativeStats;
$this->psAccountsFacade = $psAccountsFacade;
$this->toolsHelper = $toolsHelper;
$this->dbHelper = $dbHelper;
$this->multishopHelper = $multishopHelper;
$this->orderRepository = $orderRepository;
}
/**
* Get shop datas for replacing the shop data in the module settings page.
*
* @return array
*/
public function getShopData(): array
{
$currentShop = $this->shopHelper->getShopUrl(
$this->prestashopHelper->getShopId()
);
$this->googleTagProvider->setBaseUrl($currentShop['url']);
try {
$psAccountsService = $this->psAccountsFacade->getPsAccountsService();
$psAccountsJWT = $psAccountsService->getOrRefreshToken();
$psAccountsToken = $psAccountsService->getRefreshToken();
$shopUuidV4 = $psAccountsService->getShopUuidV4();
$email = $psAccountsService->getEmail();
$emailIsValidated = $psAccountsService->isEmailValidated();
$accountsUrl = $psAccountsService->getAdminAjaxUrl();
} catch (InstallerException $e) {
$psAccountsToken = '';
$psAccountsJWT = '';
$shopUuidV4 = '';
$email = '';
$emailIsValidated = false;
$accountsUrl = '';
}
$psEventBusModuleVersion = '0.0.0';
if (\Module::isInstalled('ps_eventbus')) {
/** @var \Module $psEventBusModule */
$psEventBusModule = \Module::getInstanceByName('ps_eventbus');
$psEventBusModuleVersion = $psEventBusModule->version;
}
$psAccountsModuleVersion = '0.0.0';
if (\Module::isInstalled('ps_accounts')) {
/** @var \Module $psAccountsModule */
$psAccountsModule = \Module::getInstanceByName('ps_accounts');
$psAccountsModuleVersion = $psAccountsModule->version;
}
$link = $this->prestashopHelper->getLink();
$googleLinkedUrl = $link->getAdminLink('MetricsOauthController', true, [
'route' => 'metrics_oauth',
'from' => 'PS',
]);
$caForPlan = $this->httpApi->convertToCurrency(
$this->orderRepository->getCaForPlans(),
$this->prestashopHelper->getCurrencyIsoCode()
);
$response = [
'modules' => [
'psMetrics' => [
'name' => $this->module->name,
'displayName' => $this->module->displayName,
'version' => $this->module->version,
'emailSupport' => $this->module->emailSupport,
'termsOfServiceUrl' => $this->module->termsOfServiceUrl,
],
'psEventBus' => [
'version' => $psEventBusModuleVersion,
],
'psAccounts' => [
'version' => $psAccountsModuleVersion,
'userInfos' => [
'email' => $email,
'emailIsValidated' => $emailIsValidated,
'isSuperAdmin' => (new PrestaShopHelper())
->getEmployee()
->isSuperAdmin(),
],
'apiUrl' => $accountsUrl,
'token' => $psAccountsToken,
'jwt' => $psAccountsJWT,
],
'psAnalytics' => [
'version' => $this->gaInstaller->getModuleVersion(),
'isInstalled' => $this->gaInstaller->isInstalled(),
'isEnabled' => $this->gaInstaller->isEnabled(),
'installLink' => $this->gaInstaller->getInstallLink(),
'enableLink' => $this->gaInstaller->getEnableLink(),
'configLink' => $this->gaInstaller->getConfigLink(),
],
],
'billing' => [
'caForPlan' => $caForPlan < 1 ? 1 : $caForPlan,
],
'links' => [
'api' => [
'graphql' => $link->getAdminLink(
'MetricsGraphqlController',
true,
['route' => 'metrics_graphql']
),
'accountsRetrieveToken' => $accountsUrl,
],
'controllers' => [
'metrics' => $link->getAdminLink(
'MetricsController',
true,
['route' => 'metrics_page']
),
'dashboard' => $link->getAdminLink(
'AdminDashboard',
true,
[]
),
'upgrade' => $link->getAdminLink('AdminModules', true, []),
'settings' => $link->getAdminLink('MetricsController', true, [
'route' => 'metrics_page',
]) . '#/settings',
],
],
'faq' => [
'data' => [],
'docsUrl' => $this->getReadme(),
],
'shopInfos' => [
'uuid' => $shopUuidV4,
'shopVersion' => _PS_VERSION_,
'domain' => $currentShop['domain'],
'name' => \Configuration::get('PS_SHOP_NAME'),
'isMultiShop' => $this->multishopHelper->isMultishopActive(),
'shopList' => $this->multishopHelper->getAllShopsOrGroupShops(),
'selectedShopData' => $this->multishopHelper->getSelectedShop(),
'shopContext' => $this->multishopHelper->getShopContextLitteral(),
'nativeStatsModulesEnabled' => $this->nativeStats->nativeStatsIsEnabled(),
'adminToken' => '',
],
'i18n' => [
'isoCode' => $this->prestashopHelper->getLanguageIsoCode(),
'currencyIsoCode' => $this->prestashopHelper->getCurrencyIsoCode(),
],
'serverInfos' => [
'phpVersion' => phpversion(),
],
'employeeInfos' => [
'email' => $this->prestashopHelper->getEmployeeEmail(),
'ip' => isset($_SERVER['REMOTE_ADDR'])
? $_SERVER['REMOTE_ADDR']
: '',
],
'pagesContext' => [
'isLegacyStatsPage' => $this->checkIfPageIsLegacyStats(),
'app' => '',
],
'googleAccount' => [
'isLinked' => (bool) $this->configurationRepository->getGoogleLinkedValue(),
'linkedUrl' => $googleLinkedUrl,
'list' => $this->analyticsAccountsListProvider->getAccountsList(),
'selected' => $this->analyticsAccountsListProvider->getSelectedAccount(),
'username' => $this->analyticsAccountsListProvider->getUserName(),
'tags' => [
'GTAAvailable' => $this->googleTagProvider->findGoogleTagsAnalytics(),
'GTMAvailable' => $this->googleTagProvider->findGoogleTagsManager(),
],
'error' => $this->toolsHelper->getValue('google_message_error'),
],
];
return $response;
}
/**
* Check if page is ols stats page
*
* @return bool
*/
private function checkIfPageIsLegacyStats(): bool
{
return $this->prestashopHelper->getControllerName() === 'AdminStats';
}
/**
* Get the documentation url depending on the current language
*
* @return string path of the doc
*/
private function getReadme(): string
{
$isoCode = $this->prestashopHelper->getLanguageIsoCode();
$baseUrl =
'https://storage.googleapis.com/psessentials-documentation/' .
$this->module->name;
if (
!$this->checkFileExist(
$baseUrl . '/user_guide_' . $isoCode . '.pdf'
)
) {
$isoCode = 'en';
}
return $baseUrl . '/user_guide_' . $isoCode . '.pdf';
}
/**
* Use cUrl to get HTTP headers and detect any HTTP 404
*
* @param string $docUrl
*
* @return bool
*/
private function checkFileExist($docUrl): bool
{
$ch = curl_init($docUrl);
if (false === $ch) {
return false;
}
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $retcode < 400;
}
/**
* Retrieve the date_add when a field has been added to
* the configuration table
*
* @param string $key name field in configuration table
*
* @return string date
*/
private function getProductTourDate($key): string
{
$query = $this->dbHelper->getValue(
'SELECT date_add
FROM ' .
_DB_PREFIX_ .
'configuration c
WHERE c.name = "' .
$key .
'"'
);
if (!empty($query)) {
$date = new \DateTime($query);
$query = $date->format('Y-m-d');
}
return $query;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,135 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Provider;
use PrestaShop\Module\Ps_metrics\Api\AnalyticsApi;
use PrestaShop\Module\Ps_metrics\Repository\ConfigurationRepository;
class AnalyticsAccountsListProvider
{
/**
* @var array
*/
private $accountsList;
/**
* @var ConfigurationRepository
*/
private $configurationRepository;
/**
* @var AnalyticsApi
*/
private $analyticsApi;
/**
* AnalyticsAccountsListProvider constructor.
*
* @param ConfigurationRepository $configurationRepository
* @param AnalyticsApi $analyticsApi
*/
public function __construct(
ConfigurationRepository $configurationRepository,
AnalyticsApi $analyticsApi
) {
$this->analyticsApi = $analyticsApi;
$this->accountsList = [];
$this->configurationRepository = $configurationRepository;
}
/**
* getAccountsList
*
* @return array
*/
public function getAccountsList()
{
if (false === $this->configurationRepository->getGoogleLinkedValue()) {
return [];
}
$apiReturn = $this->analyticsApi->getAccountsList();
return $this->formatAccountListArray($apiReturn);
}
/**
* Get the selected account from the account list
*
* @return mixed
*/
public function getSelectedAccount()
{
foreach ($this->accountsList as $uaTag => $accountData) {
if (true === $accountData['selected']) {
$accountData['webPropertyId'] = $uaTag;
return $accountData;
}
}
return null;
}
/**
* Get username
*
* @return string
*/
public function getUserName()
{
if (false === empty($this->accountsList)) {
$webPropertyList = array_keys($this->accountsList);
$firstWebProperty = current($webPropertyList);
return $this->accountsList[$firstWebProperty]['username'];
}
return '';
}
/**
* retrieveAccountsList
*
* @param array $accountList
*
* @return array
*/
private function formatAccountListArray($accountList)
{
if (empty($accountList)) {
return [];
}
foreach ($accountList as $accounts) {
foreach ($accounts as $account) {
foreach ($account as $key => $property) {
$this->accountsList[$key] = $property;
$this->accountsList[$key]['webPropertyId'] = $key;
$this->accountsList[$key]['typeSource'] =
$property['type_source'];
}
}
}
return $this->accountsList;
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Provider;
use PrestaShop\Module\Ps_metrics\Api\HttpApi;
class GoogleTagProvider
{
/**
* @var string|null
*/
private $shopSource;
/**
* @var HttpApi
*/
private $httpApi;
/**
* __construct
*
* @param HttpApi $httpApi
*/
public function __construct(HttpApi $httpApi)
{
$this->httpApi = $httpApi;
}
/**
* Set base url
*
* @param string $baseUrl
*
* @return void
*/
public function setBaseUrl($baseUrl)
{
$this->shopSource = $this->httpApi->getSourcePage($baseUrl);
}
/**
* Find by Regex if a Google Tag Analytics (UA-XXXXXXXXX-X) exists in source aimed page
*
* @return string
*/
public function findGoogleTagsAnalytics(): string
{
if (empty($this->shopSource)) {
return '';
}
// get google analytics tags < V4
preg_match_all('/UA-\d{6,}-\d/m', $this->shopSource, $matches);
if (!empty($matches[0])) {
return $matches[0][0];
}
return $this->findGoogleTagsAnalyticsV4();
}
/**
* Find by Regex if a Google Tag Analytics VA (G-XXXXXXXXXX) exists in source aimed page
*
* @return string
*/
public function findGoogleTagsAnalyticsV4(): string
{
if (empty($this->shopSource)) {
return '';
}
// get google analytics tags < V4
preg_match_all('/G-\S{10,}/m', $this->shopSource, $matches);
if (!empty($matches[0])) {
return $matches[0][0];
}
return '';
}
/**
* Find by Regex if a Google Tag Manager (GTM-XXXXXXX) exists in source aimed page
*
* @return string
*/
public function findGoogleTagsManager(): string
{
if (empty($this->shopSource)) {
return '';
}
preg_match_all('/GTM-\w{6,}/m', $this->shopSource, $matches);
if (!empty($matches[0])) {
return $matches[0][0];
}
return '';
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,216 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Repository;
use Configuration;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
class ConfigurationRepository
{
const PS_METRICS_FIRST_TIME_ONBOARDED = 'PS_METRICS_FIRST_TIME_ONBOARDED';
const ACCOUNT_MODULES_STATES = 'PS_METRICS_MODULES_STATES';
const ACCOUNT_LINKED = 'PS_METRICS_ACCOUNT_LINKED';
const ACCOUNT_GOOGLETAG_LINKED = 'PS_METRICS_GOOGLETAG_LINKED';
/**
* @var int
*/
private $shopId;
/**
* ConfigurationRepository constructor.
*
* @param PrestaShopHelper $prestaShopHelper
*
* @return void
*/
public function __construct(PrestaShopHelper $prestaShopHelper)
{
$this->shopId = (int) $prestaShopHelper->getShopId();
}
/**
* Get if the user has already onboarded the module
*
* @return bool
*/
public function getFirstTimeOnboarded()
{
return (bool) Configuration::get(
self::PS_METRICS_FIRST_TIME_ONBOARDED,
null,
null,
$this->shopId
);
}
/**
* Register the first time a user has onboarded the module
*
* @param bool $bool
*
* @return bool
*/
public function saveFirstTimeOnboarded($bool)
{
return Configuration::updateValue(
self::PS_METRICS_FIRST_TIME_ONBOARDED,
$bool,
false,
null,
$this->shopId
);
}
/**
* saveActionGoogleLinked
*
* @param bool $action
*
* @return bool
*/
public function saveActionGoogleLinked($action)
{
return Configuration::updateValue(
self::ACCOUNT_LINKED,
$action,
false,
null,
$this->shopId
);
}
/**
* getGoogleLinkedValue
*
* @return bool
*/
public function getGoogleLinkedValue()
{
return (bool) Configuration::get(
self::ACCOUNT_LINKED,
null,
null,
$this->shopId
);
}
/**
* getShopDomain
*
* @return string|false
*/
public function getShopDomain()
{
return Configuration::get(
'PS_SHOP_DOMAIN',
null,
null,
$this->shopId
);
}
/**
* saveGoogleTagLinked
*
* @param bool $action
*
* @return bool
*/
public function saveGoogleTagLinked($action)
{
return Configuration::updateValue(
self::ACCOUNT_GOOGLETAG_LINKED,
$action,
false,
null,
$this->shopId
);
}
/**
* getGoogleTagLinkedValue
*
* @return bool
*/
public function getGoogleTagLinkedValue()
{
return (bool) Configuration::get(
self::ACCOUNT_GOOGLETAG_LINKED,
null,
null,
$this->shopId
);
}
/**
* saveModuleListState
*
* @param array $moduleList
*
* @return bool
*/
public function saveDashboardModulesToToggle($moduleList = [])
{
if (count($moduleList) === 0) {
$moduleList = '';
} else {
$moduleList = json_encode($moduleList);
}
return Configuration::updateValue(
self::ACCOUNT_MODULES_STATES,
$moduleList
);
}
/**
* getModuleListState
*
* @return array|string
*/
public function getDashboardModulesToToggleAsArray()
{
$modules = $this->getDashboardModulesToToggle();
if (false === $modules || '' === $modules) {
return '';
}
return json_decode($modules);
}
/**
* getModuleListState
*
* @return string|false
*/
private function getDashboardModulesToToggle()
{
return Configuration::get(
self::ACCOUNT_MODULES_STATES,
null,
null,
$this->shopId
);
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Repository;
use Db;
class HookModuleRepository
{
const TABLE_NAME = 'hook_module';
/**
* setModuleHookPosition
*
* @param int $hookId
* @param int $moduleId
* @param int $position
*
* @return bool
*/
public function setModuleHookPosition($hookId, $moduleId, $position)
{
return Db::getInstance()->update(
self::TABLE_NAME,
[
'position' => $position,
],
'id_hook = ' . (int) $hookId . ' AND id_module = ' . (int) $moduleId
);
}
}

View File

@@ -0,0 +1,120 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Repository;
use PrestaShop\Module\Ps_metrics\Helper\DbHelper;
use PrestaShop\Module\Ps_metrics\Helper\ShopHelper;
class OrderRepository
{
/**
* @var DbHelper
*/
private $dbHelper;
/**
* @var ShopHelper
*/
private $shopHelper;
/**
* __construct
*
* @param DbHelper $dbHelper
* @param ShopHelper $shopHelper
*/
public function __construct(DbHelper $dbHelper, ShopHelper $shopHelper)
{
$this->dbHelper = $dbHelper;
$this->shopHelper = $shopHelper;
}
/**
* Get CA for the shop for de order paid since last 3 months for billing plan
*
* @return int
*/
public function getCaForPlans()
{
$firstOrderDate = $this->getFirstOrderDate();
if (empty($firstOrderDate)) {
return 0;
}
$begin = new \DateTime($firstOrderDate);
$end = new \DateTime();
$interval = date_diff($begin, $end);
$intervalMonth = $interval->m + $interval->y * 12;
$months = $intervalMonth > 3 ? 3 : $intervalMonth;
$months = $months == 0 ? 1 : $months;
$date = date('Y-m-d', (int) strtotime('-' . $months . 'months'));
$amount = (int) $this->dbHelper->getValue(
'SELECT SUM((od.unit_price_tax_incl / o.conversion_rate) * od.product_quantity) as revenues
FROM ' .
_DB_PREFIX_ .
'order_detail od
INNER JOIN ' .
_DB_PREFIX_ .
'orders o ON (od.id_order = o.id_order)
INNER JOIN ' .
_DB_PREFIX_ .
'order_state os ON (o.current_state = os.id_order_state)
WHERE
o.date_add >= "' .
pSQL($date) .
'"
AND os.logable = 1
' .
$this->shopHelper->addSqlRestriction(false, 'o') .
'
ORDER BY o.date_add ASC'
);
return $amount / $months;
}
/**
* Get first order date
*
* @return string
*/
private function getFirstOrderDate()
{
return $this->dbHelper->getValue(
'SELECT date_add
FROM ' .
_DB_PREFIX_ .
'orders o
INNER JOIN ' .
_DB_PREFIX_ .
'order_state os ON (o.current_state = os.id_order_state)
WHERE os.logable = 1
' .
$this->shopHelper->addSqlRestriction(false, 'o') .
'
ORDER BY date_add DESC'
);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,152 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics;
use PrestaShop\PsAccountsInstaller\Installer\Exception\ModuleNotInstalledException;
use PrestaShop\PsAccountsInstaller\Installer\Exception\ModuleVersionException;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
class StatsTabManager
{
/**
* @var \Ps_metrics
*/
private $module;
/**
* @var PsAccounts
*/
private $psAccountsFacade;
/**
* StatsTabManager constructor.
*
* @param \Ps_metrics $module
*/
public function __construct(
\Ps_metrics $module,
PsAccounts $psAccountsFacade
) {
$this->module = $module;
$this->psAccountsFacade = $psAccountsFacade;
}
/**
* Disable legacy stats controller and enable metrics controller instead
*
* @return bool
*
* @throws ModuleNotInstalledException
* @throws ModuleVersionException
*/
public function install()
{
try {
$psAccountsService = $this->psAccountsFacade->getPsAccountsService();
} catch (\Throwable $th) {
return true;
}
if (!$psAccountsService->isAccountLinked()) {
return true;
}
return $this->toggleLegacyStatsController(false) &&
$this->enableMetricsController();
}
/**
* Enable back legacy stats controller and delete metrics controller
*
* @return bool
*/
public function uninstall()
{
return $this->toggleLegacyStatsController(true) &&
$this->deleteMetricsController();
}
/**
* Enable or disable legacy stats controller
*
* @param mixed $bool
*
* @return bool
*
* @throws \PrestaShopException
* @throws \PrestaShopDatabaseException
*/
private function toggleLegacyStatsController($bool)
{
$legacyStatsTab = new \Tab(\Tab::getIdFromClassName('AdminStats'));
$legacyStatsTab->active = $bool;
$legacyStatsTab->save();
return $legacyStatsTab->save();
}
/**
* Create and active metrics stats controller
*
* @return bool
*
* @throws \PrestaShopException
* @throws \PrestaShopDatabaseException
* @throws \Exception
*/
private function enableMetricsController()
{
$legacyStatsTab = new \Tab(\Tab::getIdFromClassName('AdminStats'));
$metricsTab = \Tab::getIdFromClassName('MetricsController');
if ($metricsTab) {
$tab = new \Tab($metricsTab);
} else {
$tab = new \Tab();
}
$tab->name = $legacyStatsTab->name;
$tab->class_name = 'MetricsController';
$tab->active = true;
$tab->icon = 'assessment';
$tab->module = $this->module->name;
$tab->id_parent = $legacyStatsTab->id_parent;
return $tab->save();
}
/**
* Remove metrics stats controller
*
* @return bool
*
* @throws \PrestaShopException
* @throws \PrestaShopDatabaseException
*/
private function deleteMetricsController()
{
$metricsTab = new \Tab(\Tab::getIdFromClassName('MetricsController'));
return $metricsTab->delete();
}
}

View File

@@ -0,0 +1,238 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Tracker;
use PrestaShop\Module\Ps_metrics\Helper\PrestaShopHelper;
use PrestaShop\Module\Ps_metrics\Helper\SegmentHelper;
use PrestaShop\Module\Ps_metrics\Helper\ShopHelper;
class Segment implements TrackerInterface
{
/**
* @var string
*/
private $message = '';
/**
* @var array
*/
private $options = [];
/**
* @var SegmentHelper
*/
private $segmentHelper;
/**
* @var PrestaShopHelper
*/
private $prestaShopHelper;
/**
* @var ShopHelper
*/
private $shopHelper;
/**
* Segment constructor.
*
* @param SegmentHelper $segmentHelper
* @param PrestaShopHelper $prestaShopHelper
* @param ShopHelper $shopHelper
*/
public function __construct(
SegmentHelper $segmentHelper,
PrestaShopHelper $prestaShopHelper,
ShopHelper $shopHelper
) {
$this->segmentHelper = $segmentHelper;
$this->prestaShopHelper = $prestaShopHelper;
$this->shopHelper = $shopHelper;
$this->init();
}
/**
* Init segment client with the api key
*
* @return void
*/
private function init(): void
{
$this->segmentHelper->init();
}
/**
* Track event on segment
*
* @return void
*
* @throws \PrestaShopException
*/
public function track(): void
{
if (empty($this->message)) {
throw new \PrestaShopException('Message cannot be empty. Need to set it with setMessage() method.');
}
// Dispatch track depending on context shop
$this->dispatchTrack();
}
/**
* Add track
*
* @param mixed $userId
*
* @return void
*/
private function segmentTrack($userId): void
{
$referer = isset($_SERVER['HTTP_REFERER'])
? $_SERVER['HTTP_REFERER']
: '';
$url =
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'
? 'https'
: 'http') . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$this->segmentHelper->track([
'userId' => $userId,
'event' => $this->message,
'channel' => 'browser',
'context' => [
'locale' => (new PrestaShopHelper())->getLanguageIsoCode(),
'page' => [
'referrer' => $referer,
'url' => $url,
],
],
'properties' => array_merge(
[
'module' => 'ps_metrics',
],
$this->options
),
]);
$this->segmentHelper->flush();
}
/**
* Handle tracking differently depending on the shop context
*
* @return mixed
*
* @todo how to refacto dictionnary with helper ?
*/
private function dispatchTrack()
{
$dictionary = [
\Shop::CONTEXT_SHOP => function () {
$this->trackShop();
},
\Shop::CONTEXT_GROUP => function () {
$this->trackShopGroup();
},
\Shop::CONTEXT_ALL => function () {
$this->trackAllShops();
},
];
return call_user_func($dictionary[$this->shopHelper->getContext()]);
}
/**
* Send track segment only for the current shop
*
* @return void
*/
private function trackShop(): void
{
$userId = $this->prestaShopHelper->getShopDomain();
$this->segmentTrack($userId);
}
/**
* Send track segment for each shop in the current shop group
*
* @return void
*/
private function trackShopGroup(): void
{
$shops = $this->shopHelper->getShops(
true,
$this->shopHelper->getContextShopGroupID()
);
foreach ($shops as $shop) {
$this->segmentTrack($shop['domain']);
}
}
/**
* Send track segment for all shops
*
* @return void
*/
private function trackAllShops(): void
{
$shops = $this->shopHelper->getShops();
foreach ($shops as $shop) {
$this->segmentTrack($shop['domain']);
}
}
/**
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
/**
* @param string $message
*
* @return void
*/
public function setMessage(string $message): void
{
$this->message = $message;
}
/**
* @return array
*/
public function getOptions(): array
{
return $this->options;
}
/**
* @param array $options
*
* @return void
*/
public function setOptions(array $options): void
{
$this->options = $options;
}
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Tracker;
interface TrackerInterface
{
/**
* @return void
*/
public function track(): void;
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,55 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Ps_metrics\Validation;
class SelectAccountAnalytics
{
/**
* validate
*
* @param array $data
*
* @return bool
*/
public function validate(array $data): bool
{
if (empty($data['webPropertyId'])) {
return false;
}
/* Check if UA- is valid */
preg_match(
'/UA-\d{6,}-\d/m',
$data['webPropertyId'],
$matchWebPropertyId
);
/* Check if G- is valid */
preg_match(
'/properties\S{10,}/m',
$data['webPropertyId'],
$matchWebPropertyIdv4
);
return true;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Optimieren Sie Ihr Geschäft mit einem datengesteuerten Ansatz, indem Sie einen vollständigen Überblick über Ihr Geschäft in Echtzeit erhalten.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = 'Sind Sie sicher, dass Sie dieses Modul deinstallieren möchten?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Optimize your business with a data-driven approach by gaining a complete view of your business in real time.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = 'Are you sure you want to uninstall this module?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Optimice su negocio con un enfoque basado en datos obteniendo una visión completa de su negocio en tiempo real.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = '¿Estás seguro/a de que quieres desinstalar este módulo?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Optimisez votre entreprise grâce à une approche axée sur les données en bénéficiant d\'une vue complète de votre activité en temps réel.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = 'Etes-vous sûr de vouloir désinstaller ce module ?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Ottimizza il tuo business con un approccio basato sui dati, ottenendo una visione completa del tuo business in tempo reale.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = 'Sei sicuro/a di voler disinstallare questo modulo?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Optimaliseer uw bedrijf met een datagestuurde aanpak door in realtime een volledig beeld van uw bedrijf te krijgen.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = 'Weet u zeker dat u deze module wilt de-installeren?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Zoptymalizuj swoją działalność dzięki podejściu opartemu na danych, uzyskując pełny obraz swojej działalności w czasie rzeczywistym.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = 'Czy na pewno chcesz odinstalować ten moduł?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
global $_MODULE;
$_MODULE = [];
$_MODULE['<{ps_metrics}prestashop>ps_metrics_1fbb6edbf5c59b1a2348878ba08c97a2'] = 'Optimize o seu negócio com uma abordagem orientada pelos dados, obtendo uma visão completa do seu negócio em tempo real.';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_bb8956c67b82c7444a80c6b2433dd8b4'] = 'Tem a certeza que quer desinstalar este módulo?';
$_MODULE['<{ps_metrics}prestashop>ps_metrics_be859bacea10a8a5edbace55a7b078bc'] = 'PrestaShop Metrics';

View File

@@ -0,0 +1,11 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

Some files were not shown because too many files have changed in this diff Show More