Commit fa887a26 by lmf

后台增加日志模块

parent f249153b
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Api\Activity;
/**
* Interface ModelInterface
* @package KiwiCommerce\AdminActivity\Api\Activity
*/
interface ModelInterface
{
/**
* Get old data
* @param $model
* @return mixed
*/
public function getOldData($model);
/**
* Get edit data
* @param $model
* @return mixed
*/
public function getEditData($model, $fieldArray);
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Api;
/**
* Interface ActivityRepositoryInterface
* @package KiwiCommerce\AdminActivity\Api
*/
interface ActivityRepositoryInterface
{
/**
* Array of protected fields
* @return mixed
*/
public function protectedFields();
/**
* Get collection of admin activity
* @return mixed
*/
public function getList();
/**
* Get all admin activity data before date
* @param $endDate
* @return mixed
*/
public function getListBeforeDate($endDate);
/**
* Remove activity log entry
* @param $activityId
* @return mixed
*/
public function deleteActivityById($activityId);
/**
* Get all admin activity detail by activity id
* @param $activityId
* @return mixed
*/
public function getActivityDetail($activityId);
/**
* Get all admin activity log by activity id
* @param $activityId
* @return mixed
*/
public function getActivityLog($activityId);
/**
* Revert last changes made in module
* @param $activity
* @return mixed
*/
public function revertActivity($activity);
/**
* Get old data for system config module
* @param $model
* @return mixed
*/
public function getOldData($model);
/**
* Get admin activity by id
* @param $activityId
* @return mixed
*/
public function getActivityById($activityId);
/**
* Check field is protected or not
* @param $fieldName
* @return mixed
*/
public function isFieldProtected($fieldName);
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Api\Data;
/**
* Interface ActivityInterface
* @package KiwiCommerce\AdminActivity\Api\Data
*/
interface ActivityInterface
{
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Api\Data;
/**
* Interface LogSearchResultsInterface
* @package KiwiCommerce\EnhancedSMTP\Api\Data
*/
interface ActivitySearchResultsInterface extends \Magento\Framework\Api\SearchResultsInterface
{
/**
* Get admin activity list.
* @api
* @return \KiwiCommerce\AdminActivity\Model\Activity[]
*/
public function getItems();
/**
* Set admin activity list.
* @api
* @param \KiwiCommerce\AdminActivity\Model\Activity[] $items
* @return $this
*/
public function setItems(array $items);
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Api;
/**
* Interface LoginRepositoryInterface
* @package KiwiCommerce\AdminActivity\Api
*/
interface LoginRepositoryInterface
{
/**
* Set login data
* @param $status
* @param $type
* @return mixed
*/
public function addLog($status, $type);
/**
* Get all admin activity data before date
* @param $endDate
* @return mixed
*/
public function getListBeforeDate($endDate);
/**
* Set login user
* @param $user
* @return mixed
*/
public function setUser($user);
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Block\Adminhtml;
use Magento\Backend\Block\Template;
use KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface;
use KiwiCommerce\AdminActivity\Helper\Browser;
/**
* Class ActivityLogListing
* @package KiwiCommerce\AdminActivity\Block\Adminhtml
*/
class ActivityLogListing extends Template
{
/**
* @var ActivityRepositoryInterface
*/
public $activityRepository;
/**
* @var Browser
*/
public $browser;
/**
* Path to template file in theme.
* @var string
*/
public $_template = 'KiwiCommerce_AdminActivity::log_listing.phtml';
/**
* ActivityLogListing constructor.
* @param Template\Context $context
* @param ActivityRepositoryInterface $activityRepository
* @param Browser $browser
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
ActivityRepositoryInterface $activityRepository,
Browser $browser
) {
$this->activityRepository = $activityRepository;
$this->browser = $browser;
parent::__construct($context);
}
/**
* Get admin activity log listing
* @return array
*/
public function getLogListing()
{
$id = $this->getRequest()->getParam('id');
$data = $this->activityRepository->getActivityLog($id);
return $data->getData();
}
/**
* Get admin activity details
* @return array
*/
public function getAdminDetails()
{
$id = $this->getRequest()->getParam('id');
$activity = $this->activityRepository->getActivityById($id);
$this->browser->reset();
$this->browser->setUserAgent($activity->getUserAgent());
$browser = $this->browser->__toString();
$logData = [];
$logData['username'] = $activity->getUsername();
$logData['module'] = $activity->getModule();
$logData['name'] = $activity->getName();
$logData['fullaction'] = $activity->getFullaction();
$logData['browser'] = $browser;
$logData['date'] = $activity->getUpdatedAt();
return $logData;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Block\Adminhtml;
/**
* Class Selector
* @package KiwiCommerce\AdminActivity\Block\Adminhtml
*/
class Selector extends \Magento\Backend\Block\Template
{
/**
* Revert Activity Log action URL
* @return string
*/
public function getRevertUrl()
{
return $this->getUrl('adminactivity/activity/revert');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customise this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Block\Adminhtml\System\Config\Fieldset;
use \Magento\Backend\Block\Template;
use \Magento\Framework\Data\Form\Element\Renderer\RendererInterface;
/**
* Class Hint
* @package KiwiCommerce\AdminActivity\Block\Adminhtml\System\Config\Fieldset
*/
class Hint extends Template implements RendererInterface
{
/**
* @var \Magento\Framework\Module\ModuleList
*/
private $moduleList;
/**
* Class constructor.
* @param Template\Context $context
* @param \Magento\Framework\Module\ModuleList $moduleList
* @param array $data
*/
public function __construct(
Template\Context $context,
\Magento\Framework\Module\ModuleList $moduleList,
array $data = []
) {
$this->_template = 'KiwiCommerce_AdminActivity::system/config/fieldset/hint.phtml';
parent::__construct($context, $data);
$this->moduleList = $moduleList;
}
/**
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
*/
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$_element = $element;
return $this->toHtml();
}
/**
* @return mixed
*/
public function getModuleVersion()
{
return $this->moduleList->getOne('KiwiCommerce_AdminActivity')['setup_version'];
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Controller\Adminhtml\Activity;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Backend\App\Action;
/**
* Class Index
* @package KiwiCommerce\AdminActivity\Controller\Adminhtml\Activity
*/
class Index extends Action
{
/**
* @var string
*/
const ADMIN_RESOURCE = 'KiwiCommerce_AdminActivity::activity';
/**
* @var PageFactory
*/
public $resultPageFactory;
/**
* Index constructor.
* @param Context $context
* @param PageFactory $resultPageFactory
*/
public function __construct(
Context $context,
PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
/**
* Index action
* @return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->setActiveMenu('KiwiCommerce_AdminActivity::activity');
$resultPage->addBreadcrumb(__('KiwiCommerce'), __('Admin Activity'));
$resultPage->getConfig()->getTitle()->prepend(__('Admin Activity'));
return $resultPage;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Controller\Adminhtml\Activity;
use Magento\Backend\App\Action\Context;
use Magento\Backend\App\Action;
/**
* Class Log
* @package KiwiCommerce\AdminActivity\Controller\Adminhtml\Activity
*/
class Log extends Action
{
/**
* @var \Magento\Framework\Controller\Result\RawFactory
*/
public $resultRawFactory;
/**
* @var \Magento\Framework\View\LayoutFactory
*/
public $layoutFactory;
/**
* Log constructor.
* @param Context $context
* @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
* @param \Magento\Framework\View\LayoutFactory $layoutFactory
*/
public function __construct(
Context $context,
\Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
\Magento\Framework\View\LayoutFactory $layoutFactory
) {
$this->resultRawFactory = $resultRawFactory;
$this->layoutFactory = $layoutFactory;
parent::__construct($context);
}
/**
* view action
* @return $this
*/
public function execute()
{
$content = $this->layoutFactory->create()
->createBlock(
\KiwiCommerce\AdminActivity\Block\Adminhtml\ActivityLogListing::class
);
/** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
$resultRaw = $this->resultRawFactory->create();
return $resultRaw->setContents($content->toHtml());
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Controller\Adminhtml\Activity;
use Magento\Backend\App\Action\Context;
use Magento\Backend\App\Action;
/**
* Class Revert
* @package KiwiCommerce\AdminActivity\Controller\Adminhtml\Activity
*/
class Revert extends Action
{
/**
* @var \Magento\Framework\Controller\Result\JsonFactory
*/
public $resultJsonFactory;
/**
* @var \KiwiCommerce\AdminActivity\Model\Processor
*/
public $processor;
/**
* Revert constructor.
* @param Context $context
* @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
* @param \KiwiCommerce\AdminActivity\Model\Processor $processor
*/
public function __construct(
Context $context,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
\KiwiCommerce\AdminActivity\Model\Processor $processor
) {
parent::__construct($context);
$this->resultJsonFactory = $resultJsonFactory;
$this->processor = $processor;
}
/**
* Revert action
* @return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
$activityId = $this->getRequest()->getParam('id');
$result = $this->processor->revertActivity($activityId);
return $this->resultJsonFactory->create()->setData($result);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Controller\Adminhtml\Login;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Backend\App\Action;
/**
* Class Index
* @package KiwiCommerce\AdminActivity\Controller\Adminhtml\Login
*/
class Index extends Action
{
/**
* @var string
*/
const ADMIN_RESOURCE = 'KiwiCommerce_AdminActivity::login_activity';
/**
* @var PageFactory
*/
public $resultPageFactory;
/**
* Index constructor.
* @param Context $context
* @param PageFactory $resultPageFactory
*/
public function __construct(
Context $context,
PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
/**
* Index action
* @return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->setActiveMenu('KiwiCommerce_AdminActivity::login_activity');
$resultPage->addBreadcrumb(__('KiwiCommerce'), __('Login Activity'));
$resultPage->getConfig()->getTitle()->prepend(__('Login Activity'));
return $resultPage;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Cron;
use Psr\Log\LoggerInterface;
use KiwiCommerce\AdminActivity\Helper\Data as Helper;
use KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface;
/**
* Class ClearLog
* @package KiwiCommerce\AdminActivity\Cron
*/
class ClearLog
{
/**
* Default date format
* @var string
*/
const DATE_FORMAT = 'Y-m-d H:i:s';
/**
* @var LoggerInterface
*/
public $logger;
/**
* @var \Magento\Framework\Stdlib\DateTime\DateTime
*/
public $dateTime;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Data
*/
public $helper;
/**
* @var ActivityRepositoryInterface
*/
public $activityRepository;
/**
* @var \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface
*/
public $loginRepository;
/**
* ClearLog constructor.
* @param LoggerInterface $logger
* @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
* @param Helper $helper
* @param ActivityRepositoryInterface $activityRepository
* @param \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository
*/
public function __construct(
LoggerInterface $logger,
\Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
Helper $helper,
ActivityRepositoryInterface $activityRepository,
\KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository
) {
$this->logger = $logger;
$this->dateTime = $dateTime;
$this->helper = $helper;
$this->activityRepository = $activityRepository;
$this->loginRepository = $loginRepository;
}
/**
* Return cron cleanup date
* @return null|string
*/
public function __getDate()
{
$timestamp = $this->dateTime->gmtTimestamp();
$day = $this->helper->getConfigValue('CLEAR_LOG_DAYS');
if ($day) {
$timestamp -= $day * 24 * 60 * 60;
return $this->dateTime->gmtDate(self::DATE_FORMAT, $timestamp);
}
return null;
}
/**
* Delete record which date is less than the current date
* @return $this|null
*/
public function execute()
{
try {
if (!$this->helper->isEnable()) {
return $this;
}
if ($date = $this->__getDate()) {
$activities = $this->activityRepository->getListBeforeDate($date);
if (!empty($activities)) {
foreach ($activities as $activity) {
//TODO: Remove activity detail
$activity->delete();
}
}
//TODO: Remove login activity detail
if ($this->helper->isLoginEnable()) {
$activities = $this->loginRepository->getListBeforeDate($date);
if (!empty($activities)) {
foreach ($activities as $activity) {
$activity->delete();
}
}
}
}
} catch (\Exception $e) {
$this->logger->debug($e->getMessage());
}
return null;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customise this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
/**
* Class Benchmark
* @package KiwiCommerce\AdminActivity\Helper
*/
class Benchmark extends AbstractHelper
{
/**
* Get Benchmark is enable or not
*/
const BENCHMARK_ENABLE = 1;
/**
* @var \KiwiCommerce\AdminActivity\Logger\Logger
*/
public $logger;
/**
* @var String[] Start time of execution
*/
public $startTime;
/**
* @var String[] End time of execution
*/
public $endTime;
/**
* Benchmark constructor.
* @param \Magento\Framework\App\Helper\Context $context
* @param \KiwiCommerce\AdminActivity\Logger\Logger $logger
*/
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\KiwiCommerce\AdminActivity\Logger\Logger $logger
) {
$this->logger = $logger;
parent::__construct($context);
}
/**
* log info about start time in millisecond
* @param $method
* @return void
*/
public function start($method)
{
$this->reset($method);
if (self::BENCHMARK_ENABLE) {
$this->startTime[$method] = round(microtime(true) * 1000);
$this->logger->info("Method: ". $method);
$this->logger->info("Start time: ". $this->startTime[$method]);
\Magento\Framework\Profiler::start($method);
}
}
/**
* log info about end time and time diiference in millisecond
* @param $method
* @return void
*/
public function end($method)
{
if (self::BENCHMARK_ENABLE) {
$this->endTime[$method] = round(microtime(true) * 1000);
$difference = $this->endTime[$method] - $this->startTime[$method];
if ($difference) {
$this->logger->info("Method: ". $method);
$this->logger->info("Ends time: ". $this->endTime[$method]);
$this->logger->info("Time difference in millisecond: ". $difference);
}
\Magento\Framework\Profiler::stop($method);
}
}
/**
* Reset start time and end time
* @param $method
* @return void
*/
public function reset($method)
{
$this->startTime[$method] = 0;
$this->endTime[$method] = 0;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Helper;
/**
* Class Browser
* @package KiwiCommerce\AdminActivity\Helper
*/
class Browser extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* @var string
*/
private $_agent = '';
/**
* @var string
*/
private $_browser_name = '';
/**
* @var string
*/
private $_version = '';
/**
* @var string
*/
private $_platform = '';
/**
* @var string
*/
private $_os = '';
/**
* @var bool
*/
private $_is_aol = false;
/**
* @var bool
*/
private $_is_mobile = false;
/**
* @var bool
*/
private $_is_tablet = false;
/**
* @var bool
*/
private $_is_robot = false;
/**
* @var bool
*/
private $_is_facebook = false;
/**
* @var string
*/
private $_aol_version = '';
const BROWSER_UNKNOWN = 'unknown';
const VERSION_UNKNOWN = 'unknown';
const BROWSER_OPERA = 'Opera'; // http://www.opera.com/
const BROWSER_OPERA_MINI = 'Opera Mini'; // http://www.opera.com/mini/
const BROWSER_WEBTV = 'WebTV'; // http://www.webtv.net/pc/
const BROWSER_EDGE = 'Edge'; // https://www.microsoft.com/edge
const BROWSER_IE = 'Internet Explorer'; // http://www.microsoft.com/ie/
const BROWSER_POCKET_IE = 'Pocket Internet Explorer'; // http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
const BROWSER_KONQUEROR = 'Konqueror'; // http://www.konqueror.org/
const BROWSER_ICAB = 'iCab'; // http://www.icab.de/
const BROWSER_OMNIWEB = 'OmniWeb'; // http://www.omnigroup.com/applications/omniweb/
const BROWSER_FIREBIRD = 'Firebird'; // http://www.ibphoenix.com/
const BROWSER_FIREFOX = 'Firefox'; // http://www.mozilla.com/en-US/firefox/firefox.html
const BROWSER_ICEWEASEL = 'Iceweasel'; // http://www.geticeweasel.org/
const BROWSER_SHIRETOKO = 'Shiretoko'; // http://wiki.mozilla.org/Projects/shiretoko
const BROWSER_MOZILLA = 'Mozilla'; // http://www.mozilla.com/en-US/
const BROWSER_AMAYA = 'Amaya'; // http://www.w3.org/Amaya/
const BROWSER_LYNX = 'Lynx'; // http://en.wikipedia.org/wiki/Lynx
const BROWSER_SAFARI = 'Safari'; // http://apple.com
const BROWSER_IPHONE = 'iPhone'; // http://apple.com
const BROWSER_IPOD = 'iPod'; // http://apple.com
const BROWSER_IPAD = 'iPad'; // http://apple.com
const BROWSER_CHROME = 'Chrome'; // http://www.google.com/chrome
const BROWSER_ANDROID = 'Android'; // http://www.android.com/
const BROWSER_GOOGLEBOT = 'GoogleBot'; // http://en.wikipedia.org/wiki/Googlebot
const BROWSER_YANDEXBOT = 'YandexBot'; // http://yandex.com/bots
const BROWSER_YANDEXIMAGERESIZER_BOT = 'YandexImageResizer'; // http://yandex.com/bots
const BROWSER_YANDEXIMAGES_BOT = 'YandexImages'; // http://yandex.com/bots
const BROWSER_YANDEXVIDEO_BOT = 'YandexVideo'; // http://yandex.com/bots
const BROWSER_YANDEXMEDIA_BOT = 'YandexMedia'; // http://yandex.com/bots
const BROWSER_YANDEXBLOGS_BOT = 'YandexBlogs'; // http://yandex.com/bots
const BROWSER_YANDEXFAVICONS_BOT = 'YandexFavicons'; // http://yandex.com/bots
const BROWSER_YANDEXWEBMASTER_BOT = 'YandexWebmaster'; // http://yandex.com/bots
const BROWSER_YANDEXDIRECT_BOT = 'YandexDirect'; // http://yandex.com/bots
const BROWSER_YANDEXMETRIKA_BOT = 'YandexMetrika'; // http://yandex.com/bots
const BROWSER_YANDEXNEWS_BOT = 'YandexNews'; // http://yandex.com/bots
const BROWSER_YANDEXCATALOG_BOT = 'YandexCatalog'; // http://yandex.com/bots
const BROWSER_SLURP = 'Yahoo! Slurp'; // http://en.wikipedia.org/wiki/Yahoo!_Slurp
const BROWSER_W3CVALIDATOR = 'W3C Validator'; // http://validator.w3.org/
const BROWSER_BLACKBERRY = 'BlackBerry'; // http://www.blackberry.com/
const BROWSER_ICECAT = 'IceCat'; // http://en.wikipedia.org/wiki/GNU_IceCat
const BROWSER_NOKIA_S60 = 'Nokia S60 OSS Browser'; // http://en.wikipedia.org/wiki/Web_Browser_for_S60
const BROWSER_NOKIA = 'Nokia Browser'; // * all other WAP-based browsers on the Nokia Platform
const BROWSER_MSN = 'MSN Browser'; // http://explorer.msn.com/
const BROWSER_MSNBOT = 'MSN Bot'; // http://search.msn.com/msnbot.htm
const BROWSER_BINGBOT = 'Bing Bot'; // http://en.wikipedia.org/wiki/Bingbot
const BROWSER_VIVALDI = 'Vivalidi'; // https://vivaldi.com/
const BROWSER_YANDEX = 'Yandex'; // https://browser.yandex.ua/
const BROWSER_NETSCAPE_NAVIGATOR = 'Netscape Navigator'; // http://browser.netscape.com/ (DEPRECATED)
const BROWSER_GALEON = 'Galeon'; // http://galeon.sourceforge.net/ (DEPRECATED)
const BROWSER_NETPOSITIVE = 'NetPositive'; // http://en.wikipedia.org/wiki/NetPositive (DEPRECATED)
const BROWSER_PHOENIX = 'Phoenix'; // http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox (DEPRECATED)
const BROWSER_PLAYSTATION = "PlayStation";
const BROWSER_SAMSUNG = "SamsungBrowser";
const BROWSER_SILK = "Silk";
const BROWSER_I_FRAME = "Iframely";
const BROWSER_COCOA = "CocoaRestClient";
const PLATFORM_UNKNOWN = 'unknown';
const PLATFORM_WINDOWS = 'Windows';
const PLATFORM_WINDOWS_CE = 'Windows CE';
const PLATFORM_APPLE = 'Apple';
const PLATFORM_LINUX = 'Linux';
const PLATFORM_OS2 = 'OS/2';
const PLATFORM_BEOS = 'BeOS';
const PLATFORM_IPHONE = 'iPhone';
const PLATFORM_IPOD = 'iPod';
const PLATFORM_IPAD = 'iPad';
const PLATFORM_BLACKBERRY = 'BlackBerry';
const PLATFORM_NOKIA = 'Nokia';
const PLATFORM_FREEBSD = 'FreeBSD';
const PLATFORM_OPENBSD = 'OpenBSD';
const PLATFORM_NETBSD = 'NetBSD';
const PLATFORM_SUNOS = 'SunOS';
const PLATFORM_OPENSOLARIS = 'OpenSolaris';
const PLATFORM_ANDROID = 'Android';
const PLATFORM_PLAYSTATION = "Sony PlayStation";
const PLATFORM_ROKU = "Roku";
const PLATFORM_APPLE_TV = "Apple TV";
const PLATFORM_TERMINAL = "Terminal";
const PLATFORM_FIRE_OS = "Fire OS";
const PLATFORM_SMART_TV = "SMART-TV";
const PLATFORM_CHROME_OS = "Chrome OS";
const PLATFORM_JAVA_ANDROID = "Java/Android";
const PLATFORM_POSTMAN = "Postman";
const PLATFORM_I_FRAME = "Iframely";
const OPERATING_SYSTEM_UNKNOWN = 'unknown';
/**
* Browser constructor.
* @param string $userAgent
*/
public function __construct($userAgent = "")
{
$this->reset();
if ($userAgent != "") {
$this->setUserAgent($userAgent);
} else {
$this->determine();
}
}
/**
* Reset all properties
* @return void
*/
public function reset()
{
$this->_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
$this->_browser_name = self::BROWSER_UNKNOWN;
$this->_version = self::VERSION_UNKNOWN;
$this->_platform = self::PLATFORM_UNKNOWN;
$this->_os = self::OPERATING_SYSTEM_UNKNOWN;
$this->_is_aol = false;
$this->_is_mobile = false;
$this->_is_tablet = false;
$this->_is_robot = false;
$this->_is_facebook = false;
$this->_aol_version = self::VERSION_UNKNOWN;
}
/**
* Check to see if the specific browser is valid
* @param string $browserName
* @return bool True if the browser is the specified browser
*/
function isBrowser($browserName)
{
return (0 == strcasecmp($this->_browser_name, trim($browserName)));
}
/**
* The name of the browser. All return types are from the class contants
* @return string Name of the browser
*/
public function getBrowser()
{
return $this->_browser_name;
}
/**
* Set the name of the browser
* @param $browser string The name of the Browser
* @return void
*/
public function setBrowser($browser)
{
$this->_browser_name = $browser;
}
/**
* The name of the platform. All return types are from the class contants
* @return string Name of the browser
*/
public function getPlatform()
{
return $this->_platform;
}
/**
* Set the name of the platform
* @param string $platform The name of the Platform
* @return void
*/
public function setPlatform($platform)
{
$this->_platform = $platform;
}
/**
* The version of the browser.
* @return string Version of the browser (will only contain alpha-numeric characters and a period)
*/
public function getVersion()
{
return $this->_version;
}
/**
* Set the version of the browser
* @param string $version The version of the Browser
* @return void
*/
public function setVersion($version)
{
$this->_version = preg_replace('/[^0-9,.,a-z,A-Z-]/', '', $version);
}
/**
* The version of AOL.
* @return string Version of AOL (will only contain alpha-numeric characters and a period)
*/
public function getAolVersion()
{
return $this->_aol_version;
}
/**
* Set the version of AOL
* @param string $version The version of AOL
* @return void
*/
public function setAolVersion($version)
{
$this->_aol_version = preg_replace('/[^0-9,.,a-z,A-Z]/', '', $version);
}
/**
* Is the browser from AOL?
* @return boolean True if the browser is from AOL otherwise false
*/
public function isAol()
{
return $this->_is_aol;
}
/**
* Is the browser from a mobile device?
* @return boolean True if the browser is from a mobile device otherwise false
*/
public function isMobile()
{
return $this->_is_mobile;
}
/**
* Is the browser from a tablet device?
* @return boolean True if the browser is from a tablet device otherwise false
*/
public function isTablet()
{
return $this->_is_tablet;
}
/**
* Is the browser from a robot (ex Slurp,GoogleBot)?
* @return boolean True if the browser is from a robot otherwise false
*/
public function isRobot()
{
return $this->_is_robot;
}
/**
* Is the browser from facebook?
* @return boolean True if the browser is from facebook otherwise false
*/
public function isFacebook()
{
return $this->_is_facebook;
}
/**
* Set the browser to be from AOL
* @param $isAol
* @return void
*/
public function setAol($isAol)
{
$this->_is_aol = $isAol;
}
/**
* Set the Browser to be mobile
* @param boolean $value is the browser a mobile browser or not
* @return void
*/
protected function setMobile($value = true)
{
$this->_is_mobile = $value;
}
/**
* Set the Browser to be tablet
* @param boolean $value is the browser a tablet browser or not
* @return void
*/
protected function setTablet($value = true)
{
$this->_is_tablet = $value;
}
/**
* Set the Browser to be a robot
* @param boolean $value is the browser a robot or not
* @return void
*/
protected function setRobot($value = true)
{
$this->_is_robot = $value;
}
/**
* Set the Browser to be a Facebook request
* @param boolean $value is the browser a robot or not
* @return void
*/
protected function setFacebook($value = true)
{
$this->_is_facebook = $value;
}
/**
* Get the user agent value in use to determine the browser
* @return string The user agent from the HTTP header
*/
public function getUserAgent()
{
return $this->_agent;
}
/**
* Set the user agent value (the construction will use the HTTP header value - this will overwrite it)
* @param string $agent_string The value for the User Agent
* @return void
*/
public function setUserAgent($agent_string)
{
$this->reset();
$this->_agent = $agent_string;
$this->determine();
}
/**
* Used to determine if the browser is actually "chromeframe"
* @since 1.7
* @return boolean True if the browser is using chromeframe
*/
public function isChromeFrame()
{
return (strpos($this->_agent, "chromeframe") !== false);
}
/**
* Returns a formatted string with a summary of the details of the browser.
* @return string formatted string with a summary of the browser
*/
public function __toString()
{
$device = ($this->isMobile())?'Mobile':(($this->isTablet())?'Tablet':'Desktop');
return "<strong>Browser Name:</strong> {$this->getBrowser()}<br/>\n" .
"<strong>Browser Version:</strong> {$this->getVersion()}<br/>\n" .
"<strong>Platform:</strong> {$this->getPlatform()}<br/>\n" .
"<strong>Device:</strong> {$device}";
}
/**
* Protected routine to calculate and determine what the browser is in use (including platform)
* @return void
*/
protected function determine()
{
$this->checkPlatform();
$this->checkBrowsers();
$this->checkForAol();
}
/**
* Protected routine to determine the browser type
* @return boolean True if the browser was detected otherwise false
*/
protected function checkBrowsers()
{
return (
// well-known, well-used
// Special Notes:
// (1) Opera must be checked before FireFox due to the odd
// user agents used in some older versions of Opera
// (2) WebTV is strapped onto Internet Explorer so we must
// check for WebTV before IE
// (3) (deprecated) Galeon is based on Firefox and needs to be
// tested before Firefox is tested
// (4) OmniWeb is based on Safari so OmniWeb check must occur
// before Safari
// (5) Netscape 9+ is based on Firefox so Netscape checks
// before FireFox are necessary
// (6) Vivalid is UA contains both Firefox and Chrome so Vivalid checks
// before Firefox and Chrome
$this->checkBrowserWebTv() ||
$this->checkBrowserEdge() ||
$this->checkBrowserInternetExplorer() ||
$this->checkBrowserOpera() ||
$this->checkBrowserGaleon() ||
$this->checkBrowserNetscapeNavigator9Plus() ||
$this->checkBrowserVivaldi() ||
$this->checkBrowserYandex() ||
$this->checkBrowserFirefox() ||
$this->checkBrowserChrome() ||
$this->checkBrowserOmniWeb() ||
// common mobile
$this->checkBrowserAndroid() ||
$this->checkBrowseriPad() ||
$this->checkBrowseriPod() ||
$this->checkBrowseriPhone() ||
$this->checkBrowserBlackBerry() ||
$this->checkBrowserNokia() ||
// common bots
$this->checkBrowserGoogleBot() ||
$this->checkBrowserMSNBot() ||
$this->checkBrowserBingBot() ||
$this->checkBrowserSlurp() ||
// Yandex bots
$this->checkBrowserYandexBot() ||
$this->checkBrowserYandexImageResizerBot() ||
$this->checkBrowserYandexBlogsBot() ||
$this->checkBrowserYandexCatalogBot() ||
$this->checkBrowserYandexDirectBot() ||
$this->checkBrowserYandexFaviconsBot() ||
$this->checkBrowserYandexImagesBot() ||
$this->checkBrowserYandexMediaBot() ||
$this->checkBrowserYandexMetrikaBot() ||
$this->checkBrowserYandexNewsBot() ||
$this->checkBrowserYandexVideoBot() ||
$this->checkBrowserYandexWebmasterBot() ||
// check for facebook external hit when loading URL
$this->checkFacebookExternalHit() ||
// WebKit base check (post mobile and others)
$this->checkBrowserSamsung() ||
$this->checkBrowserSilk() ||
$this->checkBrowserSafari() ||
// everyone else
$this->checkBrowserNetPositive() ||
$this->checkBrowserFirebird() ||
$this->checkBrowserKonqueror() ||
$this->checkBrowserIcab() ||
$this->checkBrowserPhoenix() ||
$this->checkBrowserAmaya() ||
$this->checkBrowserLynx() ||
$this->checkBrowserShiretoko() ||
$this->checkBrowserIceCat() ||
$this->checkBrowserIceweasel() ||
$this->checkBrowserW3CValidator() ||
$this->checkBrowserPlayStation() ||
$this->checkBrowserIframely() ||
$this->checkBrowserCocoa() ||
$this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
);
}
/**
* Determine if the user is using a BlackBerry (last updated 1.7)
* @return boolean True if the browser is the BlackBerry browser otherwise false
*/
protected function checkBrowserBlackBerry()
{
if (stripos($this->_agent, 'blackberry') !== false) {
$aresult = explode("/", stristr($this->_agent, "BlackBerry"));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_BLACKBERRY;
$this->setMobile(true);
return true;
}
}
return false;
}
/**
* Determine if the user is using an AOL User Agent (last updated 1.7)
* @return boolean True if the browser is from AOL otherwise false
*/
protected function checkForAol()
{
$this->setAol(false);
$this->setAolVersion(self::VERSION_UNKNOWN);
if (stripos($this->_agent, 'aol') !== false) {
$aversion = explode(' ', stristr($this->_agent, 'AOL'));
if (isset($aversion[1])) {
$this->setAol(true);
$this->setAolVersion(preg_replace('/[^0-9\.a-z]/i', '', $aversion[1]));
return true;
}
}
return false;
}
/**
* Determine if the browser is the GoogleBot or not (last updated 1.7)
* @return boolean True if the browser is the GoogletBot otherwise false
*/
protected function checkBrowserGoogleBot()
{
if (stripos($this->_agent, 'googlebot') !== false) {
$aresult = explode('/', stristr($this->_agent, 'googlebot'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_GOOGLEBOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexBot or not
* @return boolean True if the browser is the YandexBot otherwise false
*/
protected function checkBrowserYandexBot()
{
if (stripos($this->_agent, 'YandexBot') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexBot'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXBOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexImageResizer or not
* @return boolean True if the browser is the YandexImageResizer otherwise false
*/
protected function checkBrowserYandexImageResizerBot()
{
if (stripos($this->_agent, 'YandexImageResizer') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexImageResizer'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXIMAGERESIZER_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexCatalog or not
* @return boolean True if the browser is the YandexCatalog otherwise false
*/
protected function checkBrowserYandexCatalogBot()
{
if (stripos($this->_agent, 'YandexCatalog') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexCatalog'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXCATALOG_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexNews or not
* @return boolean True if the browser is the YandexNews otherwise false
*/
protected function checkBrowserYandexNewsBot()
{
if (stripos($this->_agent, 'YandexNews') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexNews'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXNEWS_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexMetrika or not
* @return boolean True if the browser is the YandexMetrika otherwise false
*/
protected function checkBrowserYandexMetrikaBot()
{
if (stripos($this->_agent, 'YandexMetrika') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexMetrika'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXMETRIKA_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexDirect or not
* @return boolean True if the browser is the YandexDirect otherwise false
*/
protected function checkBrowserYandexDirectBot()
{
if (stripos($this->_agent, 'YandexDirect') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexDirect'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXDIRECT_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexWebmaster or not
* @return boolean True if the browser is the YandexWebmaster otherwise false
*/
protected function checkBrowserYandexWebmasterBot()
{
if (stripos($this->_agent, 'YandexWebmaster') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexWebmaster'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXWEBMASTER_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexFavicons or not
* @return boolean True if the browser is the YandexFavicons otherwise false
*/
protected function checkBrowserYandexFaviconsBot()
{
if (stripos($this->_agent, 'YandexFavicons') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexFavicons'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXFAVICONS_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexBlogs or not
* @return boolean True if the browser is the YandexBlogs otherwise false
*/
protected function checkBrowserYandexBlogsBot()
{
if (stripos($this->_agent, 'YandexBlogs') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexBlogs'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXBLOGS_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexMedia or not
* @return boolean True if the browser is the YandexMedia otherwise false
*/
protected function checkBrowserYandexMediaBot()
{
if (stripos($this->_agent, 'YandexMedia') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexMedia'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXMEDIA_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexVideo or not
* @return boolean True if the browser is the YandexVideo otherwise false
*/
protected function checkBrowserYandexVideoBot()
{
if (stripos($this->_agent, 'YandexVideo') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexVideo'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXVIDEO_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the YandexImages or not
* @return boolean True if the browser is the YandexImages otherwise false
*/
protected function checkBrowserYandexImagesBot()
{
if (stripos($this->_agent, 'YandexImages') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YandexImages'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(';', '', $aversion[0]));
$this->_browser_name = self::BROWSER_YANDEXIMAGES_BOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the MSNBot or not (last updated 1.9)
* @return boolean True if the browser is the MSNBot otherwise false
*/
protected function checkBrowserMSNBot()
{
if (stripos($this->_agent, "msnbot") !== false) {
$aresult = explode("/", stristr($this->_agent, "msnbot"));
if (isset($aresult[1])) {
$aversion = explode(" ", $aresult[1]);
$this->setVersion(str_replace(";", "", $aversion[0]));
$this->_browser_name = self::BROWSER_MSNBOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the BingBot or not (last updated 1.9)
* @return boolean True if the browser is the BingBot otherwise false
*/
protected function checkBrowserBingBot()
{
if (stripos($this->_agent, "bingbot") !== false) {
$aresult = explode("/", stristr($this->_agent, "bingbot"));
if (isset($aresult[1])) {
$aversion = explode(" ", $aresult[1]);
$this->setVersion(str_replace(";", "", $aversion[0]));
$this->_browser_name = self::BROWSER_BINGBOT;
$this->setRobot(true);
return true;
}
}
return false;
}
/**
* Determine if the browser is the W3C Validator or not (last updated 1.7)
* @return boolean True if the browser is the W3C Validator otherwise false
*/
protected function checkBrowserW3CValidator()
{
if (stripos($this->_agent, 'W3C-checklink') !== false) {
$aresult = explode('/', stristr($this->_agent, 'W3C-checklink'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_W3CVALIDATOR;
return true;
}
} elseif (stripos($this->_agent, 'W3C_Validator') !== false) {
// Some of the Validator versions do not delineate w/ a slash - add it back in
$ua = str_replace("W3C_Validator ", "W3C_Validator/", $this->_agent);
$aresult = explode('/', stristr($ua, 'W3C_Validator'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_W3CVALIDATOR;
return true;
}
} elseif (stripos($this->_agent, 'W3C-mobileOK') !== false) {
$this->_browser_name = self::BROWSER_W3CVALIDATOR;
$this->setMobile(true);
return true;
}
return false;
}
/**
* Determine if the browser is the Yahoo! Slurp Robot or not (last updated 1.7)
* @return boolean True if the browser is the Yahoo! Slurp Robot otherwise false
*/
protected function checkBrowserSlurp()
{
if (stripos($this->_agent, 'slurp') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Slurp'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_SLURP;
$this->setRobot(true);
$this->setMobile(false);
return true;
}
}
return false;
}
/**
* Determine if the browser is Edge or not
* @return boolean True if the browser is Edge otherwise false
*/
protected function checkBrowserEdge()
{
if (stripos($this->_agent, 'Edge/') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Edge'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_EDGE);
if (stripos($this->_agent, 'Windows Phone') !== false || stripos($this->_agent, 'Android') !== false) {
$this->setMobile(true);
}
return true;
}
}
return false;
}
/**
* Determine if the browser is Internet Explorer or not (last updated 1.7)
* @return boolean True if the browser is Internet Explorer otherwise false
*/
protected function checkBrowserInternetExplorer()
{
// Test for IE11
if (stripos($this->_agent, 'Trident/7.0; rv:11.0') !== false) {
$this->setBrowser(self::BROWSER_IE);
$this->setVersion('11.0');
return true;
} // Test for v1 - v1.5 IE
elseif (stripos($this->_agent, 'microsoft internet explorer') !== false) {
$this->setBrowser(self::BROWSER_IE);
$this->setVersion('1.0');
$aresult = stristr($this->_agent, '/');
if (preg_match('/308|425|426|474|0b1/i', $aresult)) {
$this->setVersion('1.5');
}
return true;
} // Test for versions > 1.5
elseif (stripos($this->_agent, 'msie') !== false && stripos($this->_agent, 'opera') === false) {
// See if the browser is the odd MSN Explorer
if (stripos($this->_agent, 'msnb') !== false) {
$aresult = explode(' ', stristr(str_replace(';', '; ', $this->_agent), 'MSN'));
if (isset($aresult[1])) {
$this->setBrowser(self::BROWSER_MSN);
$this->setVersion(str_replace(array('(', ')', ';'), '', $aresult[1]));
return true;
}
}
$aresult = explode(' ', stristr(str_replace(';', '; ', $this->_agent), 'msie'));
if (isset($aresult[1])) {
$this->setBrowser(self::BROWSER_IE);
$this->setVersion(str_replace(array('(', ')', ';'), '', $aresult[1]));
if(preg_match('#trident/([0-9\.]+);#i', $this->_agent, $aresult)){
if($aresult[1] == '3.1'){
$this->setVersion('7.0');
}
else if($aresult[1] == '4.0'){
$this->setVersion('8.0');
}
else if($aresult[1] == '5.0'){
$this->setVersion('9.0');
}
else if($aresult[1] == '6.0'){
$this->setVersion('10.0');
}
else if($aresult[1] == '7.0'){
$this->setVersion('11.0');
}
else if($aresult[1] == '8.0'){
$this->setVersion('11.0');
}
}
if(stripos($this->_agent, 'IEMobile') !== false) {
$this->setBrowser(self::BROWSER_POCKET_IE);
$this->setMobile(true);
}
return true;
}
} // Test for versions > IE 10
else if (stripos($this->_agent, 'trident') !== false) {
$this->setBrowser(self::BROWSER_IE);
$result = explode('rv:', $this->_agent);
if (isset($result[1])) {
$this->setVersion(preg_replace('/[^0-9.]+/', '', $result[1]));
$this->_agent = str_replace(array("Mozilla", "Gecko"), "MSIE", $this->_agent);
}
} // Test for Pocket IE
else if (stripos($this->_agent, 'mspie') !== false || stripos($this->_agent, 'pocket') !== false) {
$aresult = explode(' ', stristr($this->_agent, 'mspie'));
if (isset($aresult[1])) {
$this->setPlatform(self::PLATFORM_WINDOWS_CE);
$this->setBrowser(self::BROWSER_POCKET_IE);
$this->setMobile(true);
if (stripos($this->_agent, 'mspie') !== false) {
$this->setVersion($aresult[1]);
} else {
$aversion = explode('/', $this->_agent);
if (isset($aversion[1])) {
$this->setVersion($aversion[1]);
}
}
return true;
}
}
return false;
}
/**
* Determine if the browser is Opera or not (last updated 1.7)
* @return boolean True if the browser is Opera otherwise false
*/
protected function checkBrowserOpera()
{
if (stripos($this->_agent, 'opera mini') !== false) {
$resultant = stristr($this->_agent, 'opera mini');
if (preg_match('/\//', $resultant)) {
$aresult = explode('/', $resultant);
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
}
} else {
$aversion = explode(' ', stristr($resultant, 'opera mini'));
if (isset($aversion[1])) {
$this->setVersion($aversion[1]);
}
}
$this->_browser_name = self::BROWSER_OPERA_MINI;
$this->setMobile(true);
return true;
} else if (stripos($this->_agent, 'opera') !== false) {
$resultant = stristr($this->_agent, 'opera');
if (preg_match('/Version\/(1*.*)$/', $resultant, $matches)) {
$this->setVersion($matches[1]);
} else if (preg_match('/\//', $resultant)) {
$aresult = explode('/', str_replace("(", " ", $resultant));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
}
} else {
$aversion = explode(' ', stristr($resultant, 'opera'));
$this->setVersion(isset($aversion[1]) ? $aversion[1] : "");
}
if (stripos($this->_agent, 'Opera Mobi') !== false) {
$this->setMobile(true);
}
$this->_browser_name = self::BROWSER_OPERA;
return true;
} else if (stripos($this->_agent, 'OPR') !== false) {
$resultant = stristr($this->_agent, 'OPR');
if (preg_match('/\//', $resultant)) {
$aresult = explode('/', str_replace("(", " ", $resultant));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
}
}
if (stripos($this->_agent, 'Mobile') !== false) {
$this->setMobile(true);
}
$this->_browser_name = self::BROWSER_OPERA;
return true;
}
return false;
}
/**
* Determine if the browser is Chrome or not (last updated 1.7)
* @return boolean True if the browser is Chrome otherwise false
*/
protected function checkBrowserChrome()
{
if (stripos($this->_agent, 'Chrome') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Chrome'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_CHROME);
//Chrome on Android
if (stripos($this->_agent, 'Android') !== false) {
if (stripos($this->_agent, 'Mobile') !== false) {
$this->setMobile(true);
} else {
$this->setTablet(true);
}
}
return true;
}
}
return false;
}
/**
* Determine if the browser is WebTv or not (last updated 1.7)
* @return boolean True if the browser is WebTv otherwise false
*/
protected function checkBrowserWebTv()
{
if (stripos($this->_agent, 'webtv') !== false) {
$aresult = explode('/', stristr($this->_agent, 'webtv'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_WEBTV);
return true;
}
}
return false;
}
/**
* Determine if the browser is NetPositive or not (last updated 1.7)
* @return boolean True if the browser is NetPositive otherwise false
*/
protected function checkBrowserNetPositive()
{
if (stripos($this->_agent, 'NetPositive') !== false) {
$aresult = explode('/', stristr($this->_agent, 'NetPositive'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion(str_replace(array('(', ')', ';'), '', $aversion[0]));
$this->setBrowser(self::BROWSER_NETPOSITIVE);
return true;
}
}
return false;
}
/**
* Determine if the browser is Galeon or not (last updated 1.7)
* @return boolean True if the browser is Galeon otherwise false
*/
protected function checkBrowserGaleon()
{
if (stripos($this->_agent, 'galeon') !== false) {
$aresult = explode(' ', stristr($this->_agent, 'galeon'));
$aversion = explode('/', $aresult[0]);
if (isset($aversion[1])) {
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_GALEON);
return true;
}
}
return false;
}
/**
* Determine if the browser is Konqueror or not (last updated 1.7)
* @return boolean True if the browser is Konqueror otherwise false
*/
protected function checkBrowserKonqueror()
{
if (stripos($this->_agent, 'Konqueror') !== false) {
$aresult = explode(' ', stristr($this->_agent, 'Konqueror'));
$aversion = explode('/', $aresult[0]);
if (isset($aversion[1])) {
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_KONQUEROR);
return true;
}
}
return false;
}
/**
* Determine if the browser is iCab or not (last updated 1.7)
* @return boolean True if the browser is iCab otherwise false
*/
protected function checkBrowserIcab()
{
if (stripos($this->_agent, 'icab') !== false) {
$aversion = explode(' ', stristr(str_replace('/', ' ', $this->_agent), 'icab'));
if (isset($aversion[1])) {
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_ICAB);
return true;
}
}
return false;
}
/**
* Determine if the browser is OmniWeb or not (last updated 1.7)
* @return boolean True if the browser is OmniWeb otherwise false
*/
protected function checkBrowserOmniWeb()
{
if (stripos($this->_agent, 'omniweb') !== false) {
$aresult = explode('/', stristr($this->_agent, 'omniweb'));
$aversion = explode(' ', isset($aresult[1]) ? $aresult[1] : "");
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_OMNIWEB);
return true;
}
return false;
}
/**
* Determine if the browser is Phoenix or not (last updated 1.7)
* @return boolean True if the browser is Phoenix otherwise false
*/
protected function checkBrowserPhoenix()
{
if (stripos($this->_agent, 'Phoenix') !== false) {
$aversion = explode('/', stristr($this->_agent, 'Phoenix'));
if (isset($aversion[1])) {
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_PHOENIX);
return true;
}
}
return false;
}
/**
* Determine if the browser is Firebird or not (last updated 1.7)
* @return boolean True if the browser is Firebird otherwise false
*/
protected function checkBrowserFirebird()
{
if (stripos($this->_agent, 'Firebird') !== false) {
$aversion = explode('/', stristr($this->_agent, 'Firebird'));
if (isset($aversion[1])) {
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_FIREBIRD);
return true;
}
}
return false;
}
/**
* Determine if the browser is Netscape Navigator 9+ or not (last updated 1.7)
* NOTE: (http://browser.netscape.com/ - Official support ended on March 1st, 2008)
* @return boolean True if the browser is Netscape Navigator 9+ otherwise false
*/
protected function checkBrowserNetscapeNavigator9Plus()
{
if (stripos($this->_agent, 'Firefox') !== false && preg_match('/Navigator\/([^ ]*)/i', $this->_agent, $matches)) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
return true;
} else if (stripos($this->_agent, 'Firefox') === false && preg_match('/Netscape6?\/([^ ]*)/i', $this->_agent, $matches)) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
return true;
}
return false;
}
/**
* Determine if the browser is Shiretoko or not (https://wiki.mozilla.org/Projects/shiretoko) (last updated 1.7)
* @return boolean True if the browser is Shiretoko otherwise false
*/
protected function checkBrowserShiretoko()
{
if (stripos($this->_agent, 'Mozilla') !== false && preg_match('/Shiretoko\/([^ ]*)/i', $this->_agent, $matches)) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_SHIRETOKO);
return true;
}
return false;
}
/**
* Determine if the browser is Ice Cat or not (http://en.wikipedia.org/wiki/GNU_IceCat) (last updated 1.7)
* @return boolean True if the browser is Ice Cat otherwise false
*/
protected function checkBrowserIceCat()
{
if (stripos($this->_agent, 'Mozilla') !== false && preg_match('/IceCat\/([^ ]*)/i', $this->_agent, $matches)) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_ICECAT);
return true;
}
return false;
}
/**
* Determine if the browser is Nokia or not (last updated 1.7)
* @return boolean True if the browser is Nokia otherwise false
*/
protected function checkBrowserNokia()
{
if (preg_match("/Nokia([^\/]+)\/([^ SP]+)/i", $this->_agent, $matches)) {
$this->setVersion($matches[2]);
if (stripos($this->_agent, 'Series60') !== false || strpos($this->_agent, 'S60') !== false) {
$this->setBrowser(self::BROWSER_NOKIA_S60);
} else {
$this->setBrowser(self::BROWSER_NOKIA);
}
$this->setMobile(true);
return true;
}
return false;
}
/**
* Determine if the browser is Firefox or not (last updated 1.7)
* @return boolean True if the browser is Firefox otherwise false
*/
protected function checkBrowserFirefox()
{
if (stripos($this->_agent, 'safari') === false) {
if (preg_match("/Firefox[\/ \(]([^ ;\)]+)/i", $this->_agent, $matches)) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_FIREFOX);
//Firefox on Android
if (stripos($this->_agent, 'Android') !== false) {
if (stripos($this->_agent, 'Mobile') !== false) {
$this->setMobile(true);
} else {
$this->setTablet(true);
}
}
return true;
} else if (preg_match("/Firefox$/i", $this->_agent, $matches)) {
$this->setVersion("");
$this->setBrowser(self::BROWSER_FIREFOX);
return true;
}
}
return false;
}
/**
* Determine if the browser is Firefox or not (last updated 1.7)
* @return boolean True if the browser is Firefox otherwise false
*/
protected function checkBrowserIceweasel()
{
if (stripos($this->_agent, 'Iceweasel') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Iceweasel'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_ICEWEASEL);
return true;
}
}
return false;
}
/**
* Determine if the browser is Mozilla or not (last updated 1.7)
* @return boolean True if the browser is Mozilla otherwise false
*/
protected function checkBrowserMozilla()
{
if (stripos($this->_agent, 'mozilla') !== false && preg_match('/rv:[0-9].[0-9][a-b]?/i', $this->_agent) && stripos($this->_agent, 'netscape') === false) {
$aversion = explode(' ', stristr($this->_agent, 'rv:'));
preg_match('/rv:[0-9].[0-9][a-b]?/i', $this->_agent, $aversion);
$this->setVersion(str_replace('rv:', '', $aversion[0]));
$this->setBrowser(self::BROWSER_MOZILLA);
return true;
} else if (stripos($this->_agent, 'mozilla') !== false && preg_match('/rv:[0-9]\.[0-9]/i', $this->_agent) && stripos($this->_agent, 'netscape') === false) {
$aversion = explode('', stristr($this->_agent, 'rv:'));
$this->setVersion(str_replace('rv:', '', $aversion[0]));
$this->setBrowser(self::BROWSER_MOZILLA);
return true;
} else if (stripos($this->_agent, 'mozilla') !== false && preg_match('/mozilla\/([^ ]*)/i', $this->_agent, $matches) && stripos($this->_agent, 'netscape') === false) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_MOZILLA);
return true;
}
return false;
}
/**
* Determine if the browser is Lynx or not (last updated 1.7)
* @return boolean True if the browser is Lynx otherwise false
*/
protected function checkBrowserLynx()
{
if (stripos($this->_agent, 'lynx') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Lynx'));
$aversion = explode(' ', (isset($aresult[1]) ? $aresult[1] : ""));
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_LYNX);
return true;
}
return false;
}
/**
* Determine if the browser is Amaya or not (last updated 1.7)
* @return boolean True if the browser is Amaya otherwise false
*/
protected function checkBrowserAmaya()
{
if (stripos($this->_agent, 'amaya') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Amaya'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_AMAYA);
return true;
}
}
return false;
}
/**
* Determine if the browser is Safari or not (last updated 1.7)
* @return boolean True if the browser is Safari otherwise false
*/
protected function checkBrowserSafari()
{
if (stripos($this->_agent, 'Safari') !== false
&& stripos($this->_agent, 'iPhone') === false
&& stripos($this->_agent, 'iPod') === false
) {
$aresult = explode('/', stristr($this->_agent, 'Version'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
} else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setBrowser(self::BROWSER_SAFARI);
return true;
}
return false;
}
/**
* Check browser
* @return bool
*/
protected function checkBrowserSamsung()
{
if (stripos($this->_agent, 'SamsungBrowser') !== false) {
$aresult = explode('/', stristr($this->_agent, 'SamsungBrowser'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
} else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setBrowser(self::BROWSER_SAMSUNG);
return true;
}
return false;
}
/**
* Check browser
* @return bool
*/
protected function checkBrowserSilk()
{
if (stripos($this->_agent, 'Silk') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Silk'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
} else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setBrowser(self::BROWSER_SILK);
return true;
}
return false;
}
/**
* Check browser
* @return bool
*/
protected function checkBrowserIframely()
{
if (stripos($this->_agent, 'Iframely') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Iframely'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
} else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setBrowser(self::BROWSER_I_FRAME);
return true;
}
return false;
}
/**
* Check browser
* @return bool
*/
protected function checkBrowserCocoa()
{
if (stripos($this->_agent, 'CocoaRestClient') !== false) {
$aresult = explode('/', stristr($this->_agent, 'CocoaRestClient'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
} else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setBrowser(self::BROWSER_COCOA);
return true;
}
return false;
}
/**
* Detect if URL is loaded from FacebookExternalHit
* @return boolean True if it detects FacebookExternalHit otherwise false
*/
protected function checkFacebookExternalHit()
{
if (stristr($this->_agent, 'FacebookExternalHit')) {
$this->setRobot(true);
$this->setFacebook(true);
return true;
}
return false;
}
/**
* Detect if URL is being loaded from internal Facebook browser
* @return boolean True if it detects internal Facebook browser otherwise false
*/
protected function checkForFacebookIos()
{
if (stristr($this->_agent, 'FBIOS')) {
$this->setFacebook(true);
return true;
}
return false;
}
/**
* Detect Version for the Safari browser on iOS devices
* @return boolean True if it detects the version correctly otherwise false
*/
protected function getSafariVersionOnIos()
{
$aresult = explode('/', stristr($this->_agent, 'Version'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
return true;
}
return false;
}
/**
* Detect Version for the Chrome browser on iOS devices
* @return boolean True if it detects the version correctly otherwise false
*/
protected function getChromeVersionOnIos()
{
$aresult = explode('/', stristr($this->_agent, 'CriOS'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_CHROME);
return true;
}
return false;
}
/**
* Determine if the browser is iPhone or not (last updated 1.7)
* @return boolean True if the browser is iPhone otherwise false
*/
protected function checkBrowseriPhone()
{
if (stripos($this->_agent, 'iPhone') !== false) {
$this->setVersion(self::VERSION_UNKNOWN);
$this->setBrowser(self::BROWSER_IPHONE);
$this->getSafariVersionOnIos();
$this->getChromeVersionOnIos();
$this->checkForFacebookIos();
$this->setMobile(true);
return true;
}
return false;
}
/**
* Determine if the browser is iPad or not (last updated 1.7)
* @return boolean True if the browser is iPad otherwise false
*/
protected function checkBrowseriPad()
{
if (stripos($this->_agent, 'iPad') !== false) {
$this->setVersion(self::VERSION_UNKNOWN);
$this->setBrowser(self::BROWSER_IPAD);
$this->getSafariVersionOnIos();
$this->getChromeVersionOnIos();
$this->checkForFacebookIos();
$this->setTablet(true);
return true;
}
return false;
}
/**
* Determine if the browser is iPod or not (last updated 1.7)
* @return boolean True if the browser is iPod otherwise false
*/
protected function checkBrowseriPod()
{
if (stripos($this->_agent, 'iPod') !== false) {
$this->setVersion(self::VERSION_UNKNOWN);
$this->setBrowser(self::BROWSER_IPOD);
$this->getSafariVersionOnIos();
$this->getChromeVersionOnIos();
$this->checkForFacebookIos();
$this->setMobile(true);
return true;
}
return false;
}
/**
* Determine if the browser is Android or not (last updated 1.7)
* @return boolean True if the browser is Android otherwise false
*/
protected function checkBrowserAndroid()
{
if (stripos($this->_agent, 'Android') !== false) {
$aresult = explode(' ', stristr($this->_agent, 'Android'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
} else {
$this->setVersion(self::VERSION_UNKNOWN);
}
if (stripos($this->_agent, 'Mobile') !== false) {
$this->setMobile(true);
} else {
$this->setTablet(true);
}
$this->setBrowser(self::BROWSER_ANDROID);
return true;
}
return false;
}
/**
* Determine if the browser is Vivaldi
* @return boolean True if the browser is Vivaldi otherwise false
*/
protected function checkBrowserVivaldi()
{
if (stripos($this->_agent, 'Vivaldi') !== false) {
$aresult = explode('/', stristr($this->_agent, 'Vivaldi'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_VIVALDI);
return true;
}
}
return false;
}
/**
* Determine if the browser is Yandex
* @return boolean True if the browser is Yandex otherwise false
*/
protected function checkBrowserYandex()
{
if (stripos($this->_agent, 'YaBrowser') !== false) {
$aresult = explode('/', stristr($this->_agent, 'YaBrowser'));
if (isset($aresult[1])) {
$aversion = explode(' ', $aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_YANDEX);
if (stripos($this->_agent, 'iPad') !== false) {
$this->setTablet(true);
} elseif (stripos($this->_agent, 'Mobile') !== false) {
$this->setMobile(true);
} elseif (stripos($this->_agent, 'Android') !== false) {
$this->setTablet(true);
}
return true;
}
}
return false;
}
/**
* Determine if the browser is a PlayStation
* @return boolean True if the browser is PlayStation otherwise false
*/
protected function checkBrowserPlayStation()
{
if (stripos($this->_agent, 'PlayStation ') !== false) {
$aresult = explode(' ', stristr($this->_agent, 'PlayStation '));
$this->setBrowser(self::BROWSER_PLAYSTATION);
if (isset($aresult[0])) {
$aversion = explode(')', $aresult[2]);
$this->setVersion($aversion[0]);
if (stripos($this->_agent, 'Portable)') !== false || stripos($this->_agent, 'Vita') !== false) {
$this->setMobile(true);
}
return true;
}
}
return false;
}
/**
* Determine the user's platform (last updated 2.0)
* @return void
*/
protected function checkPlatform()
{
if (stripos($this->_agent, 'windows') !== false) {
$this->_platform = self::PLATFORM_WINDOWS;
} else if (stripos($this->_agent, 'iPad') !== false) {
$this->_platform = self::PLATFORM_IPAD;
} else if (stripos($this->_agent, 'iPod') !== false) {
$this->_platform = self::PLATFORM_IPOD;
} else if (stripos($this->_agent, 'iPhone') !== false) {
$this->_platform = self::PLATFORM_IPHONE;
} elseif (stripos($this->_agent, 'mac') !== false) {
$this->_platform = self::PLATFORM_APPLE;
} elseif (stripos($this->_agent, 'android') !== false) {
$this->_platform = self::PLATFORM_ANDROID;
} elseif (stripos($this->_agent, 'Silk') !== false) {
$this->_platform = self::PLATFORM_FIRE_OS;
} elseif (stripos($this->_agent, 'linux') !== false && stripos($this->_agent, 'SMART-TV') !== false ) {
$this->_platform = self::PLATFORM_LINUX .'/'.self::PLATFORM_SMART_TV;
} elseif (stripos($this->_agent, 'linux') !== false) {
$this->_platform = self::PLATFORM_LINUX;
} else if (stripos($this->_agent, 'Nokia') !== false) {
$this->_platform = self::PLATFORM_NOKIA;
} else if (stripos($this->_agent, 'BlackBerry') !== false) {
$this->_platform = self::PLATFORM_BLACKBERRY;
} elseif (stripos($this->_agent, 'FreeBSD') !== false) {
$this->_platform = self::PLATFORM_FREEBSD;
} elseif (stripos($this->_agent, 'OpenBSD') !== false) {
$this->_platform = self::PLATFORM_OPENBSD;
} elseif (stripos($this->_agent, 'NetBSD') !== false) {
$this->_platform = self::PLATFORM_NETBSD;
} elseif (stripos($this->_agent, 'OpenSolaris') !== false) {
$this->_platform = self::PLATFORM_OPENSOLARIS;
} elseif (stripos($this->_agent, 'SunOS') !== false) {
$this->_platform = self::PLATFORM_SUNOS;
} elseif (stripos($this->_agent, 'OS\/2') !== false) {
$this->_platform = self::PLATFORM_OS2;
} elseif (stripos($this->_agent, 'BeOS') !== false) {
$this->_platform = self::PLATFORM_BEOS;
} elseif (stripos($this->_agent, 'win') !== false) {
$this->_platform = self::PLATFORM_WINDOWS;
} elseif (stripos($this->_agent, 'Playstation') !== false) {
$this->_platform = self::PLATFORM_PLAYSTATION;
} elseif (stripos($this->_agent, 'Roku') !== false) {
$this->_platform = self::PLATFORM_ROKU;
} elseif (stripos($this->_agent, 'iOS') !== false) {
$this->_platform = self::PLATFORM_IPHONE . '/' . self::PLATFORM_IPAD;
} elseif (stripos($this->_agent, 'tvOS') !== false) {
$this->_platform = self::PLATFORM_APPLE_TV;
} elseif (stripos($this->_agent, 'curl') !== false) {
$this->_platform = self::PLATFORM_TERMINAL;
} elseif (stripos($this->_agent, 'CrOS') !== false) {
$this->_platform = self::PLATFORM_CHROME_OS;
} elseif (stripos($this->_agent, 'okhttp') !== false) {
$this->_platform = self::PLATFORM_JAVA_ANDROID;
} elseif (stripos($this->_agent, 'PostmanRuntime') !== false) {
$this->_platform = self::PLATFORM_POSTMAN;
} elseif (stripos($this->_agent, 'Iframely') !== false) {
$this->_platform = self::PLATFORM_I_FRAME;
}
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Helper;
use Magento\Framework\App\Config\ScopeConfigInterface;
/**
* Class Data
* @package KiwiCommerce\AdminActivity\Helper
*/
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* @var string
*/
const ACTIVITY_ENABLE = 'admin_activity/general/enable';
/**
* @var string
*/
const LOGIN_ACTIVITY_ENABLE = 'admin_activity/general/login_activity';
/**
* @var string
*/
const PAGE_VISIT_ENABLE = 'admin_activity/general/page_visit';
/**
* @var string
*/
const CLEAR_LOG_DAYS = 'admin_activity/general/clearlog';
/**
* @var string
*/
const MODULE_ORDER = 'admin_activity/module/order';
/**
* @var string
*/
const MODULE_PRODUCT = 'admin_activity/module/product';
/**
* @var string
*/
const MODULE_CATEGORY = 'admin_activity/module/category';
/**
* @var string
*/
const MODULE_CUSTOMER = 'admin_activity/module/customer';
/**
* @var string
*/
const MODULE_PROMOTION = 'admin_activity/module/promotion';
/**
* @var string
*/
const MODULE_EMAIL = 'admin_activity/module/email';
/**
* @var string
*/
const MODULE_PAGE = 'admin_activity/module/page';
/**
* @var string
*/
const MODULE_BLOCK = 'admin_activity/module/block';
/**
* @var string
*/
const MODULE_WIDGET = 'admin_activity/module/widget';
/**
* @var string
*/
const MODULE_THEME = 'admin_activity/module/theme';
/**
* @var string
*/
const MODULE_SYSTEM_CONFIG = 'admin_activity/module/system_config';
/**
* @var string
*/
const MODULE_ATTRIBUTE = 'admin_activity/module/attibute';
/**
* @var string
*/
const MODULE_ADMIN_USER = 'admin_activity/module/admin_user';
/**
* @var string
*/
const MODULE_SEO = 'admin_activity/module/seo';
/**
* @var \KiwiCommerce\AdminActivity\Model\Config
*/
public $config;
/**
* @var array
*/
public static $wildcardModels = [
\Magento\Framework\App\Config\Value\Interceptor::class
];
/**
* Data constructor.
* @param \Magento\Framework\App\Helper\Context $context
* @param \KiwiCommerce\AdminActivity\Model\Config $config
*/
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\KiwiCommerce\AdminActivity\Model\Config $config
) {
$this->config = $config;
parent::__construct($context);
}
/**
* Check and return status of module
* @return bool
*/
public function isEnable()
{
$status = $this->scopeConfig->isSetFlag(self::ACTIVITY_ENABLE, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
if ($status == '1') {
return true;
}
return false;
}
/**
* Check and return status for login activity
* @return bool
*/
public function isLoginEnable()
{
$status = $this->scopeConfig->isSetFlag(self::ACTIVITY_ENABLE, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
$loginStatus = $this->scopeConfig
->isSetFlag(self::LOGIN_ACTIVITY_ENABLE, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
if ($status == '1' && $loginStatus == '1') {
return true;
}
return false;
}
/**
* Check and return status for page visit history
* @return bool
*/
public function isPageVisitEnable()
{
$status = $this->scopeConfig->isSetFlag(self::ACTIVITY_ENABLE, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
$pageVisitStatus = $this->scopeConfig
->isSetFlag(self::PAGE_VISIT_ENABLE, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
if ($status == '1' && $pageVisitStatus == '1') {
return true;
}
return false;
}
/**
* Get value of system config from path
* @param $path
* @return bool
*/
public function getConfigValue($path)
{
$moduleValue = $this->scopeConfig->getValue(
constant(
'self::'
. $path
),
ScopeConfigInterface::SCOPE_TYPE_DEFAULT
);
if ($moduleValue) {
return $moduleValue;
}
return false;
}
/**
* Get translated label by action name
* @param string $action
* @return string
*/
public function getActionTranslatedLabel($action)
{
return $this->config->getActionLabel($action);
}
/**
* Get all actions
* @return array
*/
public function getAllActions()
{
return $this->config->getActions();
}
/**
* Get activity module name
* @return bool
*/
public function getActivityModuleName($module)
{
return $this->config->getActivityModuleName($module);
}
/**
* Get module name is valid or not
* @param $model
* @return bool
*/
public static function isWildCardModel($model)
{
$model = is_string($model)?$model:get_class($model);
if (in_array($model, self::$wildcardModels)) {
return true;
}
return false;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Helper;
/**
* Class Data
* @package KiwiCommerce\AdminActivity\Helper
*/
class TrackField extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* @var string;
*/
const SYSTEM_METHOD = 'getSystemConfigFieldData';
/**
* @var string;
*/
const THEME_METHOD = 'getThemeConfigFieldData';
/**
* @var string;
*/
const PRODUCT_METHOD = 'getProductFieldData';
/**
* @var \KiwiCommerce\AdminActivity\Model\Activity\SystemConfig
*/
public $systemConfig;
/**
* @var \KiwiCommerce\AdminActivity\Model\Activity\ThemeConfig
*/
public $themeConfig;
/**
* TrackField constructor.
* @param \Magento\Framework\App\Helper\Context $context
* @param \KiwiCommerce\AdminActivity\Model\Activity\SystemConfig $systemConfig
* @param \KiwiCommerce\AdminActivity\Model\Activity\ThemeConfig $themeConfig
*/
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\KiwiCommerce\AdminActivity\Model\Activity\SystemConfig $systemConfig,
\KiwiCommerce\AdminActivity\Model\Activity\ThemeConfig $themeConfig
) {
parent::__construct($context);
$this->systemConfig = $systemConfig;
$this->themeConfig = $themeConfig;
}
/**
* Get product module fields
* @return array
*/
public function getProductFieldData()
{
return [
'form_key',
'current_product_id',
'force_reindex_eav_required',
'news_from_date_is_formated',
'can_save_custom_options',
'save_rewrites_history',
'is_custom_option_changed',
'special_from_date_is_formated',
'custom_design_from_is_formated',
'affect_product_custom_options',
'product_has_weight',
'check_if_is_new',
'entity_id',
'updated_at',
'edit_mode',
'gift_message_available',
'use_config_gift_message_available',
'created_at',
'is_changed_websites'
];
}
/**
* Get category module fields
* @return array
*/
public function getCategoryFieldData()
{
return [
'form_key',
'updated_at',
'created_at'
];
}
/**
* Get customer module fields
* @return array
*/
public function getCustomerFieldData()
{
return [
'id',
'attribute_set_id',
'entity_id',
'form_key',
'check_if_is_new',
'dob_is_formated',
'updated_at',
'created_at',
'rp_token',
'rp_token_created_at',
'is_customer_save_transaction',
'store_id',
'customer_id',
'parent_id',
'force_process'
];
}
/**
* Get customer group modules fields
* @return array
*/
public function getCustomerGroupFieldData()
{
return [
'customer_group_id',
'check_if_is_new'
];
}
/**
* Get catalog promotion modules fields
* @return array
*/
public function getCatalogPromotionFieldData()
{
return [
'rule_id',
'form_key',
'check_if_is_new'
];
}
/**
* Get cart promotion modules fields
* @return array
*/
public function getCartPromotionFieldData()
{
return [
'is_rss',
'form_key',
'check_if_is_new',
'rule_id'
];
}
/**
* Get email modules fields
* @return array
*/
public function getEmailFieldData()
{
return [
'template_id',
'check_if_is_new',
'form_key',
'template_actual',
'code',
'subject',
'sender_name',
'sender_email',
'text',
'key'
];
}
/**
* Get page modules fields
* @return array
*/
public function getPageFieldData()
{
return [
'page_id',
'form_key',
'check_if_is_new',
'store_code',
'first_store_id'
];
}
/**
* Get block modules fields
* @return array
*/
public function getBlockFieldData()
{
return [
'block_id',
'form_key',
'check_if_is_new',
'store_code'
];
}
/**
* Get widget modules fields
* @return array
*/
public function getWidgetFieldData()
{
return [
'check_if_is_new',
'instance_id'
];
}
/**
* Get theme configuration field data
* @return array
*/
public function getThemeConfigFieldData()
{
return [
'back',
'scope',
'scope_id',
'form_key',
'head_includes'
];
}
/**
* Get theme schedule field data
* @return array
*/
public function getThemeScheduleFieldData()
{
return [
'store_id',
'check_if_is_new'
];
}
/**
* Get system config field data
* @return array
*/
public function getSystemConfigFieldData()
{
return [
'check_if_is_new',
];
}
/**
* Get attribute modules fields
* @return array
*/
public function getAttributeFieldData()
{
return [
'form_key',
'check_if_is_new',
'attribute_id',
'id',
'modulePrefix'
];
}
/**
* Get attribute set modules fields
* @return array
*/
public function getAttributeSetFieldData()
{
return [
'entity_type_id',
'check_if_is_new',
'id'
];
}
/**
* Get attribute set modules fields
* @return array
*/
public function getReviewRatingFieldData()
{
return [
'rating_id',
'check_if_is_new'
];
}
/**
* Get review modules fields
* @return array
*/
public function getReviewFieldData()
{
return [
'form_key',
'entity_id',
'check_if_is_new',
'review_id',
'entity_pk_value'
];
}
/**
* Get admin user modules fields
* @return array
*/
public function getAdminUserFieldData()
{
return [
'form_key',
'password_confirmation',
'current_password',
'limit',
'user_roles',
'check_if_is_new',
'user_id'
];
}
/**
* Get admin user role modules fields
* @return array
*/
public function getAdminUserRoleFieldData()
{
return [
'name',
'check_if_is_new',
'role_id'
];
}
/**
* Get order modules fields
* @return array
*/
public function getOrderFieldData()
{
return [
'check_if_is_new',
'created_at',
'updated_at',
'entity_id',
'id',
'protect_code'
];
}
/**
* Get tax rule modules fields
* @return array
*/
public function getTaxRuleFieldData()
{
return [
'form_key',
'check_if_is_new',
'id',
'tax_calculation_rule_id'
];
}
/**
* Get tax rate modules fields
* @return array
*/
public function getTaxRateFieldData()
{
return [
'form_key',
'check_if_is_new',
'tax_calculation_rate_id'
];
}
/**
* Get url rewrites modules fields
* @return array
*/
public function getUrlRewriteFieldData()
{
return [
'url_rewrite_id',
'store_id'
];
}
/**
* Get search term modules fields
* @return array
*/
public function getSearchTermFieldData()
{
return [
'form_key',
'check_if_is_new',
'query_id'
];
}
/**
* Get search synonyms modules fields
* @return array
*/
public function getSearchSynonymsFieldData()
{
return [];
}
/**
* Get sitemap modules fields
* @return array
*/
public function getSitemapFieldData()
{
return [
'form_key',
'check_if_is_new',
'store_id',
'sitemap_id'
];
}
/**
* Get checkout agreement modules fields
* @return array
*/
public function getCheckoutAgreementFieldData()
{
return [
'form_key',
'check_if_is_new',
'id'
];
}
/**
* Get Order satus modules fields
* @return array
*/
public function getOrderStatusFieldData()
{
return [
'form_key',
'check_if_is_new'
];
}
/**
* Get System store modules fields
* @return array
*/
public function getSystemStoreFieldData()
{
return [
'check_if_is_new'
];
}
/**
* Get integration modules fields
* @return array
*/
public function getIntegrationFieldData()
{
return [
'form_key',
'current_password',
'integration_id',
'check_if_is_new',
'consumer_id',
'consumer_key',
'consumer_secret',
'identity_link_url'
];
}
/**
* Get Edit fields which will skip
* @return array
*/
public function getSkipEditFieldData()
{
return [
'region_code',
'default_shipping',
'default_billing',
'is_default_billing',
'is_default_shipping',
'url_key_create_redirect',
'attribute_set_id',
'rp_token',
'rp_token_created_at',
'Page',
'role_id',
'field',
'group_id',
'scope',
'id',
'path',
'config_id',
'use_config_gift_message_available',
'new_variations_attribute_set_id',
'can_save_configurable_attributes',
'type_has_options',
'type_has_required_options',
'special_to_date_is_formated',
'custom_design_to_is_formated',
'news_to_date_is_formated',
'is_changed_categories',
'url_key_create_redirect',
'save_rewrites_history',
'custom_design_from_is_formated',
'custom_design_to_is_formated',
'image_label',
'small_image_label',
'thumbnail_label'
];
}
/**
* Get all fields by method
* @param $method
* @return array
*/
public function getFields($method)
{
$fieldArray = [];
if (!empty($method) && method_exists($this, $method)) {
$fieldArray = $this->{$method}();
}
return $fieldArray;
}
/**
* Get added activity data
* @param $model
* @param $method
* @return array
*/
public function getAddData($model, $method)
{
$skipFieldArray = $this->getFields($method);
$logData = [];
if (!empty($model->getData()) && is_array($model->getData())) {
$logData = $this->getWildCardData($model, $method);
foreach ($model->getData() as $key => $value) {
if ($this->validateValue($model, $key, $value, $skipFieldArray) || empty($value)) {
continue;
}
$logData[$key] = [
'old_value' => '',
'new_value' => $value
];
}
}
return $logData;
}
/**
* Get edited activity data
* @param $model
* @param $method
* @return array
*/
public function getEditData($model, $method)
{
$fieldArray = $this->getFields($method);
$skipFieldArray = $this->getSkipEditFieldData();
if (\KiwiCommerce\AdminActivity\Helper\Data::isWildCardModel($model)) {
if ($method==self::SYSTEM_METHOD) {
return $this->systemConfig->getEditData($model, $fieldArray);
} elseif ($method==self::THEME_METHOD) {
return $this->themeConfig->getEditData($model, $fieldArray);
}
}
$logData = [];
if (!empty($model->getData()) && is_array($model->getData())) {
$logData = $this->getWildCardData($model, $method);
$skipFieldArray = array_merge($skipFieldArray, $fieldArray);
foreach ($model->getData() as $key => $value) {
if ($this->validateValue($model, $key, $value, $skipFieldArray)) {
continue;
}
$newData = !empty($value) ? $value : '';
$oldData = !empty($model->getOrigData($key)) ? $model->getOrigData($key) : '';
if (!empty($newData) || !empty($oldData)) {
if ($newData != $oldData) {
$logData[$key] = [
'old_value' => $oldData,
'new_value' => $newData
];
}
}
}
}
return $logData;
}
/**
* Get deleted activity data
* @param $model
* @param $method
* @return array
*/
public function getDeleteData($model, $method)
{
$fieldArray = $this->getFields($method);
$logData = [];
if (!empty($model->getOrigData()) && is_array($model->getOrigData())) {
$logData = $this->getWildCardData($model, $method);
foreach ($model->getOrigData() as $key => $value) {
if ($this->validateValue($model, $key, $value, $fieldArray) || empty($value)) {
continue;
}
$logData[$key] = [
'old_value' => $value,
'new_value' => ''
];
}
}
return $logData;
}
/**
* Get wild data
* @param $model
* @param $method
* @return array
*/
public function getWildCardData($model, $method)
{
$logData = [];
if ($method == self::PRODUCT_METHOD) {
$newQty = $model->getData('stock_data');
$oldQty = $model->getOrigData('quantity_and_stock_status');
if (isset($newQty['qty']) && isset($oldQty['qty']) && $newQty['qty'] != $oldQty['qty']) {
$logData['qty'] = [
'old_value' => $oldQty['qty'],
'new_value' => $newQty['qty']
];
}
}
return $logData;
}
/**
* Skip this fields while tracking activity log
* @param $model
* @param $key
* @param $value
* @param $skipFields
* @return bool
*/
public function validateValue($model, $key, $value, $skipFields)
{
if (is_array($value) || is_object($value) || is_array($model->getOrigData($key))
|| in_array($key, $skipFields)) {
return true;
}
return false;
}
}
<!---
To maintain an effective issue workflow and make sure issues will be solved in a timely manner we kindly ask reporters to follow some guidelines.
Please have a look at our guidelines article before adding a new issue https://kiwicommerce.co.uk/docs/issue_reporting_guidelines/
-->
### Title
<!--
A title should contain a clear, brief explanation of the issue, making emphasis on the most important points.
-->
### Preconditions
<!---
Add everything that would help developer set up the same environment as you have.
For example Magento version, tag, HEAD, PHP & MySQL version, etc.
-->
1.
2.
### Steps to reproduce
<!---
It is important to provide a set of clear steps to reproduce this bug.
If relevant please include code samples
-->
1.
2.
### Expected result
<!--- Tell us what should happen -->
1. [Screenshots, logs or description]
### Actual result
<!--- Tell us what happens instead -->
1. [Screenshots, logs or description]
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customise this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Logger;
/**
* Class Handler
* @package KiwiCommerce\AdminActivity\Logger
*/
class Handler extends \Magento\Framework\Logger\Handler\Base
{
/**
* Logging level
* @var int
*/
public $loggerType = \KiwiCommerce\AdminActivity\Logger\Logger::INFO;
/**
* File name
* @var string
*/
public $fileName = '/var/log/adminactivity.log';
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customise this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Logger;
/**
* Class Logger
* @package KiwiCommerce\AdminActivity\Logger
*/
class Logger extends \Monolog\Logger
{
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
use \Magento\Framework\Model\AbstractModel;
/**
* Class Activity
* @package KiwiCommerce\Activity\Model
*/
class Activity extends AbstractModel
{
/**
* @var string
*/
const ACTIVITY_ID = 'entity_id'; // We define the id field name
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
$this->_init('KiwiCommerce\AdminActivity\Model\ResourceModel\Activity');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\Activity;
use \Magento\Framework\Model\AbstractModel;
/**
* Class Status
* @package KiwiCommerce\AdminActivity\Model\Activity
*/
class Status extends AbstractModel
{
/**
* @var Int
*/
const ACTIVITY_NONE = 0;
/**
* @var Int
*/
const ACTIVITY_REVERTABLE = 1;
/**
* @var Int
*/
const ACTIVITY_REVERT_SUCCESS = 2;
/**
* @var Int
*/
const ACTIVITY_FAIL = 3;
/**
* @var \KiwiCommerce\AdminActivity\Model\ActivityFactory
*/
public $activityFactory;
/**
* Status constructor.
* @param \KiwiCommerce\AdminActivity\Model\ActivityFactory $activityFactory
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\ActivityFactory $activityFactory
) {
$this->activityFactory = $activityFactory;
}
/**
* Set success revert status
* @param $activityId
* @return void
*/
public function markSuccess($activityId)
{
$activityModel = $this->activityFactory->create()->load($activityId);
$activityModel->setIsRevertable(self::ACTIVITY_REVERT_SUCCESS);
$activityModel->save();
}
/**
* Set fail revert status
* @param $activityId
* @return void
*/
public function markFail($activityId)
{
$activityModel = $this->activityFactory->create()->load($activityId);
$activityModel->setIsRevertable(self::ACTIVITY_FAIL);
$activityModel->save();
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\Activity;
/**
* Class SystemConfig
* @package KiwiCommerce\AdminActivity\Model\Activity
*/
class SystemConfig implements \KiwiCommerce\AdminActivity\Api\Activity\ModelInterface
{
/**
* @var \Magento\Framework\DataObject
*/
public $dataObject;
/**
* @var \Magento\Framework\App\Config\ValueFactory
*/
public $valueFactory;
/**
* @var \Magento\Framework\App\Config\Storage\WriterInterface
*/
public $configWriter;
/**
* SystemConfig constructor.
* @param \Magento\Framework\DataObject $dataObject
* @param \Magento\Framework\App\Config\ValueFactory $valueFactory
* @param \Magento\Framework\App\Config\Storage\WriterInterface $configWriter
*/
public function __construct(
\Magento\Framework\DataObject $dataObject,
\Magento\Framework\App\Config\ValueFactory $valueFactory,
\Magento\Framework\App\Config\Storage\WriterInterface $configWriter
) {
$this->dataObject = $dataObject;
$this->valueFactory = $valueFactory;
$this->configWriter = $configWriter;
}
/**
* Get config path
* @param $model
* @return string
*/
public function getPath($model)
{
if ($model->getData('path')) {
return current(
explode(
'/',
$model->getData('path')
)
);
}
return '';
}
/**
* Get old activity data of system config module
* @param $model
* @return mixed
*/
public function getOldData($model)
{
$path = $this->getPath($model);
$systemData = $this->valueFactory->create()->getCollection()->addFieldToFilter('path', ['like'=> $path.'/%']);
$data = [];
foreach ($systemData->getData() as $config) {
$splittedPath = explode('/', $config['path']);
if (count($splittedPath) === 2) {
[$group, $field] = explode('/', $config['path']);
} else {
[$path, $group, $field] = explode('/', $config['path']);
}
$data[$group]['fields'][$field]['value'] = $config['value'];
}
return $this->dataObject->setData($data);
}
/**
* Get edit activity data of system config module
* @param $model
* @return mixed
*/
public function getEditData($model, $fieldArray)
{
$logData = [];
$path = $this->getPath($model);
$result = $this->collectAdditionalData($model->getOrigData(), $model->getGroups());
$model->setConfig('System Configuration');
$model->setId($path);
if (!empty($result) && is_array($result)) {
foreach ($result as $group => $fields) {
if (!empty($fields['fields'])) {
foreach ($fields['fields'] as $field => $value) {
if (empty($value)) {
continue;
}
$fieldPath = implode('/', [
$path, $group, $field
]);
$logData[$fieldPath] = [
'old_value' => $value['old_value'],
'new_value' => $value['new_value']
];
}
}
}
}
return $logData;
}
/**
* Get revert activity data of system config module
* @param $logData
* @param $scopeId
* @return bool
*/
public function revertData($logData, $scopeId)
{
if (!empty($logData)) {
foreach ($logData as $log) {
$this->configWriter->save(
$log->getFieldName(),
$log->getOldValue(),
\Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
$scopeId
);
}
}
return true;
}
/**
* Set additional data
* @param $oldData
* @param $newData
* @return array
*/
public function collectAdditionalData($oldData, $newData)
{
$result = [];
if (!empty($oldData) && is_array($oldData)) {
foreach ($oldData as $key => $value) {
if (isset($newData[$key])) {
if (is_array($value)) {
$result[$key] = $this->collectAdditionalData($value, $newData[$key]);
} elseif (!is_array($newData[$key]) && (string)$value != (string)$newData[$key]) {
$result['new_value'] = (string)$newData[$key];
$result['old_value'] = $value;
}
}
}
}
return $result;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\Activity;
/**
* Class ThemeConfig
* @package KiwiCommerce\AdminActivity\Model\Activity
*/
class ThemeConfig implements \KiwiCommerce\AdminActivity\Api\Activity\ModelInterface
{
/**
* @var \Magento\Framework\DataObject
*/
public $dataObject;
/**
* @var \Magento\Framework\App\Config\ValueFactory
*/
public $valueFactory;
/**
* @var \Magento\Framework\App\Config\Storage\WriterInterface
*/
public $configWriter;
/**
* Request
* @var \Magento\Framework\App\RequestInterface
*/
public $request;
/**
* ThemeConfig constructor.
* @param \Magento\Framework\DataObject $dataObject
* @param \Magento\Framework\App\Config\ValueFactory $valueFactory
* @param \Magento\Framework\App\RequestInterface $request
* @param \Magento\Framework\App\Config\Storage\WriterInterface $configWriter
*/
public function __construct(
\Magento\Framework\DataObject $dataObject,
\Magento\Framework\App\Config\ValueFactory $valueFactory,
\Magento\Framework\App\RequestInterface $request,
\Magento\Framework\App\Config\Storage\WriterInterface $configWriter
) {
$this->dataObject = $dataObject;
$this->valueFactory = $valueFactory;
$this->request = $request;
$this->configWriter = $configWriter;
}
/**
* Get config path of theme configuration
* @param $model
* @return string
*/
public function getPath($model)
{
if ($model->getData('path')) {
return current(
explode(
'/',
$model->getData('path')
)
);
}
return '';
}
/**
* Get old activity data of theme configuration
* @param $model
* @return mixed
*/
public function getOldData($model)
{
$path = $this->getPath($model);
$systemData = $this->valueFactory->create()->getCollection()
->addFieldToFilter('path', ['like'=> $path.'/%']);
$data = [];
foreach ($systemData->getData() as $config) {
$path = str_replace('design_', '', str_replace('/', '_', $config['path']));
$data[$path] = $config['value'];
}
return $data;
}
/**
* Get edit activity data of theme configuration
* @param $model
* @return mixed
*/
public function getEditData($model, $fieldArray)
{
$path = 'stores/scope_id/'.$model->getScopeId();
$oldData = $this->getOldData($model);
$newData = $this->request->getPostValue();
$result = $this->collectAdditionalData($oldData, $newData, $fieldArray);
$model->setConfig('Theme Configuration');
$model->setId($path);
return $result;
}
/**
* Get revert activity data of theme configuration
* @param $logData
* @param $scopeId
* @return bool
*/
public function revertData($logData, $scopeId, $scope)
{
if (!empty($logData)) {
foreach ($logData as $log) {
$this->configWriter->save(
$log->getFieldName(),
$log->getOldValue(),
$scope,
$scopeId
);
}
}
return true;
}
/**
* Set additional data
* @param $oldData
* @param $newData
* @return array
*/
public function collectAdditionalData($oldData, $newData, $fieldArray)
{
$logData = [];
foreach ($newData as $key => $value) {
if (in_array($key, $fieldArray)) {
continue;
}
$newValue = !empty($value) ? $value : '';
$oldValue = !empty($oldData[$key]) ? $oldData[$key] : '';
if ($newValue != $oldValue) {
$key = 'design/'.preg_replace('/_/', '/', $key, 1);
$logData[$key] = [
'old_value' => $oldValue,
'new_value'=> $newValue
];
}
}
return $logData;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
use \Magento\Framework\Model\AbstractModel;
/**
* Class Activity
* @package KiwiCommerce\Activity\Model
*/
class ActivityLog extends AbstractModel
{
/**
* @var string
*/
const ACTIVITYLOG_ID = 'entity_id'; // We define the id fieldname
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
$this->_init('KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLog');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
use \Magento\Framework\Model\AbstractModel;
/**
* Class ActivityLogDetail
* @package KiwiCommerce\AdminActivity\Model
*/
class ActivityLogDetail extends AbstractModel
{
/**
* @var string
*/
const ACTIVITYLOGDETAIL_ID = 'entity_id'; // We define the id fieldname
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
$this->_init('KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLogDetail');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
use KiwiCommerce\AdminActivity\Model\Activity\SystemConfig;
/**
* Class ActivityRepository
* @package KiwiCommerce\AdminActivity\Model
*/
class ActivityRepository implements \KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface
{
/**
* @var string
*/
const THEME_MODULE = 'Themes';
/**
* @var string
*/
const QTY_FIELD = 'qty';
/**
* @var ActivityFactory
*/
public $activityFactory;
/**
* @var ResourceModel\Activity\CollectionFactory
*/
public $collectionFactory;
/**
* @var ActivityLogDetailFactory
*/
public $activityLogDetailFactory;
/**
* @var ActivityLogFactory
*/
public $activityLogFactory;
/**
* @var ResourceModel\ActivityLog\CollectionFactory
*/
public $LogCollectionFactory;
/**
* @var SystemConfig
*/
public $systemConfig;
/**
* @var Activity\ThemeConfig
*/
public $themeConfig;
/**
* Object Manager instance
* @var \Magento\Framework\ObjectManagerInterface
*/
public $objectManager;
/**
* ActivityRepository constructor.
* @param ActivityFactory $activityFactory
* @param ResourceModel\Activity\CollectionFactory $collectionFactory
* @param ActivityLogDetailFactory $activityLogDetailFactory
* @param ActivityLogFactory $activityLogFactory
* @param ResourceModel\ActivityLog\CollectionFactory $LogCollectionFactory
* @param SystemConfig $systemConfig
* @param Activity\ThemeConfig $themeConfig
* @param \Magento\Framework\ObjectManagerInterface $objectManager
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\ActivityFactory $activityFactory,
\KiwiCommerce\AdminActivity\Model\ResourceModel\Activity\CollectionFactory $collectionFactory,
\KiwiCommerce\AdminActivity\Model\ActivityLogDetailFactory $activityLogDetailFactory,
\KiwiCommerce\AdminActivity\Model\ActivityLogFactory $activityLogFactory,
\KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLog\CollectionFactory $LogCollectionFactory,
\KiwiCommerce\AdminActivity\Model\Activity\SystemConfig $systemConfig,
\KiwiCommerce\AdminActivity\Model\Activity\ThemeConfig $themeConfig,
\Magento\Framework\ObjectManagerInterface $objectManager
) {
$this->activityFactory = $activityFactory;
$this->collectionFactory = $collectionFactory;
$this->activityLogDetailFactory = $activityLogDetailFactory;
$this->activityLogFactory = $activityLogFactory;
$this->LogCollectionFactory = $LogCollectionFactory;
$this->systemConfig = $systemConfig;
$this->themeConfig = $themeConfig;
$this->objectManager = $objectManager;
}
/**
* Array of protected fields
* @return array
*/
public function protectedFields()
{
return [
'password'
];
}
/**
* Get all admin activity data
* @return ResourceModel\Activity\Collection
*/
public function getList()
{
$collection = $this->collectionFactory->create();
return $collection;
}
/**
* Get all admin activity data before date
* @param $endDate
* @return $this
*/
public function getListBeforeDate($endDate)
{
$collection = $this->collectionFactory->create()
->addFieldToSelect('entity_id')
->addFieldToFilter('created_at', ["lteq" => $endDate]);
return $collection;
}
/**
* Remove activity log entry
* @param $activityId
* @return void
*/
public function deleteActivityById($activityId)
{
$model = $this->activityFactory->create();
$model->load($activityId);
$model->delete();
}
/**
* Get all admin activity detail by activity id
* @param $activityId
* @return $this
*/
public function getActivityDetail($activityId)
{
$data = $this->activityLogDetailFactory->create()
->load($activityId, 'activity_id');
return $data;
}
/**
* Get all admin activity log by activity id
* @param $activityId
* @return $this
*/
public function getActivityLog($activityId)
{
$collection = $this->LogCollectionFactory->create()
->addFieldToFilter('activity_id', ["eq" => $activityId]);
return $collection;
}
/**
* Get method name
* @param $field
* @return string
*/
public function getMethodName($field)
{
return implode(
'',
array_map(
"ucfirst",
array_map(
"strtolower",
explode('_', $field)
)
)
);
}
/**
* Revert last changes made in module
* @param $activity
* @return bool
*/
public function revertActivity($activity)
{
$logData = $this->getActivityLog($activity->getId());
$detailModel = $this->getActivityDetail($activity->getId());
if (\KiwiCommerce\AdminActivity\Helper\Data::isWildCardModel($detailModel->getModelClass())) {
if ($activity->getModule()==self::THEME_MODULE) {
return $this->themeConfig->revertData($logData, $activity->getStoreId(), $activity->getScope());
}
return $this->systemConfig->revertData($logData, $activity->getStoreId());
}
$model = $this->objectManager->get($detailModel->getModelClass())
->setStoreId($activity->getStoreId())
->setScope($activity->getScope())
->load($detailModel->getItemId());
if ($model->getId()) {
foreach ($logData as $log) {
if ($this->isFieldProtected($log->getFieldName())) {
continue;
}
if ($log->getFieldName()==self::QTY_FIELD) {
$model-> setStockData(['qty' => $log->getOldValue()]);
}
$method = 'set'.$this->getMethodName($log->getFieldName());
$model->{$method}($log->getOldValue());
}
$model->setStoreId($activity->getStoreId());
$model->save();
return true;
}
return false;
}
/**
* Get old data for system config module
* @param $model
* @return bool
*/
public function getOldData($model)
{
if (\KiwiCommerce\AdminActivity\Helper\Data::isWildCardModel($model)) {
return $this->systemConfig->getOldData($model);
}
$data = $this->objectManager->get(get_class($model))->load($model->getId());
if ($data) {
return $data;
}
return false;
}
/**
* Get admin activity by id
* @param $activityId
* @return $this
*/
public function getActivityById($activityId)
{
return $this->activityFactory->create()->load($activityId);
}
/**
* Check field is protected or not
* @param $fieldName
* @return bool
*/
public function isFieldProtected($fieldName)
{
$fieldArray = $this->protectedFields();
if (in_array($fieldName, $fieldArray)) {
return true;
}
return false;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
/**
* Class Config
* @package KiwiCommerce\AdminActivity\Model
*/
class Config
{
/**
* Merged adminactivity.xml config
* @var array
*/
public $_xmlConfig;
/**
* Translated and sorted labels
* @var array
*/
public $_labels = [];
/**
* Config constructor.
* @param Config\Data $dataStorage
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\Config\Data $dataStorage
) {
$this->_xmlConfig = $dataStorage->get('config');
}
/**
* Get all action labels translated and sorted ASC
* @return array
*/
public function getActions()
{
if (!$this->_labels && isset($this->_xmlConfig['actions'])) {
foreach ($this->_xmlConfig['actions'] as $id => $label) {
$this->_labels[$id] = __($label);
}
asort($this->_labels);
}
return $this->_labels;
}
/**
* List of all full actions
* @return array
*/
public function getControllerActions()
{
$actions = [];
foreach ($this->_xmlConfig as $module => $config) {
if(isset($config['actions'])) {
$actions = array_merge($actions, array_keys($config['actions']));
}
}
return $actions;
}
/**
* Get logging action translated label
* @param string $action
* @return \Magento\Framework\Phrase|string
*/
public function getActionLabel($action)
{
if (isset($this->_xmlConfig['actions'])
&& array_key_exists(
$action,
$this->_xmlConfig['actions']
)
) {
return __($this->_xmlConfig['actions'][$action]);
}
return $action;
}
/**
* Get event by action
* @param $action
* @return bool
*/
public function getEventByAction($action)
{
foreach ($this->_xmlConfig as $module => $config) {
if (isset($config['actions']) && array_key_exists($action, $config['actions'])) {
return $config['actions'][$action];
}
}
return false;
}
/**
* Return Model class name
* @param $module
* @return string
*/
public function getEventModel($module)
{
if (!array_key_exists($module, $this->_xmlConfig)) {
return false;
}
return $this->_xmlConfig[$module]['model'];
}
/**
* Return model label name
* @param $module
* @return bool
*/
public function getActivityModuleName($module)
{
if (!array_key_exists($module, $this->_xmlConfig)) {
return false;
}
return $this->_xmlConfig[$module]['label'];
}
/**
* Return model class name
* @param $module
* @return string
*/
public function getTrackFieldModel($module)
{
if (!array_key_exists($module, $this->_xmlConfig)) {
return false;
}
return $this->_xmlConfig[$module]['config']['trackfield'];
}
/**
* Return module constant
* @param $module
* @return bool
*/
public function getActivityModuleConstant($module)
{
if (!array_key_exists($module, $this->_xmlConfig)) {
return false;
}
return $this->_xmlConfig[$module]['config']['configpath'];
}
/**
* Return module edit url
* @param $module
* @return bool
*/
public function getActivityModuleEditUrl($module)
{
if (!array_key_exists($module, $this->_xmlConfig)) {
return false;
}
return $this->_xmlConfig[$module]['config']['editurl'];
}
/**
* Return module item name
* @param $module
* @return bool
*/
public function getActivityModuleItemField($module)
{
if (!array_key_exists($module, $this->_xmlConfig)) {
return false;
}
return $this->_xmlConfig[$module]['config']['itemfield'];
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\Config;
/**
* Class Converter
* @package KiwiCommerce\AdminActivity\Model\Config
*/
class Converter implements \Magento\Framework\Config\ConverterInterface
{
/**
* Convert actions in array from Xpath object
* @param \DOMDocument $source
* @return array
*/
public function convert($source)
{
$result = ['config' => []];
$xpath = new \DOMXPath($source);
$result['config']['actions'] = $this->_getActions($xpath);
$modules = $xpath->query('/config/modules/module');
foreach ($modules as $module) {
$moduleId = $module->attributes->getNamedItem('name')->nodeValue;
$result['config'][$moduleId] = $this->_processModule($module, $moduleId);
}
return $result;
}
/**
* Retrieves actions array from Xpath object
* @param \DOMXPath $xpath
* @return array
*/
public function _getActions($xpath)
{
$result = [];
$actions = $xpath->query('/config/actions/action');
/** @var \DOMNode $action */
foreach ($actions as $action) {
$actionId = $action->attributes->getNamedItem('id')->nodeValue;
foreach ($action->childNodes as $label) {
if ($label->nodeName == 'label') {
$result[$actionId] = $label->nodeValue;
}
}
}
return $result;
}
/**
* Convert module node to array
*
* @param $module
* @param $moduleId
* @return array
*/
public function _processModule($module, $moduleId)
{
$result = [];
foreach ($module->childNodes as $params) {
switch ($params->nodeName) {
case 'label':
$result['label'] = $params->nodeValue;
break;
case 'models':
$result['model'] = $this->_processModels($params);
break;
case 'events':
$result['actions'] = $this->_processEvents($params, $moduleId);
break;
case 'config':
$result['config'] = $this->_processConfig($params);
break;
}
}
return $result;
}
/**
* @param $events
* @return array
*/
public function _processModels($events)
{
$result = [];
foreach ($events->childNodes as $event) {
if ($event->nodeName == 'class') {
$result[] = $event->attributes->getNamedItem('name')->nodeValue;
}
}
return $result;
}
/**
* Convert events node to array
*
* @param $events
* @param $moduleId
* @return array
*/
public function _processEvents($events, $moduleId)
{
$result = [];
foreach ($events->childNodes as $event) {
if ($event->nodeName == 'event') {
$result[$event->attributes->getNamedItem('controller_action')->nodeValue] = [
'action' => $event->attributes->getNamedItem('action_alias')->nodeValue,
'module' => $moduleId
];
$postDispatch = $event->attributes->getNamedItem('post_dispatch');
if ($postDispatch !== null) {
$result[$event->attributes->getNamedItem('controller_action')->nodeValue]['post_dispatch'] = $postDispatch->nodeValue;
}
}
}
return $result;
}
/**
* Converts config to array
*
* @param $configs
* @return array
*/
public function _processConfig($configs)
{
$result = [];
foreach ($configs->childNodes as $config) {
switch ($config->nodeName) {
case 'trackfield':
$result['trackfield'] = $config->attributes->getNamedItem('method')->nodeValue;
break;
case 'configpath':
$result['configpath'] = $config->attributes->getNamedItem('constant')->nodeValue;
break;
case 'editurl':
$result['editurl'] = $config->attributes->getNamedItem('url')->nodeValue;
break;
case 'itemfield':
$result['itemfield'] = $config->attributes->getNamedItem('field')->nodeValue;
break;
}
}
return $result;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\Config;
/**
* Class Data
* @package KiwiCommerce\AdminActivity\Model\Config
*/
class Data extends \Magento\Framework\Config\Data
{
}
\ No newline at end of file
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\Config;
use Magento\Framework\Config\SchemaLocatorInterface;
use Magento\Framework\Module\Dir;
/**
* Class SchemaLocator
* @package KiwiCommerce\AdminActivity\Model\Config
*/
class SchemaLocator implements SchemaLocatorInterface
{
/**
* XML schema for config file.
*/
const CONFIG_FILE_SCHEMA = 'adminactivity.xsd';
/**
* Path to corresponding XSD file with validation rules for merged config
* @var string
*/
public $schema = null;
/**
* Path to corresponding XSD file with validation rules for separate config files
* @var string
*/
public $perFileSchema = null;
/**
* SchemaLocator constructor.
* @param Dir\Reader $moduleReader
*/
public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
{
$configDir = $moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'KiwiCommerce_AdminActivity');
$this->schema = $configDir . DIRECTORY_SEPARATOR . self::CONFIG_FILE_SCHEMA;
$this->perFileSchema = $configDir . DIRECTORY_SEPARATOR . self::CONFIG_FILE_SCHEMA;
}
/**
* Get schema
* @return string
*/
public function getSchema()
{
return $this->schema;
}
/**
* Get file schema
* @return string
*/
public function getPerFileSchema()
{
return $this->perFileSchema;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
use \KiwiCommerce\AdminActivity\Helper\TrackField as Helper;
use \Magento\Framework\App\Request\Http;
use \Magento\Framework\UrlInterface;
/**
* Class Handler
* @package KiwiCommerce\AdminActivity\Model
*/
class Handler
{
/**
* @var Helper
*/
public $helper;
/**
* @var \Magento\Framework\HTTP\Header
*/
public $header;
/**
* @var \Magento\Framework\App\Request\Http
*/
public $request;
/**
* @var UrlInterface
*/
public $urlInterface;
/**
* @var ActivityLogFactory
*/
public $activityLogFactory;
/**
* Handler constructor.
* @param Helper $helper
* @param \Magento\Framework\HTTP\Header $header
* @param Http $request
* @param UrlInterface $urlInterface
* @param ActivityLogFactory $activityLogFactory
*/
public function __construct(
Helper $helper,
\Magento\Framework\HTTP\Header $header,
Http $request,
UrlInterface $urlInterface,
\KiwiCommerce\AdminActivity\Model\ActivityLogFactory $activityLogFactory
) {
$this->helper = $helper;
$this->header = $header;
$this->request = $request;
$this->urlInterface = $urlInterface;
$this->activityLogFactory = $activityLogFactory;
}
/**
* Set log data
* @param $logs
* @return mixed
*/
public function __initLog($logs)
{
if (!empty($logs)) {
foreach ($logs as $field => $value) {
$log = $this->activityLogFactory->create()->setData($value);
$log->setFieldName($field);
$logs[$field] = $log;
}
}
return $logs;
}
/**
* Get add activity log data
* @param $model
* @param $method
* @return mixed
*/
public function modelAdd($model, $method)
{
return $this->__initLog(
$this->helper->getAddData($model, $method)
);
}
/**
* Get edit activity log data
* @param $model
* @param $method
* @return mixed
*/
public function modelEdit($model, $method)
{
return $this->__initLog(
$this->helper->getEditData($model, $method)
);
}
/**
* Get delete activity log data
* @param $model
* @param $method
* @return mixed
*/
public function modelDelete($model, $method)
{
return $this->__initLog(
$this->helper->getDeleteData($model, $method)
);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\Handler;
/**
* Class PostDispatch
* @package KiwiCommerce\AdminActivity\Model\Handler
*/
class PostDispatch
{
/**
* Request
*
* @var \Magento\Framework\App\RequestInterface
*/
public $request;
/**
* Response
*
* @var \Magento\Framework\App\ResponseInterface
*/
public $response;
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
*/
public $productRepository;
/**
* @var \Magento\Backend\Model\Session
*/
public $session;
/**
* PostDispatch constructor.
*
* @param \Magento\Framework\App\RequestInterface $request
* @param \Magento\Framework\App\ResponseInterface $response
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @param \Magento\Backend\Model\Session $session
*/
public function __construct(
\Magento\Framework\App\RequestInterface $request,
\Magento\Framework\App\ResponseInterface $response,
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Backend\Model\Session $session
) {
$this->request = $request;
$this->response = $response;
$this->productRepository = $productRepository;
$this->session = $session;
}
/**
* @param $model
* @return array
*/
public function getProductAttributes($model)
{
$logData = [];
$status = $this->request->getParam('status', '');
if($status != '') {
$logData['status'] = [
'old_value' => $model->getStatus(),
'new_value' => $status
];
}
$attributes = $this->request->getParam('attributes', []);
if(!empty($attributes)) {
foreach ($attributes as $attribute => $value) {
$logData[$attribute] = [
'old_value' => $model->getData($attribute),
'new_value' => $value
];
}
}
$inventories = $this->request->getParam('inventory', []);
if(!empty($inventories)) {
foreach ($inventories as $field => $value) {
$logData[$field] = [
'old_value' => $model->getData($field),
'new_value' => $value
];
}
}
$websiteIds = $this->request->getParam('remove_website', []);
if ($websiteIds) {
$logData['remove_website_ids'] = [
'old_value' => '[]',
'new_value' => implode(', ', $websiteIds)
];
}
$websiteIds = $this->request->getParam('add_website', []);
if ($websiteIds) {
$logData['add_website_ids'] = [
'old_value' => '[]',
'new_value' => implode(', ', $websiteIds)
];
}
return $logData;
}
/**
* Set product update activity log
* @param $config
* @param $processor
*/
public function productUpdate($config, $processor)
{
$activity = $processor->_initLog();
$activity->setIsRevertable(1);
$selected = $this->request->getParam('selected');
if(empty($selected)) {
$selected = $this->session->getProductIds();
}
if(!empty($selected)) {
foreach ($selected as $id) {
$model = $this->productRepository->getById($id);
$log = clone $activity;
$log->setItemName($model->getData($processor->config->getActivityModuleItemField($config['module'])));
$log->setItemUrl($processor->getEditUrl($model));
$logData = $processor->handler->__initLog($this->getProductAttributes($model));
$logDetail = $processor->_initActivityDetail($model);
$processor->activityLogs[] = [
\KiwiCommerce\AdminActivity\Model\Activity::class => $log,
\KiwiCommerce\AdminActivity\Model\ActivityLog::class => $logData,
\KiwiCommerce\AdminActivity\Model\ActivityLogDetail::class => $logDetail
];
}
}
}
}
\ No newline at end of file
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
use \Magento\Framework\Model\AbstractModel;
/**
* Class Login
* @package KiwiCommerce\Activity\Model
*/
class Login extends AbstractModel
{
/**
* @var string
*/
const LOGIN_ACTIVITY_ID = 'entity_id'; // We define the id field name
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
$this->_init('KiwiCommerce\AdminActivity\Model\ResourceModel\Login');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
/**
* Class LoginRepository
* @package KiwiCommerce\AdminActivity\Model
*/
class LoginRepository implements \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface
{
/**
* @var boolean
*/
const LOGIN_SUCCESS = 1;
/**
* @var boolean
*/
const LOGIN_FAILED = 0;
/**
* @var LoginFactory
*/
public $loginFactory;
/**
* @var Processor
*/
public $processor;
/**
* @var object Magento\User\Model\User
*/
public $user;
/**
* @var ResourceModel\Activity\CollectionFactory
*/
public $collectionFactory;
/**
* LoginRepository constructor.
* @param LoginFactory $loginFactory
* @param ResourceModel\Login\CollectionFactory $collectionFactory
* @param Processor $processor
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\LoginFactory $loginFactory,
\KiwiCommerce\AdminActivity\Model\ResourceModel\Login\CollectionFactory $collectionFactory,
\KiwiCommerce\AdminActivity\Model\Processor $processor
) {
$this->loginFactory = $loginFactory;
$this->collectionFactory = $collectionFactory;
$this->processor = $processor;
}
/**
* Get login user
* @return string
*/
public function getUser()
{
return $this->user;
}
/**
* Set login user
* @param $user
* @return $this
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Set login activity data
* @return mixed
*/
public function _initLoginActivity()
{
$login = $this->loginFactory->create();
$user = $this->getUser();
if($user != null && $user instanceof \Magento\User\Model\User) {
$login->setUsername($user->getUsername());
$login->setName(ucwords($user->getName()));
}
$login->setRemoteIp($this->processor->remoteAddress->getRemoteAddress());
$login->setForwardedIp($this->processor->request->getServer('HTTP_X_FORWARDED_FOR'));
$login->setUserAgent($this->processor->handler->header->getHttpUserAgent());
return $login;
}
/**
* Set login data
* @param $status
* @param $type
* @param string $remark
* @return boolean
*/
public function addLog($status, $type, $remark = '')
{
$login = $this->_initLoginActivity();
$login->setStatus($status);
$login->setType($type);
$login->setRemarks($remark);
$login->save();
return true;
}
/**
* Track login success log
* @return void
*/
public function addSuccessLog()
{
$this->addLog(self::LOGIN_SUCCESS, 'Login');
}
/**
* Track login fail log
* @param string $remark
*/
public function addFailedLog($remark = '')
{
$this->addLog(self::LOGIN_FAILED, 'Login', $remark);
}
/**
* Track logout success log
* @return void
*/
public function addLogoutLog()
{
$this->addLog(self::LOGIN_SUCCESS, 'Logout');
}
/**
* Get all admin activity data before date
* @param $endDate
* @return $this
*/
public function getListBeforeDate($endDate)
{
$collection = $this->collectionFactory->create()
->addFieldToSelect('entity_id')
->addFieldToFilter('created_at', ["lteq" => $endDate]);
return $collection;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model;
use KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
/**
* Class Processor
* @package KiwiCommerce\AdminActivity\Model
*/
class Processor
{
/**
* @var string
*/
const PRIMARY_FIELD = 'id';
/**
* @var array
*/
const SKIP_MODULE_ACTIONS = [
'mui_index_render',
'adminactivity_activity_index',
'adminactivity_activity_log',
'adminactivity_activity_revert'
];
/**
* @var string
*/
const SKIP_MODULE = [
'mui'
];
/**
* @var string
*/
const SALES_ORDER = 'sales_order';
/**
* @var string
*/
const SAVE_ACTION = 'save';
/**
* @var string
*/
const EDIT_ACTION = 'edit';
/**
* @var Config
*/
public $config;
/**
* current event config
* @var array
*/
public $eventConfig;
/**
* Last action name
* @var string
*/
public $actionName = '';
/**
* Last full action name
* @var string
*/
public $lastAction = '';
/**
* Initialization full action name
* @var string
*/
public $initAction = '';
/**
* Temporary storage for model changes before saving to table.
* @var array
*/
public $activityLogs = [];
/**
* @var \Magento\Backend\Model\Auth\Session
*/
public $authSession;
/**
* @var Handler
*/
public $handler;
/**
* @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress
*/
public $remoteAddress;
/**
* @var ActivityFactory
*/
public $activityFactory;
/**
* @var ActivityLogDetailFactory
*/
public $activityDetailFactory;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
public $storeManager;
/**
* @var \Magento\Framework\Stdlib\DateTime\DateTime
*/
public $dateTime;
/**
* @var ActivityRepositoryInterface
*/
public $activityRepository;
/**
* @var Helper
*/
public $helper;
/**
* @var \Magento\Framework\Message\ManagerInterface
*/
public $messageManager;
/**
* Request
*
* @var \Magento\Framework\App\RequestInterface
*/
public $request;
/**
* Http request
* @var \Magento\Framework\App\Request\Http
*/
public $httpRequest;
/**
* @var Activity\Status
*/
public $status;
/**
* @var Handler\PostDispatch
*/
public $postDispatch;
/**
* @var array
*/
public $urlParams = [
'{{module}}',
'{{controller}}',
'{{action}}',
'{{field}}',
'{{id}}'
];
/**
* Processor constructor.
* @param Config $config
* @param \Magento\Backend\Model\Auth\Session $authSession
* @param Handler $handler
* @param \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress
* @param ActivityFactory $activityFactory
* @param ActivityLogDetailFactory $activityDetailFactory
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
* @param ActivityRepositoryInterface $activityRepository
* @param Helper $helper
* @param \Magento\Framework\Message\ManagerInterface $messageManager
* @param \Magento\Framework\App\RequestInterface $request
* @param Activity\Status $status
* @param Handler\PostDispatch $postDispatch
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\Config $config,
\Magento\Backend\Model\Auth\Session $authSession,
\KiwiCommerce\AdminActivity\Model\Handler $handler,
\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress,
\KiwiCommerce\AdminActivity\Model\ActivityFactory $activityFactory,
\KiwiCommerce\AdminActivity\Model\ActivityLogDetailFactory $activityDetailFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
ActivityRepositoryInterface $activityRepository,
Helper $helper,
\Magento\Framework\Message\ManagerInterface $messageManager,
\Magento\Framework\App\RequestInterface $request,
\Magento\Framework\App\Request\Http $httpRequest,
\KiwiCommerce\AdminActivity\Model\Activity\Status $status,
\KiwiCommerce\AdminActivity\Model\Handler\PostDispatch $postDispatch
) {
$this->config = $config;
$this->authSession = $authSession;
$this->handler = $handler;
$this->remoteAddress = $remoteAddress;
$this->activityFactory = $activityFactory;
$this->activityDetailFactory = $activityDetailFactory;
$this->storeManager = $storeManager;
$this->dateTime = $dateTime;
$this->activityRepository = $activityRepository;
$this->helper = $helper;
$this->messageManager = $messageManager;
$this->request = $request;
$this->httpRequest = $httpRequest;
$this->status = $status;
$this->postDispatch = $postDispatch;
}
/**
* Get and set event config from full action name
* @param $fullActionName
* @param $actionName
* @return $this
*/
public function init($fullActionName, $actionName)
{
$this->actionName = $actionName;
if (!$this->initAction) {
$this->initAction = $fullActionName;
}
$this->lastAction = $fullActionName;
$this->eventConfig = $this->config->getEventByAction($fullActionName);
if (isset($this->eventConfig['post_dispatch'])) {
$this->_callPostDispatchCallback();
}
return $this;
}
/**
* Check Model class
* @param $model
* @return bool
*/
public function validate($model)
{
if (\KiwiCommerce\AdminActivity\Helper\Data::isWildCardModel($model)) {
if (!empty($this->activityLogs)) {
return false;
}
}
if ($this->eventConfig) {
$usedModel = (array)$this->config->getEventModel($this->eventConfig['module']);
$pathConst = $this->config->getActivityModuleConstant($this->eventConfig['module']);
if (!empty($this->helper->getConfigValue($pathConst))) {
foreach ($usedModel as $module) {
if ($model instanceof $module) {
return true;
}
}
}
}
return false;
}
/**
* Return method name of TrackField class
* @return string
*/
public function getMethod()
{
return $this->config->getTrackFieldModel($this->eventConfig['module']);
}
/**
* Get item url
* @param $model
* @return string
*/
public function getEditUrl($model)
{
$id = $model->getId();
if ($this->eventConfig['module']==self::SALES_ORDER && (!empty($model->getOrderId())
|| !empty($model->getParentId()))) {
$id = ($model->getOrderId()) ? $model->getOrderId() : $model->getParentId();
}
return str_replace(
$this->urlParams,
[
$this->handler->request->getModuleName(),
$this->handler->request->getControllerName(),
$this->handler->request->getActionName(),
self::PRIMARY_FIELD,
$id
],
$this->config->getActivityModuleEditUrl($this->eventConfig['module'])
);
}
/**
* Set activity data after item added
* @param $model
* @return $this|bool
*/
public function modelAddAfter($model)
{
if ($this->validate($model)) {
$logData = $this->handler->modelAdd($model, $this->getMethod());
if (!empty($logData)) {
$activity = $this->_initActivity($model);
$activity->setIsRevertable(0);
$this->addLog($activity, $logData, $model);
}
}
return $this;
}
/**
* Set activity data after item edited
* @param $model
* @return $this|bool
*/
public function modelEditAfter($model)
{
$label = ($this->eventConfig['action'] == self::SAVE_ACTION) ? self::EDIT_ACTION : $this->eventConfig['action'];
if ($this->validate($model)) {
$logData = $this->handler->modelEdit($model, $this->getMethod());
if (!empty($logData)) {
$activity = $this->_initActivity($model);
$activity->setActionType($label);
$activity->setIsRevertable(1);
$this->addLog($activity, $logData, $model);
}
}
return $this;
}
/**
* Set activity data after item deleted
* @param $model
* @return $this|bool
*/
public function modelDeleteAfter($model)
{
if ($this->validate($model)) {
$logData = $this->handler->modelDelete($model, $this->getMethod());
if (!empty($logData)) {
$activity = $this->_initActivity($model);
$activity->setIsRevertable(0);
$activity->setItemUrl('');
$this->addLog($activity, $logData, $model);
}
}
return $this;
}
/**
* Set activity details data
* @param $activity
* @param $logData
* @param $model
* @return void
*/
public function addLog($activity, $logData, $model)
{
$logDetail = $this->_initActivityDetail($model);
$this->activityLogs[] = [
\KiwiCommerce\AdminActivity\Model\Activity::class => $activity,
\KiwiCommerce\AdminActivity\Model\ActivityLog::class => $logData,
\KiwiCommerce\AdminActivity\Model\ActivityLogDetail::class => $logDetail
];
}
/**
* Insert activity log data in database
* @return bool
*/
public function saveLogs()
{
try {
if (!empty($this->activityLogs)) {
foreach ($this->activityLogs as $model) {
$activity = $model[\KiwiCommerce\AdminActivity\Model\Activity::class];
$activity->save();
$activityId = $activity->getId();
if (isset($model[\KiwiCommerce\AdminActivity\Model\ActivityLog::class])) {
$logData = $model[\KiwiCommerce\AdminActivity\Model\ActivityLog::class];
if ($logData) {
foreach ($logData as $log) {
$log->setActivityId($activityId);
$log->save();
}
}
}
if (isset($model[\KiwiCommerce\AdminActivity\Model\ActivityLogDetail::class])) {
$detail = $model[\KiwiCommerce\AdminActivity\Model\ActivityLogDetail::class];
$detail->setActivityId($activityId);
$detail->save();
}
}
$this->activityLogs = [];
}
} catch (\Exception $e) {
return false;
}
return true;
}
/**
* Set activity details data
* @return Activity
*/
public function _initLog()
{
$activity = $this->activityFactory->create();
if ($this->authSession->isLoggedIn()) {
$activity->setUsername($this->authSession->getUser()->getUsername());
$activity->setName($this->authSession->getUser()->getName());
$activity->setAdminId($this->authSession->getUser()->getId());
}
$activity->setScope($this->getScope());
$activity->setRemoteIp($this->remoteAddress->getRemoteAddress());
$activity->setForwardedIp($this->httpRequest->getServer('HTTP_X_FORWARDED_FOR'));
$activity->setUserAgent($this->handler->header->getHttpUserAgent());
$activity->setModule($this->helper->getActivityModuleName($this->eventConfig['module']));
$activity->setActionType($this->eventConfig['action']);
$activity->setFullaction($this->escapeString($this->lastAction, '/'));
$activity->setStoreId(0);
return $activity;
}
/**
* Set activity scope, name and item url
* @param $model
* @return bool|Activity
*/
public function _initActivity($model)
{
if (!$this->authSession->isLoggedIn()) {
return false;
}
$activity = $this->_initLog();
$activity->setStoreId($this->getStoreId($model));
$activity->setItemName($model->getData($this->config
->getActivityModuleItemField($this->eventConfig['module'])));
$activity->setItemUrl($this->getEditUrl($model));
return $activity;
}
/**
* Set activity details
* @param $model
* @return mixed
*/
public function _initActivityDetail($model)
{
$activity = $this->activityDetailFactory->create()->setData([
'model_class' => get_class($model),
'item_id' => $model->getId(),
'status' => 'success',
'response' => ''
]);
return $activity;
}
/**
* Check post dispatch method to track log for mass actions
* @return bool
*/
public function _callPostDispatchCallback()
{
$handler = $this->postDispatch;
if (isset($this->eventConfig['post_dispatch'])) {
$callback = $this->eventConfig['post_dispatch'];
if ($handler && $callback && method_exists($handler, $callback)) {
$handler->{$callback}($this->eventConfig, $this);
return true;
}
}
return false;
}
/**
* Get store identifier
* @param $model
* @return int
*/
public function getStoreId($model)
{
$data = $model->getData();
if (isset($data['scope_id'])) {
return $model->getScopeId();
}
if (isset($data['store_id'])) {
return $model->getStoreId();
}
return $this->storeManager->getStore()->getId();
}
/**
* Get scope name
* @return string
*/
public function getScope()
{
if ($this->request->getParam('store') == 1 || $this->request->getParam('scope') == 'stores') {
$scope = 'stores';
} elseif ($this->request->getParam('website') == 1) {
$scope = 'website';
} else {
$scope = 'default';
}
return $scope;
}
/**
* Revert last changes made in module
* @param $activityId
* @return array
*/
public function revertActivity($activityId)
{
$result = [
'error' => true,
'message' => __('Something went wrong, please try again')
];
try {
$activityModel = $this->activityFactory->create()->load($activityId);
if ($activityModel->getIsRevertable() === '0') {
$result['message'] = __('Activity data has already been reverted');
} else {
if ($activityModel->getId() && $this->activityRepository->revertActivity($activityModel)) {
$activityModel->setRevertBy($this->authSession->getUser()->getUsername());
$activityModel->setUpdatedAt($this->dateTime->gmtDate());
$activityModel->save();
$result['error'] = false;
$this->status->markSuccess($activityId);
$this->messageManager->addSuccessMessage(__('Activity data has been reverted successfully'));
}
}
} catch (\Exception $e) {
$result['message'] = $e->getMessage();
$this->status->markFail($activityId);
}
return $result;
}
/**
* Convert module and action name to user readable format
* @param $name
* @param string $delimiter
* @return string
*/
public function escapeString($name, $delimiter = ' ')
{
return implode(
$delimiter,
array_map(
'ucfirst',
array_filter(
explode(
'_',
strtolower($name)
)
)
)
);
}
/**
* Check action to skip
* @param $module
* @param $fullAction
* @return bool
*/
public function isValidAction($module, $fullAction)
{
if (in_array(strtolower($fullAction), self::SKIP_MODULE_ACTIONS)
|| in_array(strtolower($module), self::SKIP_MODULE)) {
return false;
}
return true;
}
/**
* Track page visit history
* @param $module
* @return void
*/
public function addPageVisitLog($module)
{
if (in_array(strtolower($this->lastAction), $this->config->getControllerActions())) {
return false;
}
if ($this->helper->isPageVisitEnable()
&& $this->isValidAction($module, $this->lastAction)) {
$activity = $this->_initLog();
$activity->setActionType('view');
$activity->setIsRevertable(0);
if (!$activity->getModule()) {
$activity->setModule($this->escapeString($module));
}
$activity->save();
}
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel;
use \Magento\Framework\Model\ResourceModel\Db\AbstractDb;
/**
* Class Activity
* @package KiwiCommerce\AdminActivity\Model\ResourceModel
*/
class Activity extends AbstractDb
{
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
// Table Name and Primary Key column
$this->_init('kiwicommerce_activity', 'entity_id');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel\Activity;
use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
/**
* Class Collection
* @package KiwiCommerce\AdminActivity\Model\ResourceModel\Activity
*/
class Collection extends AbstractCollection
{
/**
* Define resource model
* @return void
*/
public function _construct()
{
$this->_init(
'KiwiCommerce\AdminActivity\Model\Activity',
'KiwiCommerce\AdminActivity\Model\ResourceModel\Activity'
);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel;
use \Magento\Framework\Model\ResourceModel\Db\AbstractDb;
/**
* Class ActivityLog
* @package KiwiCommerce\AdminActivity\Model\ResourceModel
*/
class ActivityLog extends AbstractDb
{
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
// Table Name and Primary Key column
$this->_init('kiwicommerce_activity_log', 'entity_id');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLog;
use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
/**
* Class Collection
* @package KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLog
*/
class Collection extends AbstractCollection
{
/**
* Define resource model
* @return void
*/
public function _construct()
{
$this->_init(
'KiwiCommerce\AdminActivity\Model\ActivityLog',
'KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLog'
);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel;
use \Magento\Framework\Model\ResourceModel\Db\AbstractDb;
/**
* Class ActivityLogDetail
* @package KiwiCommerce\AdminActivity\Model\ResourceModel
*/
class ActivityLogDetail extends AbstractDb
{
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
// Table Name and Primary Key column
$this->_init('kiwicommerce_activity_detail', 'entity_id');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLogDetail;
use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
/**
* Class Collection
* @package KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLogDetail
*/
class Collection extends AbstractCollection
{
/**
* Define resource model
* @return void
*/
public function _construct()
{
$this->_init(
'KiwiCommerce\AdminActivity\Model\ActivityLogDetail',
'KiwiCommerce\AdminActivity\Model\ResourceModel\ActivityLogDetail'
);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel;
use \Magento\Framework\Model\ResourceModel\Db\AbstractDb;
/**
* Class Login
* @package KiwiCommerce\AdminActivity\Model\ResourceModel
*/
class Login extends AbstractDb
{
/**
* Initialize resource model
* @return void
*/
public function _construct()
{
// Table Name and Primary Key column
$this->_init('kiwicommerce_login_activity', 'entity_id');
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Model\ResourceModel\Login;
use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
/**
* Class Collection
* @package KiwiCommerce\AdminActivity\Model\ResourceModel\Login
*/
class Collection extends AbstractCollection
{
/**
* Define resource model
* @return void
*/
public function _construct()
{
$this->_init(
'KiwiCommerce\AdminActivity\Model\Login',
'KiwiCommerce\AdminActivity\Model\ResourceModel\Login'
);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Observer;
use Magento\Framework\Event\ObserverInterface;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
use \KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface;
/**
* Class DeleteAfter
* @package KiwiCommerce\AdminActivity\Observer
*/
class DeleteAfter implements ObserverInterface
{
/**
* @var string
*/
const SYSTEM_CONFIG = 'adminhtml_system_config_save';
/**
* @var \KiwiCommerce\AdminActivity\Model\Processor
*/
private $processor;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Data
*/
public $helper;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* DeleteAfter constructor.
* @param \KiwiCommerce\AdminActivity\Model\Processor $processor
* @param Helper $helper
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\Processor $processor,
\KiwiCommerce\AdminActivity\Helper\Data $helper,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->processor = $processor;
$this->helper = $helper;
$this->benchmark = $benchmark;
}
/**
* Delete after
* @param \Magento\Framework\Event\Observer $observer
* @return \Magento\Framework\Event\Observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->benchmark->start(__METHOD__);
if (!$this->helper->isEnable()) {
return $observer;
}
$object = $observer->getEvent()->getObject();
if ($this->processor->validate($object) && ($this->processor->initAction==self::SYSTEM_CONFIG)) {
$this->processor->modelEditAfter($object);
}
$this->processor->modelDeleteAfter($object);
$this->benchmark->end(__METHOD__);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Observer;
use Magento\Framework\Event\ObserverInterface;
/**
* Class LoadAfter
* @package KiwiCommerce\AdminActivity\Observer
*/
class LoadAfter implements ObserverInterface
{
/**
* @var \KiwiCommerce\AdminActivity\Model\Processor
*/
private $processor;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Data
*/
public $helper;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* LoadAfter constructor.
* @param \KiwiCommerce\AdminActivity\Model\Processor $processor
* @param \KiwiCommerce\AdminActivity\Helper\Data $helper
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\Processor $processor,
\KiwiCommerce\AdminActivity\Helper\Data $helper,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->processor = $processor;
$this->helper = $helper;
$this->benchmark = $benchmark;
}
/**
* Delete after
* @param \Magento\Framework\Event\Observer $observer
* @return \Magento\Framework\Event\Observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->benchmark->start(__METHOD__);
if (!$this->helper->isEnable()) {
return $observer;
}
$object = $observer->getEvent()->getObject();
$this->processor->modelLoadAfter($object);
$this->benchmark->end(__METHOD__);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Observer;
use Magento\Framework\Event\ObserverInterface;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
/**
* Class LoginFailed
* @package KiwiCommerce\AdminActivity\Observer
*/
class LoginFailed implements ObserverInterface
{
/**
* @var Helper
*/
public $helper;
/**
* @var \Magento\User\Model\User
*/
public $user;
/**
* @var \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface
*/
public $loginRepository;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* LoginFailed constructor.
* @param Helper $helper
* @param \Magento\User\Model\User $user
* @param \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
Helper $helper,
\Magento\User\Model\User $user,
\KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->helper = $helper;
$this->user = $user;
$this->loginRepository = $loginRepository;
$this->benchmark = $benchmark;
}
/**
* Login failed
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->benchmark->start(__METHOD__);
if (!$this->helper->isLoginEnable()) {
return $observer;
}
$user = null;
if ($observer->getUserName()) {
$user = $this->user->loadByUsername($observer->getUserName());
}
$this->loginRepository
->setUser($user)
->addFailedLog($observer->getException()->getMessage());
$this->benchmark->end(__METHOD__);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Observer;
use Magento\Framework\Event\ObserverInterface;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
/**
* Class LoginSuccess
* @package KiwiCommerce\AdminActivity\Observer
*/
class LoginSuccess implements ObserverInterface
{
/**
* @var Helper
*/
public $helper;
/**
* @var \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface
*/
public $loginRepository;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* LoginSuccess constructor.
* @param Helper $helper
* @param \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
Helper $helper,
\KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->helper = $helper;
$this->loginRepository = $loginRepository;
$this->benchmark = $benchmark;
}
/**
* Login success
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->benchmark->start(__METHOD__);
if (!$this->helper->isLoginEnable()) {
return $observer;
}
$this->loginRepository
->setUser($observer->getUser())
->addSuccessLog();
$this->benchmark->end(__METHOD__);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Observer;
use Magento\Framework\Event\ObserverInterface;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
/**
* Class PostDispatch
* @package KiwiCommerce\AdminActivity\Observer
*/
class PostDispatch implements ObserverInterface
{
/**
* @var \KiwiCommerce\AdminActivity\Model\Processor
*/
private $processor;
/**
* @var Helper
*/
public $helper;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* PostDispatch constructor.
* @param \KiwiCommerce\AdminActivity\Model\Processor $processor
* @param Helper $helper
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\Processor $processor,
Helper $helper,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->processor = $processor;
$this->helper = $helper;
$this->benchmark = $benchmark;
}
/**
* Post dispatch
* @param \Magento\Framework\Event\Observer $observer
* @return \Magento\Framework\Event\Observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->benchmark->start(__METHOD__);
if (!$this->helper->isEnable()) {
return $observer;
}
$this->processor->saveLogs();
$this->benchmark->end(__METHOD__);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Observer;
use Magento\Framework\Event\ObserverInterface;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
/**
* Class SaveAfter
* @package KiwiCommerce\AdminActivity\Observer
*/
class SaveAfter implements ObserverInterface
{
/**
* @var string
*/
const ACTION_MASSCANCEL = 'massCancel';
/**
* @var string
*/
const SYSTEM_CONFIG = 'adminhtml_system_config_save';
/**
* @var \KiwiCommerce\AdminActivity\Model\Processor
*/
private $processor;
/**
* @var Helper
*/
public $helper;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* SaveAfter constructor.
* @param \KiwiCommerce\AdminActivity\Model\Processor $processor
* @param Helper $helper
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\Processor $processor,
Helper $helper,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->processor = $processor;
$this->helper = $helper;
$this->benchmark = $benchmark;
}
/**
* Save after
* @param \Magento\Framework\Event\Observer $observer
* @return \Magento\Framework\Event\Observer|boolean
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->benchmark->start(__METHOD__);
if (!$this->helper->isEnable()) {
return $observer;
}
$object = $observer->getEvent()->getObject();
if ($object->getCheckIfIsNew()) {
if ($this->processor->initAction==self::SYSTEM_CONFIG) {
$this->processor->modelEditAfter($object);
}
$this->processor->modelAddAfter($object);
} else {
if ($this->processor->validate($object)) {
if ($this->processor->eventConfig['action']==self::ACTION_MASSCANCEL) {
$this->processor->modelDeleteAfter($object);
}
$this->processor->modelEditAfter($object);
}
}
$this->benchmark->end(__METHOD__);
return true;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Observer;
use Magento\Framework\Event\ObserverInterface;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
use KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface;
/**
* Class SaveBefore
* @package KiwiCommerce\AdminActivity\Observer
*/
class SaveBefore implements ObserverInterface
{
/**
* @var Helper
*/
public $helper;
/**
* @var \KiwiCommerce\AdminActivity\Model\Processor
*/
public $processor;
/**
* @var ActivityRepositoryInterface
*/
public $activityRepository;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* SaveBefore constructor.
* @param Helper $helper
* @param \KiwiCommerce\AdminActivity\Model\Processor $processor
* @param ActivityRepositoryInterface $activityRepository
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $banchmark
*/
public function __construct(
Helper $helper,
\KiwiCommerce\AdminActivity\Model\Processor $processor,
ActivityRepositoryInterface $activityRepository,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->helper = $helper;
$this->processor = $processor;
$this->activityRepository = $activityRepository;
$this->benchmark = $benchmark;
}
/**
* Save before
* @param \Magento\Framework\Event\Observer $observer
* @return \Magento\Framework\Event\Observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$this->benchmark->start(__METHOD__);
if (!$this->helper->isEnable()) {
return $observer;
}
$object = $observer->getEvent()->getObject();
if ($object->getId() == 0) {
$object->setCheckIfIsNew(true);
} else {
$object->setCheckIfIsNew(false);
if ($this->processor->validate($object)) {
$origData = $object->getOrigData();
if (!empty($origData)) {
return $observer;
}
$data = $this->activityRepository->getOldData($object);
foreach ($data->getData() as $key => $value) {
$object->setOrigData($key, $value);
}
}
}
$this->benchmark->end(__METHOD__);
return $observer;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Plugin\App;
/**
* Class Action
* @package KiwiCommerce\AdminActivity\Plugin\App
*/
class Action
{
/**
* @var \KiwiCommerce\AdminActivity\Model\Processor
*/
public $processor;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* Action constructor.
* @param \KiwiCommerce\AdminActivity\Model\Processor $processor
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
\KiwiCommerce\AdminActivity\Model\Processor $processor,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->processor = $processor;
$this->benchmark = $benchmark;
}
/**
* Get before dispatch data
* @param \Magento\Framework\Interception\InterceptorInterface $controller
* @return void
*/
public function beforeDispatch(\Magento\Framework\Interception\InterceptorInterface $controller)
{
$this->benchmark->start(__METHOD__);
$actionName = $controller->getRequest()->getActionName();
$fullActionName = $controller->getRequest()->getFullActionName();
$this->processor->init($fullActionName, $actionName);
$this->processor->addPageVisitLog($controller->getRequest()->getModuleName());
$this->benchmark->end(__METHOD__);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Plugin;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
/**
* Class Auth
* @package KiwiCommerce\AdminActivity\Plugin
*/
class Auth
{
/**
* @var Helper
*/
public $helper;
/**
* @var \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface
*/
public $loginRepository;
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* Auth constructor.
* @param Helper $helper
* @param \KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
Helper $helper,
\KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface $loginRepository,
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->helper = $helper;
$this->loginRepository = $loginRepository;
$this->benchmark = $benchmark;
}
/**
* Track admin logout activity
* @param \Magento\Backend\Model\Auth $auth
* @param callable $proceed
* @return mixed
*/
public function aroundLogout(\Magento\Backend\Model\Auth $auth, callable $proceed)
{
$this->benchmark->start(__METHOD__);
if ($this->helper->isLoginEnable()) {
$user = $auth->getAuthStorage()->getUser();
$this->loginRepository->setUser($user)->addLogoutLog();
}
$result = $proceed();
$this->benchmark->end(__METHOD__);
return $result;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Plugin\User;
/**
* Class Delete
* @package KiwiCommerce\AdminActivity\Plugin\User
*/
class Delete
{
/**
* @var \KiwiCommerce\AdminActivity\Helper\Benchmark
*/
public $benchmark;
/**
* Delete constructor.
* @param \KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
*/
public function __construct(
\KiwiCommerce\AdminActivity\Helper\Benchmark $benchmark
) {
$this->benchmark = $benchmark;
}
/**
* @param \Magento\User\Model\ResourceModel\User $user
* @param callable $proceed
* @param $object
* @return mixed
*/
public function aroundDelete(\Magento\User\Model\ResourceModel\User $user, callable $proceed, $object)
{
$this->benchmark->start(__METHOD__);
$object->load($object->getId());
$result = $proceed($object);
$object->afterDelete();
$this->benchmark->end(__METHOD__);
return $result;
}
}
# Magento 2 - Admin Activity by [KiwiCommerce](https://kiwicommerce.co.uk/)
- Easily track every admin activity like add, edit, delete, print, view, mass update etc.
- Failed attempts of admin login are recorded as well. You get access to the user’s login information and IP address.
- Track page visit history of admin.
- Track fields that have been changed from the backend.
- Allow administrator to revert the modification.
## **Installation**
1. Composer Installation
- Navigate to your Magento root folder<br />
`cd path_to_the_magento_root_directory`
- Then run the following command<br />
`composer require kiwicommerce/module-admin-activity`
- Make sure that composer finished the installation without errors.
2. Command Line Installation
- Backup your web directory and database.
- Download the latest Cron Scheduler installation package kiwicommerce-admin-activity-vvvv.zip [here](https://github.com/kiwicommerce/magento2-admin-activity/releases)
- Navigate to your Magento root folder<br />
`cd path_to_the_magento_root_directory`<br />
- Upload contents of the Admin Activity Log installation package to your Magento root directory
- Then run the following command<br />
`php bin/magento module:enable KiwiCommerce_AdminActivity`<br />
- After installing the extension, run the following command
```
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
php bin/magento cache:flush
```
- Log out from the backend and log in again.
Find More details on [KiwiCommerce](https://kiwicommerce.co.uk/extensions/magento2-admin-activity)
## Where will it appear in the Admin Panel
### Admin Activity Log
Go to **System > Admin Activity by KiwiCommerce > Admin Activity**. Here you can See the list of admin activity logs and page visit history.
<img src="https://kiwicommerce.co.uk/wp-content/uploads/2018/06/admin-activity-history.png"/><br/>
- Page Visit History
<img src="https://kiwicommerce.co.uk/wp-content/uploads/2018/06/page-visit-history.png"/><br/>
By clicking View in each admin activity log, you can see the slider with admin activity log details.
<img src="https://kiwicommerce.co.uk/wp-content/uploads/2018/05/activity-log-slider.png"/> <br/>
### Login Activity
Go to **System > Admin Activity by KiwiCommerce > Login Activity**. Here you can See the list of login activity logs.
<img src="https://kiwicommerce.co.uk/wp-content/uploads/2018/06/admin-activity-history.png"/><br/>
## Configuration
You need to follow this path. **System > Admin Activity by KiwiCommerce > Configuration**
- General configuration
<img src="https://kiwicommerce.co.uk/wp-content/uploads/2018/05/configuration-general-section.png" /> <br/>
- Allow Module Section
<img src="https://kiwicommerce.co.uk/wp-content/uploads/2018/05/configuration-allow-module-section.png" /> <br/>
## Need Additional Features?
Feel free to get in touch with us at https://kiwicommerce.co.uk/get-in-touch/
## Other KiwiCommerce Extensions
* [Magento 2 Cron Scheduler](https://kiwicommerce.co.uk/extensions/magento2-cron-scheduler/)
* [Magento 2 Login As Customer](https://kiwicommerce.co.uk/extensions/magento2-login-as-customer/)
* [Magento 2 Inventory Log](https://kiwicommerce.co.uk/extensions/magento2-inventory-log/)
* [Magento 2 Enhanced SMTP](https://kiwicommerce.co.uk/extensions/magento2-enhanced-smtp/)
* [Magento 2 Customer Password](https://github.com/kiwicommerce/magento2-customer-password/)
## Contribution
Well unfortunately there is no formal way to contribute, we would encourage you to feel free and contribute by:
- Creating bug reports, issues or feature requests on [Github](https://github.com/kiwicommerce/magento2-admin-activity/issues)
- Submitting pull requests for improvements.
We love answering questions or doubts simply ask us in issue section. We're looking forward to hearing from you!
- Follow us [@KiwiCommerce](https://twitter.com/KiwiCommerce)
- <a href="mailto:support@kiwicommerce.co.uk">Email Us</a>
- Have a look at our [documentation](https://kiwicommerce.co.uk/docs/admin-activity/)
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
/**
* Class InstallSchema
* @package KiwiCommerce\AdminActivity\Setup
*/
class InstallSchema implements InstallSchemaInterface
{
/**
* Installs DB schema for a module
* @param SchemaSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
/**
* Create table 'kiwicommerce_activity'
*/
$table = $installer->getConnection()->newTable(
$installer->getTable('kiwicommerce_activity')
)->addColumn(
'entity_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Primary key for the Table'
)->addColumn(
'username',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
40,
['nullable' => false, 'default' => ''],
'Store admin username'
)->addColumn(
'name',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
64,
['nullable' => false, 'default' => ''],
'Full name of admin'
)->addColumn(
'admin_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['nullable' => false, 'unsigned' => true, 'default' => 1],
'Store id of admin user'
)->addColumn(
'store_id',
\Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
5,
['nullable' => false, 'unsigned' => true, 'default' => 0],
'Insert store id'
)->addColumn(
'action_type',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
32,
['nullable' => false, 'default' => ''],
'Action type like New, Edit, View, Delete, Mass Delete, etc'
)->addColumn(
'remote_ip',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
32,
['nullable' => false, 'default' => ''],
'IP address of logged in admin user'
)->addColumn(
'user_agent',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'',
['nullable' => false, 'default' => ''],
'Store browser’s user agent'
)->addColumn(
'module',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
50,
['nullable' => false, 'default' => ''],
'Name of module in which action performed'
)->addColumn(
'item_name',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => ''],
'Name of item which is effected like product, user, order, etc'
)->addColumn(
'item_url',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => ''],
'Url of item if possible'
)->addColumn(
'is_revertable',
\Magento\Framework\DB\Ddl\Table::TYPE_BOOLEAN,
'',
['nullable' => true, 'default' => 0],
'0 = Not able revert activity, 1= Able to revert activity'
)->addColumn(
'revert_by',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
64,
['nullable' => false, 'default' => ''],
'Name of admin user who reverted the activity'
)->addColumn(
'created_at',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
'The date when the activity was created'
)->addColumn(
'updated_at',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE],
'The date when the activity was modified or reverted'
)->addIndex(
$installer->getIdxName('admin_user', ['user_id']),
['admin_id']
)->addIndex(
$installer->getIdxName('store', ['store_id']),
['store_id']
)->setComment(
'This is master table of admin activity extension'
);
$installer->getConnection()->createTable($table);
/**
* Create table 'kiwicommerce_activity_log'
*/
$table = $installer->getConnection()->newTable(
$installer->getTable('kiwicommerce_activity_log')
)->addColumn(
'entity_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Primary key for the Table'
)->addColumn(
'activity_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['nullable' => true, 'unsigned' => true, 'nullable' => false],
'Entity id of kiwicommerce_activity table'
)->addColumn(
'field_name',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
32,
['nullable' => false, 'default' => ''],
'Name of field which is effected'
)->addColumn(
'old_value',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'',
['nullable' => false, 'default' => ''],
'Old value of field'
)->addColumn(
'new_value',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'',
['nullable' => false, 'default' => ''],
'New value of field'
)->addIndex(
$installer->getIdxName('kiwicommerce_activity', ['entity_id']),
['activity_id']
)->addForeignKey(
$installer->getFkName(
'kiwicommerce_activity_log',
'activity_id',
'kiwicommerce_activity',
'entity_id'
),
'activity_id',
$installer->getTable('kiwicommerce_activity'),
'entity_id',
\Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
)->setComment(
'This is activity log table of admin activity extension'
);
$installer->getConnection()->createTable($table);
/**
* Create table 'kiwicommerce_activity_detail'
*/
$table = $installer->getConnection()->newTable(
$installer->getTable('kiwicommerce_activity_detail')
)->addColumn(
'entity_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Primary key for the Table'
)->addColumn(
'activity_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['unsigned' => true, 'nullable' => false],
'Entity id of kiwicommerce_activity table'
)->addColumn(
'model_class',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => ''],
'Name of field which is effected'
)->addColumn(
'item_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['nullable' => true],
'Old value of field'
)->addColumn(
'status',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
16,
['nullable' => false, 'default' => ''],
'Status of revert process'
)->addColumn(
'response',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'',
['nullable' => false, 'default' => ''],
'Error message faced during revert process'
)->addIndex(
$installer->getIdxName('kiwicommerce_activity', ['entity_id']),
['activity_id']
)->addForeignKey(
$installer->getFkName(
'kiwicommerce_activity_detail',
'activity_id',
'kiwicommerce_activity',
'entity_id'
),
'activity_id',
$installer->getTable('kiwicommerce_activity'),
'entity_id',
\Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
)->setComment(
'This is activity log details table of admin activity extension'
);
$installer->getConnection()->createTable($table);
// Table creation
$installer->endSetup();
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Setup;
use Magento\Framework\Setup\UninstallInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\App\Config\Storage\Writer;
use KiwiCommerce\AdminActivity\Helper\Data as ActivityHelper;
/**
* Class Uninstall
* @package KiwiCommerce\AdminActivity\Setup
*/
class Uninstall implements UninstallInterface
{
/**
* @var Writer
*/
public $scope;
/**
* Uninstall constructor.
* @param Writer $scopeWriter
*/
public function __construct(Writer $scopeWriter)
{
$this->scope = $scopeWriter;
}
/**
* Module uninstall code
* @param SchemaSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
$connection = $setup->getConnection();
$connection->dropTable($connection->getTableName('kiwicommerce_activity_log'));
$connection->dropTable($connection->getTableName('kiwicommerce_activity_detail'));
$connection->dropTable($connection->getTableName('kiwicommerce_login_activity'));
$connection->dropTable($connection->getTableName('kiwicommerce_activity'));
$setup->endSetup();
$scope = $this->scope;
$scope->delete(ActivityHelper::ACTIVITY_ENABLE);
$scope->delete(ActivityHelper::LOGIN_ACTIVITY_ENABLE);
$scope->delete(ActivityHelper::PAGE_VISIT_ENABLE);
$scope->delete(ActivityHelper::CLEAR_LOG_DAYS);
$scope->delete(ActivityHelper::MODULE_ORDER);
$scope->delete(ActivityHelper::MODULE_PRODUCT);
$scope->delete(ActivityHelper::MODULE_CATEGORY);
$scope->delete(ActivityHelper::MODULE_CUSTOMER);
$scope->delete(ActivityHelper::MODULE_PROMOTION);
$scope->delete(ActivityHelper::MODULE_EMAIL);
$scope->delete(ActivityHelper::MODULE_PAGE);
$scope->delete(ActivityHelper::MODULE_BLOCK);
$scope->delete(ActivityHelper::MODULE_WIDGET);
$scope->delete(ActivityHelper::MODULE_THEME);
$scope->delete(ActivityHelper::MODULE_SYSTEM_CONFIG);
$scope->delete(ActivityHelper::MODULE_ATTRIBUTE);
$scope->delete(ActivityHelper::MODULE_ADMIN_USER);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
/**
* Class UpgradeSchema
* @package KiwiCommerce\AdminActivity\Setup
*/
class UpgradeSchema implements UpgradeSchemaInterface
{
/**
* Upgrade DB schema for a module
* @param SchemaSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '0.0.2') < 0) {
$tableName = $setup->getTable('kiwicommerce_activity');
//TODO: Check if the table already exists
if ($setup->getConnection()->isTableExists($tableName) == true) {
$columns = [
'forwarded_ip' => [
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 32,
'nullable' => true,
'comment' => __('Real ip address if visitor used proxy'),
'after' => 'remote_ip'
]
];
$connection = $setup->getConnection();
foreach ($columns as $name => $definition) {
$connection->addColumn($tableName, $name, $definition);
}
}
}
if (version_compare($context->getVersion(), '0.1.2') < 0) {
$tableName = $setup->getTable('kiwicommerce_activity');
//TODO: Check if the table already exists
if ($setup->getConnection()->isTableExists($tableName) == true) {
$columns = [
'scope' => [
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 15,
'nullable' => true,
'comment' => __('Scope of activity'),
'after' => 'store_id'
]
];
$connection = $setup->getConnection();
foreach ($columns as $name => $definition) {
$connection->addColumn($tableName, $name, $definition);
}
}
}
if (version_compare($context->getVersion(), '0.1.3') < 0) {
/**
* Create table 'kiwicommerce_login_activity'
*/
$table = $setup->getConnection()->newTable(
$setup->getTable('kiwicommerce_login_activity')
)->addColumn(
'entity_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
10,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Primary key for the table'
)->addColumn(
'username',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
40,
['nullable' => false, 'default' => ''],
'Admin username'
)->addColumn(
'name',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
64,
['nullable' => false, 'default' => ''],
'Full name of admin'
)->addColumn(
'remote_ip',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
32,
['nullable' => false, 'default' => ''],
'IP address of logged in admin user'
)->addColumn(
'forwarded_ip',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
32,
['nullable' => false, 'default' => ''],
'Real ip address if visitor used proxy'
)->addColumn(
'user_agent',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'',
['nullable' => false, 'default' => ''],
'Store browser’s user agent'
)->addColumn(
'location',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => ''],
'Location of visitor'
)->addColumn(
'type',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
8,
['nullable' => false, 'default' => ''],
'Is it Login/Logout?'
)->addColumn(
'status',
\Magento\Framework\DB\Ddl\Table::TYPE_BOOLEAN,
'',
['nullable' => true],
'0 = Faild, 1= Success'
)->addColumn(
'created_at',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
'The date when the activity was created'
)->setComment(
'Log all login/logout activity of admin user'
);
$setup->getConnection()->createTable($table);
}
if (version_compare($context->getVersion(), '0.1.4') < 0) {
$tableName = $setup->getTable('kiwicommerce_login_activity');
$connection = $setup->getConnection();
//TODO: Check if the table already exists
if ($connection->isTableExists($tableName) == true) {
$connection->addColumn($tableName, 'remarks', [
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => '',
'nullable' => false,
'default' => '',
'comment' => __('Reason for failed'),
'after' => 'status'
]);
$connection->dropColumn($tableName, 'location', $schemaName = null);
}
}
if (version_compare($context->getVersion(), '0.1.5') < 0) {
$tableName = $setup->getTable('kiwicommerce_activity_log');
//TODO: Check if the table already exists
if ($setup->getConnection()->isTableExists($tableName) == true) {
$definition = [
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 255
];
$setup->getConnection()->addColumn($tableName, 'field_name', $definition);
}
}
if (version_compare($context->getVersion(), '0.1.6') < 0) {
$tableName = $setup->getTable('kiwicommerce_activity');
$connection = $setup->getConnection();
//TODO: Check if the table already exists
if ($connection->isTableExists($tableName) == true) {
$connection->addColumn($tableName, 'fullaction', [
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 200,
'nullable' => false,
'default' => '',
'comment' => __('Full Action Name'),
'after' => 'module'
]);
}
}
$setup->endSetup();
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Block\Adminhtml;
/**
* Class ActivityLogListingTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Block\Adminhtml
*/
class ActivityLogListingTest extends \PHPUnit\Framework\TestCase
{
public $activityRepositoryMock;
public $browserMock;
public $contextMock;
public $request;
public $activityLogListing;
public $activityModel;
public $userAgent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) G...';
public $logData = [
'username' => 'admin',
'module' => 'Admin',
'name' => 'admin admin',
'fullaction' => 'Adminhtml/Index/Index',
'browser' => '',
'date' => '2018-05-18 14:51:23'
];
/**
* @requires PHP 7.0
*/
public function setUp()
{
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->activityRepositoryMock = $this->getMockForAbstractClass(
\KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface::class,
[],
'',
false
);
$this->browserMock = $this->createMock(\KiwiCommerce\AdminActivity\Helper\Browser::class);
$this->request = $this->getMockForAbstractClass(
\Magento\Framework\App\RequestInterface::class,
[],
'',
false
);
$this->contextMock = $objectManager->getObject(
\Magento\Backend\Block\Template\Context::class,
[
'request' => $this->request
]
);
$this->activityModel = $this
->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Activity::class)
->setMethods(
[
'getUserAgent',
'getUsername',
'getModule',
'getName',
'getFullaction',
'getUpdatedAt'
]
)
->disableOriginalConstructor()
->getMock();
$this->activityLogListing = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Block\Adminhtml\ActivityLogListing::class,
[
'activityRepository' => $this->activityRepositoryMock,
'browser' => $this->browserMock,
'context' => $this->contextMock,
]
);
}
/**
* @requires PHP 7.0
*/
public function testGetLogListing()
{
$this->request->expects($this->once())
->method('getParam')
->with('id')
->willReturn(1);
$this->activityRepositoryMock->expects($this->once())
->method('getActivityLog')
->with(1)
->willReturn($this->activityModel);
$this->activityLogListing->getLogListing();
}
/**
* @requires PHP 7.0
*/
public function testGetAdminDetails()
{
$this->request->expects($this->once())
->method('getParam')
->with('id')
->willReturn(1);
$this->activityRepositoryMock->expects($this->once())
->method('getActivityById')
->with(1)
->willReturn($this->activityModel);
$this->browserMock->expects($this->once())
->method('reset')
->willReturnSelf();
$this->activityModel->expects($this->once())
->method('getUserAgent')
->willReturn($this->userAgent);
$this->browserMock->expects($this->once())
->method('setUserAgent')
->with($this->userAgent)
->willReturnSelf();
$this->activityModel->expects($this->once())
->method('getUsername')
->willReturn($this->logData['username']);
$this->activityModel->expects($this->once())
->method('getModule')
->willReturn($this->logData['module']);
$this->activityModel->expects($this->once())
->method('getName')
->willReturn($this->logData['name']);
$this->activityModel->expects($this->once())
->method('getFullaction')
->willReturn($this->logData['fullaction']);
$this->activityModel->expects($this->once())
->method('getUpdatedAt')
->willReturn($this->logData['date']);
$this->assertEquals($this->logData, $this->activityLogListing->getAdminDetails());
}
}
\ No newline at end of file
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Block\Adminhtml;
/**
* Class SelectorTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Block\Adminhtml
*/
class SelectorTest extends \PHPUnit\Framework\TestCase
{
public $urlBuiler;
public $revertUrl = 'http://magento.com/adminactivity/activity/revert';
public $selector;
/**
* @requires PHP 7.0
*/
public function setUp()
{
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->urlBuiler = $this->createMock(\Magento\Framework\UrlInterface::class);
$this->selector = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Block\Adminhtml\Selector::class,
[
'_urlBuilder' => $this->urlBuiler,
]
);
}
/**
* @requires PHP 7.0
*/
public function testGetRevertUrl()
{
$this->urlBuiler->expects($this->once())
->method('getUrl')
->with('adminactivity/activity/revert')
->willReturn($this->revertUrl);
$this->assertEquals($this->revertUrl, $this->selector->getRevertUrl());
}
}
\ No newline at end of file
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Helper;
/**
* Class DataTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Helper
*/
class DataTest extends \PHPUnit\Framework\TestCase
{
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->context = $this->getMockBuilder(\Magento\Framework\App\Helper\Context::class)
->disableOriginalConstructor()
->getMock();
$this->scopeConfig = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
->getMockForAbstractClass();
$this->scopeConfig->expects($this->any())
->method('isSetFlag')
->willReturn(true);
$this->context->expects($this->any())
->method('getScopeConfig')
->willReturn($this->scopeConfig);
$this->config = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Config::class)
->disableOriginalConstructor()
->getMock();
$this->helper = new \KiwiCommerce\AdminActivity\Helper\Data(
$this->context,
$this->config
);
}
/**
* @requires PHP 7.0
*/
public function testIsEnable()
{
$this->assertSame(true, $this->helper->isEnable());
}
/**
* @requires PHP 7.0
*/
public function testIsLoginEnable()
{
$this->assertSame(true, $this->helper->isLoginEnable());
}
/**
* @requires PHP 7.0
*/
public function testIsWildCardModel()
{
$notwildcardmethod = \KiwiCommerce\AdminActivity\Helper\Data::isWildCardModel(\Magento\Framework\App\Helper\Context::class);
$this->assertSame(false, $notwildcardmethod);
$notwildcardmethod = \KiwiCommerce\AdminActivity\Helper\Data::isWildCardModel(\Magento\Framework\App\Config\Value\Interceptor::class);
$this->assertSame(true, $notwildcardmethod);
}
}
\ No newline at end of file
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Helper;
/**
* Class TrackFieldTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Helper
*/
class TrackFieldTest extends \PHPUnit\Framework\TestCase
{
public $helper;
public $product;
public $sampleProduct = [
'name' => 'Test Product',
'sku' => 'TEST-PRO1',
'price' => 99.99
];
/**
* @requires PHP 7.0
*/
public function setUp()
{
$context = $this->getMockBuilder(\Magento\Framework\App\Helper\Context::class)
->disableOriginalConstructor()
->getMock();
$systemConfig = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Activity\SystemConfig::class)
->disableOriginalConstructor()
->getMock();
$themeConfig = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Activity\ThemeConfig::class)
->disableOriginalConstructor()
->getMock();
$this->helper = new \KiwiCommerce\AdminActivity\Helper\TrackField(
$context,
$systemConfig,
$themeConfig
);
$this->product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
->disableOriginalConstructor()
->getMock();
$this->product->expects($this->any())
->method('getData')
->willReturn($this->sampleProduct);
}
/**
* @requires PHP 7.0
* @dataProvider collectFieldDataMethods
*/
public function testGetFields($method)
{
$this->assertNotEmpty($this->helper->getFields($method));
$this->assertGreaterThanOrEqual(1, $this->helper->getFields($method));
}
public function collectFieldDataMethods()
{
return [
'Category' => ['getCategoryFieldData'],
'Product' => ['getProductFieldData'],
'Customer Group' => ['getCustomerGroupFieldData'],
'Customer' => ['getCustomerFieldData'],
'Catalog Promotion' => ['getCatalogPromotionFieldData'],
'Cart Promotion' => ['getCartPromotionFieldData'],
'Email' => ['getEmailFieldData'],
'Page' => ['getPageFieldData'],
'Block' => ['getBlockFieldData'],
'Widget' => ['getWidgetFieldData'],
'Admin User' => ['getAdminUserFieldData'],
'Order' => ['getOrderFieldData'],
'Product Attribute' => ['getAttributeFieldData'],
];
}
/**
* @requires PHP 7.0
*/
public function testGetAddData()
{
$result = $this->helper->getAddData($this->product, 'getProductFieldData');
$this->assertNotEmpty($result);
$this->assertCount(3, $result);
}
/**
* @requires PHP 7.0
*/
public function testGetDeleteData()
{
$result = $this->helper->getDeleteData($this->product, 'getProductFieldData');
$this->assertEmpty($result);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Model;
/**
* Class ProcessorTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Model
*/
class ProcessorTest extends \PHPUnit\Framework\TestCase
{
public $configMock;
public $actionName = '';
public $fullActionName = 'catalog_product_save';
public $observerMock;
public $handlerMock;
public $getEvent;
public $lastAction = '';
public $moduleName = 'module_name';
public $eventConfig = ['action' => 'save', 'module' => 'catalog_products'];
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->configMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Config::class)
->setMethods(['getEventByAction','getTrackFieldModel','getEventModel','getActivityModuleConstant'])
->disableOriginalConstructor()
->getMock();
$this->sessionMock = $this->getMockBuilder(\Magento\Backend\Model\Auth\Session::class)
->disableOriginalConstructor()
->getMock();
$this->handlerMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Handler::class)
->setMethods(['request'])
->disableOriginalConstructor()
->getMock();
$this->observerMock = $this->getMockBuilder(\Magento\Framework\Event\Observer::class)
->setMethods(['getId','getEvent'])
->disableOriginalConstructor()
->getMock();
$this->eventMock = $this
->getMockBuilder(\Magento\Framework\Event::class)
->setMethods(['getObject'])
->disableOriginalConstructor()
->getMock();
$this->objectMock = $this
->getMockBuilder(\Magento\Framework\DataObject::class)
->disableOriginalConstructor()
->getMock();
$this->remoteAddressMock = $this->getMockBuilder(\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress::class)
->disableOriginalConstructor()
->getMock();
$this->activityFactoryMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\ActivityFactory::class)
->disableOriginalConstructor()
->getMock();
$this->activityLogDetailFactoryMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\ActivityLogDetailFactory::class)
->disableOriginalConstructor()
->getMock();
$this->storeManagerInterfaceMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
->disableOriginalConstructor()
->getMock();
$this->dateTimeMock = $this->getMockBuilder(\Magento\Framework\Stdlib\DateTime\DateTime::class)
->disableOriginalConstructor()
->getMock();
$this->activityRepositoryInterfaceMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface::class)
->disableOriginalConstructor()
->getMock();
$this->dataMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->managerInterfaceMock = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class)
->disableOriginalConstructor()
->getMock();
$this->requestInterfaceMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)
->setMethods(['getModuleName',
'getControllerName',
'setModuleName',
'getActionName',
'setActionName',
'getParam',
'getParams',
'getCookie',
'setParams',
'isSecure'])
->disableOriginalConstructor()
->getMock();
$this->statusMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Activity\Status::class)
->disableOriginalConstructor()
->getMock();
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->processorTest = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Model\Processor::class,
[
'config' => $this->configMock,
'authSession' => $this->sessionMock,
'handler' => $this->handlerMock,
'remoteAddress' => $this->remoteAddressMock,
'activityFactory' => $this->activityFactoryMock,
'activityDetailFactory' => $this->activityLogDetailFactoryMock,
'storeManager' => $this->storeManagerInterfaceMock,
'dateTime' => $this->dateTimeMock,
'activityRepository' => $this->activityRepositoryInterfaceMock,
'helper' => $this->dataMock,
'messageManager' => $this->managerInterfaceMock,
'request' => $this->requestInterfaceMock,
'status' => $this->statusMock
]
);
}
public function testValidate()
{
$this->observerMock
->expects($this->any())
->method('getEvent')
->willReturnSelf();
$this->dataMock
->expects($this->any())
->method('isWildCardModel')
->with($this->observerMock)
->willReturn(false);
$this->configMock
->expects($this->any())
->method('getEventByAction')
->with('catalog_product_save')
->willReturn($this->eventConfig);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Observer;
class DeleteAfterTest extends \PHPUnit\Framework\TestCase
{
public $deleteAfter;
public $processorMock;
public $helperMock;
public $observerMock;
public $eventMock;
public $objectMock;
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->processorMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Processor::class)
->disableOriginalConstructor()
->getMock();
$this->helperMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->observerMock = $this
->getMockBuilder(\Magento\Framework\Event\Observer::class)
->disableOriginalConstructor()
->getMock();
$this->eventMock = $this
->getMockBuilder(\Magento\Framework\Event::class)
->setMethods(['getObject'])
->disableOriginalConstructor()
->getMock();
$this->objectMock = $this
->getMockBuilder(\Magento\Framework\DataObject::class)
->setMethods([])
->disableOriginalConstructor()
->getMock();
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->deleteAfter = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Observer\DeleteAfter::class,
[
'processor' => $this->processorMock,
'helper' => $this->helperMock,
]
);
}
/**
* @requires PHP 7.0
*/
public function testExecute()
{
$this->helperMock->expects($this->once())
->method('isEnable')
->willReturn(true);
$this->observerMock
->expects($this->atLeastOnce())
->method('getEvent')
->willReturn($this->eventMock);
$this->eventMock
->expects($this->atLeastOnce())
->method('getObject')
->willReturn($this->objectMock);
$this->processorMock->expects($this->once())
->method('modelDeleteAfter')
->with($this->objectMock)
->willReturnSelf();
$this->assertNull($this->deleteAfter->execute($this->observerMock));
}
/**
* @requires PHP 7.0
*/
public function testExecuteIsEnableFalse()
{
$this->helperMock->expects($this->once())
->method('isEnable')
->willReturn(false);
$this->assertEquals($this->observerMock, $this->deleteAfter->execute($this->observerMock));
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Observer;
class SaveAfterTest extends \PHPUnit\Framework\TestCase
{
public $saveAfter;
public $processorMock;
public $helperMock;
public $observerMock;
public $eventMock;
public $objectMock;
public $configMock;
public $eventConfig = ['action' => 'massCancel', 'module' => 'catalog_products'];
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->processorMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Processor::class)
->disableOriginalConstructor()
->getMock();
$this->helperMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->observerMock = $this
->getMockBuilder(\Magento\Framework\Event\Observer::class)
->disableOriginalConstructor()
->getMock();
$this->eventMock = $this
->getMockBuilder(\Magento\Framework\Event::class)
->setMethods(['getObject'])
->disableOriginalConstructor()
->getMock();
$this->objectMock = $this
->getMockBuilder(\Magento\Framework\DataObject::class)
->setMethods(['getCheckIfIsNew'])
->disableOriginalConstructor()
->getMock();
$this->configMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Config::class)
->setMethods(['getEventByAction','getTrackFieldModel','getEventModel','getActivityModuleConstant'])
->disableOriginalConstructor()
->getMock();
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->saveAfter = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Observer\SaveAfter::class,
[
'processor' => $this->processorMock,
'helper' => $this->helperMock,
]
);
}
/**
* @requires PHP 7.0
*/
public function testExecute()
{
$this->helperMock->expects($this->once())
->method('isEnable')
->willReturn(true);
$this->observerMock
->expects($this->atLeastOnce())
->method('getEvent')
->willReturn($this->eventMock);
$this->eventMock
->expects($this->atLeastOnce())
->method('getObject')
->willReturn($this->objectMock);
$this->objectMock
->expects($this->atLeastOnce())
->method('getCheckIfIsNew')
->willReturn(true);
$this->processorMock->expects($this->once())
->method('modelAddAfter')
->with($this->objectMock)
->willReturnSelf();
$this->assertTrue($this->saveAfter->execute($this->observerMock));
}
/**
* @requires PHP 7.0
*/
public function testExecuteIsEnableReturnFalse()
{
$this->helperMock->expects($this->once())
->method('isEnable')
->willReturn(false);
$this->assertEquals($this->observerMock, $this->saveAfter->execute($this->observerMock));
}
/**
* @requires PHP 7.0
*/
public function testExecuteGetCheckIfIsNewReturnFalse()
{
$this->helperMock->expects($this->once())
->method('isEnable')
->willReturn(true);
$this->observerMock
->expects($this->atLeastOnce())
->method('getEvent')
->willReturn($this->eventMock);
$this->eventMock
->expects($this->atLeastOnce())
->method('getObject')
->willReturn($this->objectMock);
$this->objectMock
->expects($this->atLeastOnce())
->method('getCheckIfIsNew')
->willReturn(false);
$this->processorMock->expects($this->once())
->method('validate')
->with($this->objectMock)
->willReturn(true);
$this->processorMock->expects($this->once())
->method('modelEditAfter')
->with($this->objectMock)
->willReturnSelf();
$this->assertTrue($this->saveAfter->execute($this->observerMock));
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Observer;
class SaveBeforeTest extends \PHPUnit\Framework\TestCase
{
public $saveBefore;
public $processorMock;
public $helperMock;
public $activityRepositoryMock;
public $observerMock;
public $eventMock;
public $objectMock;
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->processorMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Processor::class)
->disableOriginalConstructor()
->getMock();
$this->helperMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->activityRepositoryMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface::class)
->getMock();
$this->observerMock = $this
->getMockBuilder(\Magento\Framework\Event\Observer::class)
->disableOriginalConstructor()
->getMock();
$this->eventMock = $this
->getMockBuilder(\Magento\Framework\Event::class)
->setMethods(['getObject'])
->disableOriginalConstructor()
->getMock();
$this->objectMock = $this
->getMockBuilder(\Magento\Framework\DataObject::class)
->setMethods(
[
'getId',
'setCheckIfIsNew',
'getOrigData'
]
)
->disableOriginalConstructor()
->getMock();
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->saveBefore = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Observer\SaveBefore::class,
[
'processor' => $this->processorMock,
'helper' => $this->helperMock,
'activityRepository' => $this->activityRepositoryMock,
]
);
}
/**
* @requires PHP 7.0
*/
public function testExecuteIsEnableReturnFalse()
{
$this->helperMock->expects($this->once())
->method('isEnable')
->willReturn(false);
$this->assertEquals($this->observerMock, $this->saveBefore->execute($this->observerMock));
}
/**
* @requires PHP 7.0
*/
public function testExecuteGetIdReturnZero()
{
$this->helperMock->expects($this->once())
->method("isEnable")
->willReturn(true);
$this->observerMock
->expects($this->atLeastOnce())
->method('getEvent')
->willReturn($this->eventMock);
$this->eventMock
->expects($this->atLeastOnce())
->method('getObject')
->willReturn($this->objectMock);
$this->objectMock
->expects($this->atLeastOnce())
->method('getId')
->willReturn(0);
$this->objectMock
->expects($this->atLeastOnce())
->method('setCheckIfIsNew')
->with(true)
->willReturnSelf();
$this->assertEquals($this->observerMock, $this->saveBefore->execute($this->observerMock));
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Plugin\App;
/**
* Class ActionTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Plugin\App
*/
class ActionTest extends \PHPUnit\Framework\TestCase
{
public $processorMock;
public $controllerMock;
public $requestMock;
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->processorMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Model\Processor::class)
->disableOriginalConstructor()
->getMock();
$this->controllerMock = $this->getMockBuilder(\Magento\Framework\Interception\InterceptorInterface::class)
->setMethods(['getRequest','___callParent'])
->disableOriginalConstructor()
->getMock();
$this->requestMock = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class)
->disableOriginalConstructor()
->setMethods([
'getActionName','getFullActionName','getModuleName'
])
->getMock();
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->actionTest = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Plugin\App\Action::class,
[
'processor' => $this->processorMock
]
);
}
/**
* @requires PHP 7.0
*/
public function testBeforeDispatch()
{
$this->controllerMock
->expects($this->exactly(3))
->method('getRequest')
->willReturn($this->requestMock);
$this->requestMock
->expects($this->once())
->method('getActionName')
->willReturn('action');
$this->requestMock
->expects($this->once())
->method('getFullActionName')
->willReturn('fullaction');
$this->requestMock
->expects($this->once())
->method('getModuleName')
->willReturn('module');
$this->processorMock->expects($this->once())
->method('init')
->with('fullaction', 'action')
->willReturnSelf();
$this->processorMock->expects($this->once())
->method('addPageVisitLog')
->with('module')
->willReturnSelf();
$this->assertNull($this->actionTest->beforeDispatch($this->controllerMock));
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Plugin;
/**
* Class AuthTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Plugin
*/
class AuthTest extends \PHPUnit\Framework\TestCase
{
public $authMock;
public $authStorageMock;
public $helperMock;
public $loginRepositoryMock;
public $user;
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->authMock = $this->getMockBuilder(\Magento\Backend\Model\Auth::class)
->setMethods(['getAuthStorage'])
->disableOriginalConstructor()
->getMock();
$this->authStorageMock = $this->getMockBuilder(\Magento\Backend\Model\Auth\StorageInterface::class)
->setMethods([
'getUser',
'processLogin',
'isLoggedIn',
'prolong',
'processLogout'
])
->disableOriginalConstructor()
->getMock();
$this->helperMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Helper\Data::class)
->disableOriginalConstructor()
->getMock();
$this->loginRepositoryMock = $this->getMockBuilder(\KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface
::class)
->setMethods(['setUser','addLog','getListBeforeDate'])
->disableOriginalConstructor()
->getMock();
$this->user = $this->getMockBuilder(\Magento\User\Model\User::class)
->setMethods(['addLogoutLog'])
->disableOriginalConstructor()
->getMock();
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->authTest = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Plugin\Auth::class,
[
'helper' => $this->helperMock,
'loginRepository' => $this->loginRepositoryMock
]
);
}
/**
* @requires PHP 7.0
*/
public function testAroundLogout()
{
$this->authMock
->expects($this->once())
->method('getAuthStorage')
->willReturn($this->authStorageMock);
$this->authStorageMock
->expects($this->once())
->method('getUser')
->willReturn('user');
$this->helperMock
->expects($this->once())
->method('isLoginEnable')
->willReturn($this->loginRepositoryMock);
$this->loginRepositoryMock
->expects($this->once())
->method('setUser')
->with('user')
->willReturn($this->user);
$this->user
->expects($this->once())
->method('addLogoutLog')
->willReturn('LogoutLog');
$callbackMock = $this->getMockBuilder(\stdClass::class)
->setMethods(['__invoke'])
->getMock();
$callbackMock->expects($this->once())->method('__invoke');
$this->authTest->aroundLogout($this->authMock, $callbackMock);
}
/**
* @requires PHP 7.0
*/
public function testAroundLogoutIsLoginEnableFalse()
{
$this->helperMock
->expects($this->once())
->method('isLoginEnable')
->willReturn(false);
$callbackMock = $this->getMockBuilder(\stdClass::class)
->setMethods(['__invoke'])
->getMock();
$callbackMock
->expects($this->once())
->method('__invoke');
$this->assertNull($this->authTest->aroundLogout($this->authMock, $callbackMock));
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Test\Unit\Plugin\User;
/**
* Class DeleteTest
* @package KiwiCommerce\AdminActivity\Test\Unit\Plugin
*/
class DeleteTest extends \PHPUnit\Framework\TestCase
{
public $delete;
public $userMock;
public $userResourceMock;
/**
* @requires PHP 7.0
*/
public function setUp()
{
$this->userResourceMock = $this->getMockBuilder(\Magento\User\Model\ResourceModel\User::class)
->setMethods([])
->disableOriginalConstructor()
->getMock();
$this->userMock = $this->getMockBuilder(\Magento\User\Model\User::class)
->setMethods(['load', 'getId', 'afterDelete'])
->disableOriginalConstructor()
->getMock();
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->delete = $objectManager->getObject(
\KiwiCommerce\AdminActivity\Plugin\User\Delete::class,
[]
);
}
/**
* @requires PHP 7.0
*/
public function testaroundDelete()
{
$this->userMock
->expects($this->once())
->method('getId')
->willReturn(1);
$this->userMock->expects($this->once())
->method('load')
->willReturn($this->userMock);
$this->userMock->expects($this->once())
->method('afterDelete')
->willReturnSelf();
$callbackMock = $this->getMockBuilder(\stdClass::class)
->setMethods(['__invoke'])
->getMock();
$callbackMock
->expects($this->once())
->method('__invoke');
$this->delete->aroundDelete($this->userResourceMock, $callbackMock, $this->userMock);
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\ActionType;
/**
* Class Options
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\ActionType
*/
class Options implements \Magento\Framework\Option\ArrayInterface
{
/**
* @var \KiwiCommerce\AdminActivity\Helper\Data
*/
public $helper;
/**
* Options constructor.
* @param \KiwiCommerce\AdminActivity\Helper\Data $helper
*/
public function __construct(\KiwiCommerce\AdminActivity\Helper\Data $helper)
{
$this->helper = $helper;
}
/**
* List all option to get in filter
* @return array
*/
public function toOptionArray()
{
$data = [];
$lableList = $this->helper->getAllActions();
foreach ($lableList as $key => $value) {
$data[] = ['value'=> $key,'label'=> __($value)];
}
return $data;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Ui\Component\Listing\Columns\Column;
use \KiwiCommerce\AdminActivity\Helper\Data as Helper;
/**
* Class ActionTypeColumn
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class ActionTypeColumn extends Column
{
/**
* @var \KiwiCommerce\AdminActivity\Helper\Data
*/
public $helper;
/**
* ActionTypeColumn constructor.
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param Helper $helper
* @param array $components
* @param array $data
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
Helper $helper,
array $components = [],
array $data = []
) {
$this->helper = $helper;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* Prepare Data Source
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
if (isset($item['action_type'])) {
$item['action_type'] = $this->helper->getActionTranslatedLabel($item['action_type']);
}
}
}
return $dataSource;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
use Magento\Ui\Component\Listing\Columns\Column;
/**
* Class BrowserColumn
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class BrowserColumn extends Column
{
/**
* @var \KiwiCommerce\AdminActivity\Helper\Browser
*/
public $browser;
/**
* BrowserColumn constructor.
* @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
* @param \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory
* @param \KiwiCommerce\AdminActivity\Helper\Browser $browser
* @param array $components
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\UiComponent\ContextInterface $context,
\Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory,
\KiwiCommerce\AdminActivity\Helper\Browser $browser,
array $components,
array $data
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->browser = $browser;
}
/**
* Get user agent data
* @param $item
* @return string
*/
public function getAgent($item)
{
$this->browser->reset();
$this->browser->setUserAgent($item['user_agent']);
return $this->browser->getBrowser().' '.$this->browser->getVersion();
}
/**
* Prepare Data Source
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
$item[$this->getData('name')] = $this->getAgent($item);
}
}
return $dataSource;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
use Magento\Ui\Component\Listing\Columns\Column;
/**
* Class ItemColumn
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class ItemColumn extends Column
{
/**
* @var int
*/
const URL_COUNT = 7;
/**
* @var array
*/
public $allowedAttributes = [
'href',
'title',
'id',
'class',
'style',
'target'
];
/**
* Escaper
* @var \Magento\Framework\Escaper
*/
public $escaper;
/**
* @var \Magento\Backend\Model\UrlInterface
*/
public $backendUrl;
/**
* Filter manager
* @var \Magento\Framework\Filter\FilterManager
*/
public $filterManager;
/**
* ItemColumn constructor.
* @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
* @param \Magento\Framework\View\Element\Context $contexts
* @param \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory
* @param \Magento\Backend\Model\UrlInterface $backendUrl
* @param array $components
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\UiComponent\ContextInterface $context,
\Magento\Framework\View\Element\Context $contexts,
\Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory,
\Magento\Backend\Model\UrlInterface $backendUrl,
array $components,
array $data
) {
$this->escaper = $contexts->getEscaper();
$this->backendUrl = $backendUrl;
$this->filterManager = $contexts->getFilterManager();
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* Escape HTML entities
* @param string|array $data
* @param array|null $allowedTags
* @return string
*/
public function escapeHtml($data, $allowedTags = null)
{
return $this->escaper->escapeHtml($data, $allowedTags);
}
/**
* Render block HTML
* @return string
*/
public function _toHtml()
{
$length = 30;
$itemName = $this->filterManager->truncate(
$this->getLabel(),
['length' => $length, 'etc' => '...', 'remainder' => '', 'breakWords' => false]);
return '<a ' . $this->getLinkAttributes() . ' >' . $this->escapeHtml($itemName) . '</a></li>';
}
/**
* Prepare link attributes as serialized and formatted string
* @return string
*/
public function getLinkAttributes()
{
$attributes = [];
foreach ($this->allowedAttributes as $attribute) {
$value = $this->getDataUsingMethod($attribute);
if ($value !== null) {
$attributes[$attribute] = $this->escapeHtml($value);
}
}
if (!empty($attributes)) {
return $this->serialize($attributes);
}
return '';
}
/**
* Serialize attributes
* @param array $attributes
* @param string $valueSeparator
* @param string $fieldSeparator
* @param string $quote
* @return string
*/
public function serialize($attributes = [], $valueSeparator = '=', $fieldSeparator = ' ', $quote = '"')
{
$data = [];
foreach ($attributes as $key => $value) {
$data[] = $key . $valueSeparator . $quote . $value . $quote;
}
return implode($fieldSeparator, $data);
}
/**
* Convert action to url
* @param $url
* @return string
*/
public function prepareUrl($url)
{
if (current(explode('/', $url))=='theme' && count(explode('/', $url))==self::URL_COUNT) {
list($module, $controller, $action, $scope, $store, $field, $id) = explode('/', $url);
$editUrl = $this->backendUrl->getUrl(
implode('/', [$module, $controller, $action, $scope, $store]),
[$field => $id]
);
return $editUrl;
}
list($module, $controller, $action, $field, $id) = explode('/', $url);
$editUrl = $this->backendUrl->getUrl(
implode('/', [$module, $controller, $action]),
[$field => $id]
);
return $editUrl;
}
/**
* Initialize parameter for link
* @return void
*/
public function __initLinkParams($item)
{
$this->setHref($this->prepareUrl($item['item_url']));
$this->setTitle($item['item_name']);
$this->setTarget('_blank');
$this->setLabel($item['item_name']);
}
/**
* Prepare Data Source
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
if (!empty($item['item_url'])) {
$this->__initLinkParams($item);
$item[$this->getData('name')] = $this->_toHtml();
}
}
}
return $dataSource;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
use Magento\Ui\Component\Listing\Columns\Column;
/**
* Class StatusColumn
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class RevertStatusColumn extends Column
{
/**
* Prepare Data Source
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
if ($item['is_revertable']==\KiwiCommerce\AdminActivity\Model\Activity\Status::ACTIVITY_REVERTABLE) {
$item[$this->getData('name')] =
'<span class="grid-severity-minor" title=""><span>Revert</span></span>';
} elseif ($item['is_revertable']==
\KiwiCommerce\AdminActivity\Model\Activity\Status::ACTIVITY_REVERT_SUCCESS) {
$item[$this->getData('name')] =
'<span class="grid-severity-notice" title=""><span>Success</span></span>'.
'<br/><strong>Reverted By:</strong> '.$item['revert_by'];
} elseif ($item['is_revertable']==\KiwiCommerce\AdminActivity\Model\Activity\Status::ACTIVITY_FAIL) {
$item[$this->getData('name')] =
'<span class="grid-severity-critical" title=""><span>Faild</span></span>';
} else {
$item[$this->getData('name')] = '-';
}
}
}
return $dataSource;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
use Magento\Ui\Component\Listing\Columns\Column;
/**
* Class StatusColumn
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class StatusColumn extends Column
{
/**
* Prepare Data Source
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
if ($item[$this->getData('name')]) {
$item[$this->getData('name')] =
'<span class="grid-severity-notice"><span>Success</span></span>';
} else {
$remark = $item['remarks'];
$item[$this->getData('name')] =
'<span class="grid-severity-critical" title="'.$remark.'"><span>Faild</span></span>';
}
}
}
return $dataSource;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
/**
* Class StoreColumn
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class StoreColumn extends \Magento\Store\Ui\Component\Listing\Column\Store
{
/**
* Field name for store
* @var string
*/
const KEY_FIELD = 'store_id';
/**
* Prepare Item
* @param array $item
* @return string
*/
public function prepareItem(array $item)
{
//TODO: To set and display default value
$this->storeKey = !empty($this->storeKey)?$this->storeKey:self::KEY_FIELD;
if ($item[$this->storeKey]==0) {
$origStores['0'] = 0;
}
$content = '';
if (!empty($item[$this->storeKey])) {
$origStores = $item[$this->storeKey];
}
if (empty($origStores)) {
return '';
}
if (!is_array($origStores)) {
$origStores = [$origStores];
}
if (in_array(0, $origStores) && count($origStores) == 1) {
return __('All Store Views');
}
$data = $this->systemStore->getStoresStructure(false, $origStores);
foreach ($data as $website) {
$content .= $website['label'] . "<br/>";
foreach ($website['children'] as $group) {
$content .= str_repeat('&nbsp;', 3) . $this->escaper->escapeHtml($group['label']) . "<br/>";
foreach ($group['children'] as $store) {
$content .= str_repeat('&nbsp;', 6) . $this->escaper->escapeHtml($store['label']) . "<br/>";
}
}
}
return $content;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
use Magento\Ui\Component\Listing\Columns\Column;
/**
* Class UserAgentColumn
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class UserAgentColumn extends Column
{
/**
* @var \KiwiCommerce\AdminActivity\Helper\Browser
*/
public $browser;
/**
* UserAgentColumn constructor.
* @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
* @param \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory
* @param \KiwiCommerce\AdminActivity\Helper\Browser $browser
* @param array $components
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\UiComponent\ContextInterface $context,
\Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory,
\KiwiCommerce\AdminActivity\Helper\Browser $browser,
array $components,
array $data
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->browser = $browser;
}
/**
* Get user agent data
* @param $item
* @return string
*/
public function getAgent($item)
{
$this->browser->reset();
$this->browser->setUserAgent($item['user_agent']);
return $this->browser->__toString();
}
/**
* Prepare Data Source
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
$item[$this->getData('name')] = $this->getAgent($item);
}
}
return $dataSource;
}
}
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
namespace KiwiCommerce\AdminActivity\Ui\Component\Listing\Column;
use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
/**
* Class ViewAction
* @package KiwiCommerce\AdminActivity\Ui\Component\Listing\Column
*/
class ViewAction extends Column
{
/**
* @var UrlInterface
*/
public $urlBuilder;
/**
* @var \Magento\Framework\View\LayoutInterface
*/
public $layout;
/**
* ViewAction constructor.
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param UrlInterface $urlBuilder
* @param \Magento\Framework\View\LayoutInterface $layout
* @param array $components
* @param array $data
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
UrlInterface $urlBuilder,
\Magento\Framework\View\LayoutInterface $layout,
array $components = [],
array $data = []
) {
$this->urlBuilder = $urlBuilder;
$this->layout = $layout;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* Get item url
* @return string
*/
public function getViewUrl()
{
return $this->urlBuilder->getUrl(
$this->getData('config/viewUrlPath')
);
}
/**
* Prepare Data Source
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
if (isset($item['entity_id'])) {
$item[$this->getData('name')] = $this->layout->createBlock(
\Magento\Backend\Block\Widget\Button::class,
'',
[
'data' => [
'label' => __('View'),
'type' => 'button',
'disabled' => false,
'class' => 'action-activity-log-view',
'onclick' => 'adminActivityLogView.open(\''
. $this->getViewUrl() . '\', \'' . $item['entity_id']
. '\', \'' . $item['is_revertable'] . '\')',
]
]
)->toHtml();
}
}
}
return $dataSource;
}
}
{
"name": "kiwicommerce/module-admin-activity",
"description": "The Admin Activity extension makes it easy to track all admin activity and revert the modification.",
"type": "magento2-module",
"version": "1.0.7",
"license": [
"OSL-3.0"
],
"minimum-stability": "dev",
"authors": [
{
"name": "Kiwi Commerce Ltd",
"email": "hello@kiwicommerce.co.uk",
"homepage": "https://kiwicommerce.co.uk/",
"role": "Leader"
}
],
"require": {
"magento/framework": ">=100.0.0",
"magento/module-backend": ">=100.0.0"
},
"keywords": [
"magento 2",
"magento2",
"admin",
"backend",
"activity",
"log"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"KiwiCommerce\\AdminActivity\\": ""
}
}
}
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Magento_Backend::stores">
<resource id="Magento_Backend::stores_settings">
<resource id="Magento_Config::config">
<resource id="KiwiCommerce_AdminActivity::activityConfig" title="Admin Activity Section" />
</resource>
</resource>
</resource>
<resource id="Magento_Backend::system">
<resource id="KiwiCommerce_AdminActivity::activity_head" title="Admin Activity" sortOrder="100" >
<resource id="KiwiCommerce_AdminActivity::activity" title="View" sortOrder="10" />
<resource id="KiwiCommerce_AdminActivity::login_activity" title="Login Activity" sortOrder="20" />
<resource id="KiwiCommerce_AdminActivity::configuration" title="Settings" sortOrder="40" />
</resource>
</resource>
</resource>
</resources>
</acl>
</config>
\ No newline at end of file
<?xml version="1.0" ?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="adminactivity.xsd">
<actions>
<action id="view">
<label translate="true">View</label>
</action>
<action id="save">
<label translate="true">New</label>
</action>
<action id="edit">
<label translate="true">Edit</label>
</action>
<action id="delete">
<label translate="true">Delete</label>
</action>
<action id="massDelete">
<label translate="true">Mass Delete</label>
</action>
<action id="massStatus">
<label translate="true">Mass Status</label>
</action>
<action id="massEdit">
<label translate="true">Mass Edit</label>
</action>
<action id="massSubscribe">
<label translate="true">Mass Subscribe</label>
</action>
<action id="massUnsubscribe">
<label translate="true">Mass Unsubscribe</label>
</action>
<action id="massAssignGroup">
<label translate="true">Mass Assign Group</label>
</action>
<action id="massDisable">
<label translate="true">Mass Disable</label>
</action>
<action id="massEnable">
<label translate="true">Mass Enable</label>
</action>
<action id="reorder">
<label translate="true">Reorder</label>
</action>
<action id="hold">
<label translate="true">Hold</label>
</action>
<action id="unhold">
<label translate="true">Unhold</label>
</action>
<action id="cancel">
<label translate="true">Cancel</label>
</action>
<action id="addComment">
<label translate="true">Add Comment</label>
</action>
<action id="massCancel">
<label translate="true">Mass Cancel</label>
</action>
<action id="massHold">
<label translate="true">Mass Hold</label>
</action>
<action id="massUnhold">
<label translate="true">Mass Unhold</label>
</action>
<action id="assign">
<label translate="true">Assign</label>
</action>
<action id="unassign">
<label translate="true">Unassign</label>
</action>
</actions>
<modules>
<module name="catalog_products">
<label translate="true">Catalog Product</label>
<models>
<class name="Magento\Catalog\Model\Product" />
<class name="Magento\Catalog\Model\Product\Action" />
<class name="Magento\Catalog\Model\Product\Attribute\Source\Status" />
<class name="Magento\CatalogInventory\Model\StockState" />
</models>
<events>
<event controller_action="catalog_product_save" action_alias="save" />
<event controller_action="catalog_product_massDelete" action_alias="massDelete" />
<event controller_action="catalog_product_massStatus" action_alias="massStatus" post_dispatch="productUpdate" />
<event controller_action="catalog_product_action_attribute_save" action_alias="massEdit" post_dispatch="productUpdate" />
</events>
<config>
<trackfield method="getProductFieldData" />
<configpath constant="MODULE_PRODUCT" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="name" />
</config>
</module>
<module name="catalog_categories">
<label translate="true">Catalog Categories</label>
<models>
<class name="Magento\Catalog\Model\Category" />
</models>
<events>
<event controller_action="catalog_category_save" action_alias="save" />
<event controller_action="catalog_category_edit" action_alias="edit" />
<event controller_action="catalog_category_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getCategoryFieldData" />
<configpath constant="MODULE_CATEGORY" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="name" />
</config>
</module>
<module name="customer">
<label translate="true">Customer</label>
<models>
<class name="Magento\Customer\Model\Customer" />
<class name="Magento\Newsletter\Model\Subscriber" />
<class name="Magento\Customer\Model\Address" />
</models>
<events>
<event controller_action="customer_index_save" action_alias="save" />
<event controller_action="customer_index_delete" action_alias="delete" />
<event controller_action="customer_index_massDelete" action_alias="massDelete" />
<event controller_action="customer_index_massSubscribe" action_alias="massSubscribe" />
<event controller_action="customer_index_massUnsubscribe" action_alias="massUnsubscribe" />
<event controller_action="customer_index_massAssignGroup" action_alias="massAssignGroup" />
<event controller_action="customer_index_inlineEdit" action_alias="massEdit" />
</events>
<config>
<trackfield method="getCustomerFieldData" />
<configpath constant="MODULE_CUSTOMER" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="firstname" />
</config>
</module>
<module name="customer_group">
<label translate="true">Customer Group</label>
<models>
<class name="Magento\Customer\Model\Group" />
</models>
<events>
<event controller_action="customer_group_save" action_alias="save" />
<event controller_action="customer_group_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getCustomerGroupFieldData" />
<configpath constant="MODULE_CUSTOMER" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="customer_group_code" />
</config>
</module>
<module name="catalog_promotion">
<label translate="true">Catalog Promotion</label>
<models>
<class name="Magento\CatalogRule\Model\Rule" />
</models>
<events>
<event controller_action="catalog_rule_promo_catalog_save" action_alias="save" />
<event controller_action="catalog_rule_promo_catalog_edit" action_alias="edit" />
<event controller_action="catalog_rule_promo_catalog_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getCatalogPromotionFieldData" />
<configpath constant="MODULE_PROMOTION" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="name" />
</config>
</module>
<module name="cart_promotion">
<label translate="true">Cart Promotion</label>
<models>
<class name="Magento\SalesRule\Model\Rule" />
</models>
<events>
<event controller_action="sales_rule_promo_quote_save" action_alias="save" />
<event controller_action="sales_rule_promo_quote_edit" action_alias="edit" />
<event controller_action="sales_rule_promo_quote_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getCartPromotionFieldData" />
<configpath constant="MODULE_PROMOTION" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="name" />
</config>
</module>
<module name="email">
<label translate="true">Email Newsletter</label>
<models>
<class name="Magento\Email\Model\Template" />
<class name="Magento\Newsletter\Model\Template" />
</models>
<events>
<event controller_action="adminhtml_email_template_save" action_alias="save" />
<event controller_action="adminhtml_email_template_edit" action_alias="edit" />
<event controller_action="adminhtml_email_template_delete" action_alias="delete" />
<event controller_action="newsletter_template_save" action_alias="save" />
<event controller_action="newsletter_template_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getEmailFieldData" />
<configpath constant="MODULE_EMAIL" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="template_subject" />
</config>
</module>
<module name="cms_pages">
<label translate="true">Cms Pages</label>
<models>
<class name="Magento\Cms\Model\Page" />
</models>
<events>
<event controller_action="cms_page_save" action_alias="save" />
<event controller_action="cms_page_edit" action_alias="edit" />
<event controller_action="cms_page_delete" action_alias="delete" />
<event controller_action="cms_page_massDelete" action_alias="massDelete" />
<event controller_action="cms_page_massDisable" action_alias="massDisable" />
<event controller_action="cms_page_massEnable" action_alias="massEnable" />
<event controller_action="cms_page_inlineEdit" action_alias="massEdit" />
</events>
<config>
<trackfield method="getPageFieldData" />
<configpath constant="MODULE_PAGE" />
<editurl url="{{module}}/{{controller}}/edit/page_id/{{id}}" />
<itemfield field="title" />
</config>
</module>
<module name="cms_blocks">
<label translate="true">Cms Blocks</label>
<models>
<class name="Magento\Cms\Model\Block" />
</models>
<events>
<event controller_action="cms_block_save" action_alias="save" />
<event controller_action="cms_block_edit" action_alias="edit" />
<event controller_action="cms_block_delete" action_alias="delete" />
<event controller_action="cms_block_massDelete" action_alias="massDelete" />
<event controller_action="cms_block_inlineEdit" action_alias="massEdit" />
</events>
<config>
<trackfield method="getBlockFieldData" />
<configpath constant="MODULE_BLOCK" />
<editurl url="{{module}}/{{controller}}/edit/block_id/{{id}}" />
<itemfield field="title" />
</config>
</module>
<module name="cms_widget">
<label translate="true">Cms Widget</label>
<models>
<class name="Magento\Widget\Model\Widget\Instance" />
</models>
<events>
<event controller_action="adminhtml_widget_instance_save" action_alias="save" />
<event controller_action="adminhtml_widget_instance_edit" action_alias="edit" />
<event controller_action="adminhtml_widget_instance_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getWidgetFieldData" />
<configpath constant="MODULE_WIDGET" />
<editurl url="{{module}}/{{controller}}/edit/instance_id/{{id}}" />
<itemfield field="title" />
</config>
</module>
<module name="theme_configuration">
<label translate="true">Themes</label>
<models>
<class name="Magento\Framework\App\Config\Value" />
</models>
<events>
<event controller_action="theme_design_config_save" action_alias="edit" />
</events>
<config>
<trackfield method="getThemeConfigFieldData" />
<configpath constant="MODULE_THEME" />
<editurl url="theme/design_config/edit/scope/{{id}}" />
<itemfield field="config" />
</config>
</module>
<module name="theme_schedule">
<label translate="true">Themes Schedule</label>
<models>
<class name="Magento\Framework\App\DesignInterface" />
</models>
<events>
<event controller_action="adminhtml_system_design_save" action_alias="save" />
<event controller_action="adminhtml_system_design_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getThemeScheduleFieldData" />
<configpath constant="MODULE_THEME" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="design_change_id" />
</config>
</module>
<module name="system_configuration">
<label translate="true">System Configuration</label>
<models>
<class name="Magento\Framework\App\Config\Value" />
</models>
<events>
<event controller_action="adminhtml_system_config_save" action_alias="save" />
<event controller_action="adminhtml_system_currencysymbol_save" action_alias="save" />
</events>
<config>
<trackfield method="getSystemConfigFieldData" />
<configpath constant="MODULE_SYSTEM_CONFIG" />
<editurl url="admin/system_config/edit/section/{{id}}" />
<itemfield field="config" />
</config>
</module>
<module name="system_store">
<label translate="true">Store and Website</label>
<models>
<class name="Magento\Store\Model\Store" />
<class name="Magento\Store\Model\Website" />
<class name="Magento\Store\Model\Group" />
</models>
<events>
<event controller_action="adminhtml_system_store_save" action_alias="save" />
<event controller_action="adminhtml_system_store_deleteStorePost" action_alias="delete" />
<event controller_action="adminhtml_system_store_deleteWebsitePost" action_alias="delete" />
<event controller_action="adminhtml_system_store_deleteGroupPost" action_alias="delete" />
</events>
<config>
<trackfield method="getSystemStoreFieldData" />
<configpath constant="MODULE_SYSTEM_CONFIG" />
<editurl url="admin/system_store/editStore/store_id/{{id}}" />
<itemfield field="code" />
</config>
</module>
<module name="product_attributes">
<label translate="true">Product Attributes</label>
<models>
<class name="Magento\Catalog\Model\ResourceModel\Eav\Attribute" />
</models>
<events>
<event controller_action="catalog_product_attribute_save" action_alias="save" />
<event controller_action="catalog_product_attribute_edit" action_alias="edit" />
<event controller_action="catalog_product_attribute_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getAttributeFieldData" />
<configpath constant="MODULE_ATTRIBUTE" />
<editurl url="{{module}}/{{controller}}/edit/attribute_id/{{id}}" />
<itemfield field="frontend_label" />
</config>
</module>
<module name="product_attributes_set">
<label translate="true">Product Attributes Set</label>
<models>
<class name="Magento\Eav\Model\Entity\Attribute\Set" />
</models>
<events>
<event controller_action="catalog_product_set_save" action_alias="save" />
<event controller_action="catalog_product_set_edit" action_alias="edit" />
<event controller_action="catalog_product_set_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getAttributeSetFieldData" />
<configpath constant="MODULE_ATTRIBUTE" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="attribute_set_name" />
</config>
</module>
<module name="product_review_rating">
<label translate="true">Product Review Rating</label>
<models>
<class name="Magento\Review\Model\Rating" />
</models>
<events>
<event controller_action="review_rating_save" action_alias="save" />
<event controller_action="review_rating_edit" action_alias="edit" />
<event controller_action="review_rating_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getReviewRatingFieldData" />
<configpath constant="MODULE_ATTRIBUTE" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="rating_code" />
</config>
</module>
<module name="product_review">
<label translate="true">Product Review</label>
<models>
<class name="Magento\Review\Model\Review" />
</models>
<events>
<event controller_action="review_product_post" action_alias="save" />
<event controller_action="review_product_save" action_alias="edit" />
<event controller_action="review_product_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getReviewFieldData" />
<configpath constant="MODULE_ATTRIBUTE" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="nickname" />
</config>
</module>
<module name="admin_user">
<label translate="true">Admin User</label>
<models>
<class name="Magento\User\Model\User" />
</models>
<events>
<event controller_action="adminhtml_user_save" action_alias="save" />
<event controller_action="adminhtml_user_edit" action_alias="edit" />
<event controller_action="adminhtml_user_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getAdminUserFieldData" />
<configpath constant="MODULE_ADMIN_USER" />
<editurl url="{{module}}/{{controller}}/edit/user_id/{{id}}" />
<itemfield field="username" />
</config>
</module>
<module name="admin_user_role">
<label translate="true">Admin User Role</label>
<models>
<class name="Magento\Authorization\Model\Role" />
</models>
<events>
<event controller_action="adminhtml_user_role_saverole" action_alias="save" />
<event controller_action="adminhtml_user_role_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getAdminUserRoleFieldData" />
<configpath constant="MODULE_ADMIN_USER" />
<editurl url="{{module}}/{{controller}}/editrole/rid/{{id}}" />
<itemfield field="role_name" />
</config>
</module>
<module name="sales_order">
<label translate="true">Sales Order</label>
<models>
<class name="Magento\Sales\Model\Order" />
<class name="Magento\Sales\Model\Order\Invoice" />
<class name="Magento\Sales\Model\Order\Status\History" />
<class name="Magento\Customer\Model\Customer" />
<class name="Magento\Customer\Model\Address" />
<class name="Magento\Sales\Model\Order\Invoice\Comment" />
<class name="Magento\Sales\Model\Order\Shipment" />
<class name="Magento\Sales\Model\Order\Shipment\Comment" />
<class name="Magento\Sales\Model\Order\Shipment\Track" />
<class name="Magento\Sales\Model\Order\Creditmemo" />
<class name="Magento\Sales\Model\Order\Creditmemo\Comment" />
<class name="Magento\Sales\Model\Order\Address" />
</models>
<events>
<event controller_action="sales_order_create_save" action_alias="save" />
<event controller_action="sales_order_edit_save" action_alias="edit" />
<event controller_action="sales_order_addresssave" action_alias="edit" />
<event controller_action="sales_order_cancel" action_alias="cancel" />
<event controller_action="sales_order_hold" action_alias="hold" />
<event controller_action="sales_order_unhold" action_alias="unhold" />
<event controller_action="sales_order_create_reorder" action_alias="reorder" />
<event controller_action="sales_order_invoice_save" action_alias="save" />
<event controller_action="sales_order_creditmemo_save" action_alias="save" />
<event controller_action="adminhtml_order_shipment_save" action_alias="save" />
<event controller_action="sales_order_massCancel" action_alias="massCancel" />
<event controller_action="sales_order_massHold" action_alias="massHold" />
<event controller_action="sales_order_massUnhold" action_alias="massUnhold" />
<event controller_action="adminhtml_order_shipment_addTrack" action_alias="save" />
<event controller_action="sales_order_addComment" action_alias="addComment" />
<event controller_action="sales_order_invoice_addComment" action_alias="addComment" />
<event controller_action="sales_order_creditmemo_addComment" action_alias="addComment" />
<event controller_action="adminhtml_order_shipment_addComment" action_alias="addComment" />
</events>
<config>
<trackfield method="getOrderFieldData" />
<configpath constant="MODULE_ORDER" />
<editurl url="{{module}}/order/view/order_id/{{id}}" />
<itemfield field="increment_id" />
</config>
</module>
<module name="taxes">
<label translate="true">Taxes</label>
<models>
<class name="\Magento\Tax\Model\Calculation\Rule" />
</models>
<events>
<event controller_action="tax_rule_save" action_alias="save"/>
<event controller_action="tax_rule_edit" action_alias="edit"/>
<event controller_action="tax_rule_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getTaxRuleFieldData" />
<configpath constant="MODULE_ORDER" />
<editurl url="{{module}}/{{controller}}/edit/rule/{{id}}" />
<itemfield field="code" />
</config>
</module>
<module name="tax_rate">
<label translate="true">Tax Rate</label>
<models>
<class name="Magento\Tax\Model\Calculation\Rate" />
</models>
<events>
<event controller_action="tax_rate_save" action_alias="save" />
<event controller_action="tax_rate_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getTaxRateFieldData" />
<configpath constant="MODULE_ORDER" />
<editurl url="{{module}}/{{controller}}/edit/rate/{{id}}" />
<itemfield field="code" />
</config>
</module>
<module name="seo_url_rewrites">
<label translate="true">SEO URL Rewrites</label>
<models>
<class name="Magento\UrlRewrite\Model\UrlRewrite" />
</models>
<events>
<event controller_action="adminhtml_url_rewrite_save" action_alias="save" />
<event controller_action="adminhtml_url_rewrite_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getUrlRewriteFieldData" />
<configpath constant="MODULE_SEO" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="entity_type" />
</config>
</module>
<module name="seo_search_term">
<label translate="true">SEO Search Term</label>
<models>
<class name="Magento\Search\Model\Query" />
</models>
<events>
<event controller_action="search_term_save" action_alias="save" />
<event controller_action="search_term_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getSearchTermFieldData" />
<configpath constant="MODULE_SEO" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="query_text" />
</config>
</module>
<module name="seo_search_synonyms">
<label translate="true">SEO Search Synonyms</label>
<models>
<class name="Magento\Search\Model\SynonymGroup" />
</models>
<events>
<event controller_action="search_synonyms_save" action_alias="save" />
<event controller_action="search_synonyms_delete" action_alias="delete" />
<event controller_action="search_synonyms_massDelete" action_alias="massDelete" />
</events>
<config>
<trackfield method="getSearchSynonymsFieldData" />
<configpath constant="MODULE_SEO" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="group_id" />
</config>
</module>
<module name="seo_sitemap">
<label translate="true">SEO Sitemap</label>
<models>
<class name="Magento\Sitemap\Model\Sitemap" />
</models>
<events>
<event controller_action="adminhtml_sitemap_save" action_alias="save" />
<event controller_action="adminhtml_sitemap_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getSitemapFieldData" />
<configpath constant="MODULE_SEO" />
<editurl url="{{module}}/{{controller}}/edit/sitemap_id/{{id}}" />
<itemfield field="sitemap_filename" />
</config>
</module>
<module name="checkout_agreement">
<label translate="true">Terms and Conditions</label>
<models>
<class name="Magento\CheckoutAgreements\Model\Agreement" />
</models>
<events>
<event controller_action="checkout_agreement_save" action_alias="save" />
<event controller_action="checkout_agreement_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getCheckoutAgreementFieldData" />
<configpath constant="MODULE_SYSTEM_CONFIG" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="name" />
</config>
</module>
<module name="order_status">
<label translate="true">Order Status</label>
<models>
<class name="Magento\Sales\Model\Order\Status" />
<class name="Magento\Sales\Model\ResourceModel\Order\Status" />
</models>
<events>
<event controller_action="sales_order_status_save" action_alias="save" />
<event controller_action="sales_order_status_assignPost" action_alias="assign" />
<event controller_action="sales_order_status_unassign" action_alias="unassign" />
</events>
<config>
<trackfield method="getOrderStatusFieldData" />
<configpath constant="MODULE_SYSTEM_CONFIG" />
<editurl url="{{module}}/{{controller}}/edit/status/{{id}}" />
<itemfield field="label" />
</config>
</module>
<module name="api_integration">
<label translate="true">API Integration</label>
<models>
<class name="Magento\Integration\Model\Integration" />
</models>
<events>
<event controller_action="adminhtml_integration_save" action_alias="save" />
<event controller_action="adminhtml_integration_delete" action_alias="delete" />
</events>
<config>
<trackfield method="getIntegrationFieldData" />
<configpath constant="MODULE_SYSTEM_CONFIG" />
<editurl url="{{module}}/{{controller}}/edit/id/{{id}}" />
<itemfield field="name" />
</config>
</module>
</modules>
</config>
\ No newline at end of file
<?xml version="1.0" ?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="config">
<xs:complexType>
<xs:all>
<xs:element name="actions" type="adminActions" minOccurs="0" />
<xs:element name='modules' type="adminModules" minOccurs="1" />
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="adminActions">
<xs:sequence>
<xs:element name="action" type="adminAction" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="adminAction">
<xs:sequence>
<xs:element name="label" type="actionLabel" minOccurs="1" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="id" type="xs:ID" use="required"/>
</xs:complexType>
<xs:complexType name="adminModules">
<xs:sequence>
<xs:element name="module" type="adminModule" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="adminModule">
<xs:all>
<xs:element name="label" type="actionLabel" minOccurs="0" maxOccurs="1" />
<xs:element name="models" type="modelClass" minOccurs="0" />
<xs:element name="events" type="modelEvents" minOccurs="0" />
<xs:element name="config" type="configEvents" minOccurs="0" />
</xs:all>
<xs:attribute name="name" type="xs:token" use="required"/>
</xs:complexType>
<xs:complexType name="actionLabel">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="translate" use="optional" fixed="true" type="xs:boolean"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="modelClass">
<xs:sequence>
<xs:element name="class" type="className" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="modelEvents">
<xs:sequence>
<xs:element name="event" type="eventType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="configEvents">
<xs:sequence>
<xs:element name="trackfield" type="classMethod" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="configpath" type="modelConstant" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="editurl" type="editurl" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="itemfield" type="field" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="classMethod">
<xs:attribute name="method" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="modelConstant">
<xs:attribute name="constant" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="editurl">
<xs:attribute name="url" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="field">
<xs:attribute name="field" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="eventType">
<xs:attribute name="controller_action" type="xs:token" use="required" />
<xs:attribute name="action_alias" type="xs:token" use="required" />
<xs:attribute name="post_dispatch" type="xs:token" />
</xs:complexType>
<xs:complexType name="className">
<xs:attribute name="name" type="xs:token" use="required" />
</xs:complexType>
</xs:schema>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\App\Action\AbstractAction">
<plugin name="app_action" type="KiwiCommerce\AdminActivity\Plugin\App\Action" sortOrder="1"/>
</type>
<type name="Magento\User\Model\ResourceModel\User">
<plugin name="app_action" type="KiwiCommerce\AdminActivity\Plugin\User\Delete" sortOrder="1"/>
</type>
<type name="Magento\Backend\Model\Auth">
<plugin name="logout_auth" type="KiwiCommerce\AdminActivity\Plugin\Auth" sortOrder="1" />
</type>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="controller_action_postdispatch">
<observer name="admin_activity_controller_action_postdispatch" instance="KiwiCommerce\AdminActivity\Observer\PostDispatch" />
</event>
<event name="model_save_before">
<observer name="admin_activity_model_save_before" instance="KiwiCommerce\AdminActivity\Observer\SaveBefore" />
</event>
<event name="model_save_after">
<observer name="admin_activity_model_save_after" instance="KiwiCommerce\AdminActivity\Observer\SaveAfter" />
</event>
<event name="model_delete_after">
<observer name="admin_activity_model_delete_after" instance="KiwiCommerce\AdminActivity\Observer\DeleteAfter" />
</event>
<event name="backend_auth_user_login_success">
<observer name="admin_login_activity" instance="KiwiCommerce\AdminActivity\Observer\LoginSuccess" />
</event>
<event name="backend_auth_user_login_failed">
<observer name="admin_login_activity" instance="KiwiCommerce\AdminActivity\Observer\LoginFailed" />
</event>
</config>
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="KiwiCommerce_AdminActivity::activity_head" title="Admin Activity by KiwiCommerce" module="KiwiCommerce_AdminActivity" sortOrder="100" parent="Magento_Backend::system" resource="KiwiCommerce_AdminActivity::activity_head" />
<add id="KiwiCommerce_AdminActivity::activity" title="Admin Activity" module="KiwiCommerce_AdminActivity" sortOrder="10" parent="KiwiCommerce_AdminActivity::activity_head" action="adminactivity/activity" resource="KiwiCommerce_AdminActivity::activity" />
<add id="KiwiCommerce_AdminActivity::login_activity" title="Login Activity" module="KiwiCommerce_AdminActivity" sortOrder="20" parent="KiwiCommerce_AdminActivity::activity_head" action="adminactivity/login" resource="KiwiCommerce_AdminActivity::login_activity" />
<add id="KiwiCommerce_AdminActivity::configuration" title="Configuration" module="KiwiCommerce_AdminActivity" sortOrder="40" parent="KiwiCommerce_AdminActivity::activity_head" action="adminhtml/system_config/edit/section/admin_activity" resource="KiwiCommerce_AdminActivity::configuration"/>
</menu>
</config>
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="adminactivity" frontName="adminactivity">
<module name="KiwiCommerce_AdminActivity" before="Magento_Backend" />
</route>
</router>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="kiwicommerce" translate="label" sortOrder="9999">
<label><![CDATA[KiwiCommerce Extensions]]></label>
</tab>
<section id="admin_activity" translate="label" sortOrder="130" showInDefault="1" showInWebsite="0" showInStore="0">
<class>separator-top</class>
<label>Admin Activity</label>
<tab>kiwicommerce</tab>
<resource>KiwiCommerce_AdminActivity::activityConfig</resource>
<group id="hint" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
<frontend_model>KiwiCommerce\AdminActivity\Block\Adminhtml\System\Config\Fieldset\Hint</frontend_model>
</group>
<group id="general" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>General Configuration</label>
<field id="enable" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="login_activity" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Enable Login Activity</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="page_visit" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Enable Page Visit History</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="clearlog" translate="label comment" type="text" sortOrder="2" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Clear Admin Activity Logs After</label>
<comment>Clear all admin activity logs after this days</comment>
</field>
</group>
<group id="module" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Allow Module</label>
<field id="order" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Order</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="product" translate="label" type="select" sortOrder="2" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Product</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="category" translate="label" type="select" sortOrder="3" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Category</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="customer" translate="label" type="select" sortOrder="4" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Customer</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="promotion" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Promotion</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="email" translate="label" type="select" sortOrder="6" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Email Templates</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="page" translate="label" type="select" sortOrder="7" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Page</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="block" translate="label" type="select" sortOrder="8" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Block</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="widget" translate="label" type="select" sortOrder="9" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Widget</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="theme" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Theme</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="system_config" translate="label" type="select" sortOrder="11" showInDefault="1" showInWebsite="0" showInStore="0">
<label>System Configuration</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="attibute" translate="label" type="select" sortOrder="12" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Product Attributes</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="admin_user" translate="label" type="select" sortOrder="13" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Admin user</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="seo" translate="label" type="select" sortOrder="14" showInDefault="1" showInWebsite="0" showInStore="0">
<label>SEO</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
</system>
</config>
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<admin_activity>
<general>
<enable>1</enable>
<login_activity>1</login_activity>
<page_visit>1</page_visit>
<clearlog>7</clearlog>
</general>
<module>
<order>1</order>
<product>1</product>
<category>1</category>
<customer>1</customer>
<promotion>1</promotion>
<email>1</email>
<page>1</page>
<block>1</block>
<widget>1</widget>
<theme>1</theme>
<system_config>1</system_config>
<attibute>1</attibute>
<admin_user>1</admin_user>
<seo>1</seo>
</module>
</admin_activity>
</default>
</config>
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="kiwicommerce_admin_activity_clearlog" instance="KiwiCommerce\AdminActivity\Cron\ClearLog" method="execute">
<schedule>0 3 * * *</schedule>
</job>
</group>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!-- Create our type ActivityRepositoryInterface-->
<preference for="KiwiCommerce\AdminActivity\Api\ActivityRepositoryInterface" type="KiwiCommerce\AdminActivity\Model\ActivityRepository" />
<preference for="KiwiCommerce\AdminActivity\Api\LoginRepositoryInterface" type="KiwiCommerce\AdminActivity\Model\LoginRepository" />
<preference for="KiwiCommerce\AdminActivity\Api\Data\ActivitySearchResultsInterface" type="Magento\Framework\Api\SearchResults" />
<!-- Type for admin_activity_listing_data_source -->
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="admin_activity_listing_data_source" xsi:type="string">KiwiCommerce\AdminActivity\Model\ResourceModel\Grid\Activity\Collection</item>
<item name="login_activity_listing_data_source" xsi:type="string">KiwiCommerce\AdminActivity\Model\ResourceModel\Grid\Login\Collection</item>
</argument>
</arguments>
</type>
<virtualType name="KiwiCommerce\AdminActivity\Model\ResourceModel\Grid\Activity\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">kiwicommerce_activity</argument>
<argument name="resourceModel" xsi:type="string">KiwiCommerce\AdminActivity\Model\ResourceModel\Activity</argument>
</arguments>
</virtualType>
<virtualType name="KiwiCommerce\AdminActivity\Model\ResourceModel\Grid\Login\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">kiwicommerce_login_activity</argument>
<argument name="resourceModel" xsi:type="string">KiwiCommerce\AdminActivity\Model\ResourceModel\Login</argument>
</arguments>
</virtualType>
<virtualType name="AAConfigReader" type="Magento\Framework\Config\Reader\Filesystem">
<arguments>
<argument name="converter" xsi:type="object">KiwiCommerce\AdminActivity\Model\Config\Converter</argument>
<argument name="schemaLocator" xsi:type="object">KiwiCommerce\AdminActivity\Model\Config\SchemaLocator</argument>
<argument name="fileName" xsi:type="string">adminactivity.xml</argument>
<argument name="idAttributes" xsi:type="array">
<item name="/config/modules/module" xsi:type="string">name</item>
</argument>
</arguments>
</virtualType>
<!-- AdminActivity Logger and Handler -->
<type name="KiwiCommerce\AdminActivity\Logger\Handler">
<arguments>
<argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
</arguments>
</type>
<type name="KiwiCommerce\AdminActivity\Logger\Logger">
<arguments>
<argument name="name" xsi:type="string">adminactivityLogHandler</argument>
<argument name="handlers" xsi:type="array">
<item name="system" xsi:type="object">KiwiCommerce\AdminActivity\Logger\Handler</item>
</argument>
</arguments>
</type>
<type name="KiwiCommerce\AdminActivity\Model\Config\Data">
<arguments>
<argument name="reader" xsi:type="object">AAConfigReader</argument>
<argument name="cacheId" xsi:type="string">KiwiCommerce_admin_activity_cache</argument>
</arguments>
</type>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="KiwiCommerce_AdminActivity" setup_version="1.0.7"/>
</config>
KiwiCommerce,KiwiCommerce
"Admin Activity","Admin Activity"
"Login Activity","Login Activity"
actions,actions
"Something went wrong, please try again","Something went wrong, please try again"
"Activity data has already been reverted","Activity data has already been reverted"
"Activity data has been reverted successfully","Activity data has been reverted successfully"
"Real ip address if visitor used proxy","Real ip address if visitor used proxy"
"Scope of activity","Scope of activity"
"Reason for failed","Reason for failed"
"All Store Views","All Store Views"
View,View
"Activity Log","Activity Log"
Back,Back
Revert,Revert
New,New
Edit,Edit
Delete,Delete
Orders,Orders
"Catalog Products","Catalog Products"
"Catalog Categories","Catalog Categories"
Customer,Customer
"Customer Group","Customer Group"
"Catalog Promotion","Catalog Promotion"
"Cart Promotion","Cart Promotion"
Email,Email
"Cms Pages","Cms Pages"
"Cms Blocks","Cms Blocks"
"Cms Widget","Cms Widget"
Themes,Themes
"System Configuration","System Configuration"
"Product Attributes","Product Attributes"
"Admin User","Admin User"
"General Configuration","General Configuration"
Enable,Enable
"Enable Login Activity","Enable Login Activity"
"Clear Admin Activity Logs After","Clear Admin Activity Logs After"
"Clear all admin activity logs after this days","Clear all admin activity logs after this days"
"Allow Module","Allow Module"
Order,Order
Product,Product
Category,Category
Promotion,Promotion
"Email Templates","Email Templates"
Page,Page
Block,Block
Widget,Widget
Theme,Theme
"Admin user","Admin user"
"Store View","Store View"
All,All
"Action Type","Action Type"
Date,Date
Username,Username
Name,Name
"Activity Type","Activity Type"
Module,Module
IP,IP
Item,Item
Type,Type
"IP Address","IP Address"
"User Agent","User Agent"
Status,Status
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'KiwiCommerce_AdminActivity',
__DIR__
);
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="KiwiCommerce_AdminActivity::css/activity-view.css"/>
</head>
<body>
<referenceContainer name="js">
<block class="KiwiCommerce\AdminActivity\Block\Adminhtml\Selector" template="KiwiCommerce_AdminActivity::activity/js.phtml" name="activity.view.model.js"/>
</referenceContainer>
<referenceContainer name="content">
<uiComponent name="admin_activity_listing"/>
</referenceContainer>
</body>
</page>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<uiComponent name="login_activity_listing"/>
</referenceContainer>
</body>
</page>
\ No newline at end of file
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
?>
<script>
require([
"jquery",
"Magento_Ui/js/modal/modal",
'mage/backend/notification',
"prototype"
], function(jQuery, modal, notification) {
//<![CDATA[
Window.keepMultiModalWindow = true;
var adminActivityLogView = {
overlayShowEffectOptions : null,
overlayHideEffectOptions : null,
modal: null,
activityId: 0,
open : function(editorUrl, elementId, revertable) {
if (editorUrl && elementId) {
jQuery.ajax({
url: editorUrl,
data: {
id: elementId
},
showLoader: true,
dataType: 'html',
success: function(data, textStatus, transport) {
this.openDialogWindow(data, elementId, revertable);
}.bind(this)
});
}
},
openDialogWindow : function(data, elementId, revertable) {
var self = this;
this.activityId = elementId;
if (this.modal) {
this.modal.html(jQuery(data).html());
} else {
this.modal = jQuery(data).modal({
title: '<?= /* @escapeNotVerified */ __('Activity Log'); ?>',
modalClass: 'magento',
type: 'slide',
firedElementId: elementId,
buttons: [{
text: jQuery.mage.__('Back'),
class: 'action- scalable back',
click: function () {
self.closeDialogWindow(this);
}
},{
text: jQuery.mage.__('Revert'),
class: 'action- scalable action-primary action-revert-activity',
click: function () {
self.revertDialogWindow(this);
}
}],
close: function () {
self.closeDialogWindow(this);
}
});
}
jQuery(".action-revert-activity").hide();
if(revertable == 1) {
jQuery(".action-revert-activity").show();
}
this.modal.modal('openModal');
this.autoResize();
},
revertDialogWindow : function(dialogWindow) {
var self = this;
jQuery.ajax({
type: 'POST',
url: '<?= /* @escapeNotVerified */ $block->getRevertUrl(); ?>',
data: {
id: this.activityId,
form_key: '<?= /* @escapeNotVerified */ $block->getFormKey(); ?>'
},
dataType: 'json',
showLoader: true
})
.success(function (data) {
if (!data.error) {
self.closeDialogWindow(dialogWindow);
window.location.reload();
} else {
self.error(data.message);
}
});
},
closeDialogWindow : function(dialogWindow) {
jQuery('body').trigger('processStop');
dialogWindow.closeModal();
Windows.overlayShowEffectOptions = this.overlayShowEffectOptions;
Windows.overlayHideEffectOptions = this.overlayHideEffectOptions;
},
error: function (message) {
jQuery('body').notification('clear')
.notification('add', {
error: true,
message: jQuery.mage.__(message),
insertMethod: function (message) {
var $wrapper = jQuery('<div/>').html(message);
jQuery('.page-main-actions').after($wrapper);
}
});
},
autoResize: function () {
jQuery.each(jQuery('textarea.value-container'), function() {
var offset = this.offsetHeight - this.clientHeight;
var resizeTextarea = function(el) {
console.log('You clicked me!!');
jQuery(el).css('height', 'auto').css('height', el.scrollHeight + offset);
};
jQuery(this).unbind().on('click', function() { resizeTextarea(this); }).trigger('click');
});
}
};
window.adminActivityLogView = adminActivityLogView;
//]]>
});
</script>
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
$collection = $block->getLogListing();
$adminDetails = $block->getAdminDetails();
?>
<table border="0" width="100%" cellspacing="0" cellpadding="0">
<tr>
<td>
<table border="0" width="100%" cellspacing="1" cellpadding="1">
<tr style="height: 35px;text-indent: 10px;">
<td width="10%" style="font-size: 16px;font-weight: 600;">Admin</td>
<td width="1%" style="font-size: 16px;font-weight: 600;">:</td>
<td><?php if (!empty($adminDetails['username'])) {
echo $adminDetails['username'];
if (!empty($adminDetails['name'])) {
echo " (". ucwords(strtolower($adminDetails['name'])) .") ";
}
}
?></td>
</tr>
<tr style="height: 35px;text-indent: 10px;">
<td style="font-size: 16px;font-weight: 600;">Module</td>
<td width="1%" style="font-size: 16px;font-weight: 600;">: </td>
<td><?php echo $adminDetails['module']; ?></td>
</tr>
<tr style="height: 35px;text-indent: 10px;">
<td style="font-size: 16px;font-weight: 600;">Action</td>
<td width="1%" style="font-size: 16px;font-weight: 600;">: </td>
<td><?php echo $adminDetails['fullaction']; ?> </td>
</tr>
<tr style="height: 35px;text-indent: 10px;">
<td style="font-size: 16px;font-weight: 600;">User Agent</td>
<td width="1%" style="font-size: 16px;font-weight: 600;">: </td>
<td style="text-indent: 0px;padding-left: 10px;"><?php echo $adminDetails['browser']; ?></td>
</tr>
<tr style="height: 35px;text-indent: 10px;">
<td style="font-size: 16px;font-weight: 600;">Date</td>
<td width="1%" style="font-size: 16px;font-weight: 600;">: </td>
<td><?php echo $adminDetails['date']; ?></td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="height: 35px;"></td>
</tr>
<?php if (!empty($collection)) { ?>
<tr>
<td>
<table border="1" width="100%" cellspacing="1" cellpadding="1">
<tr style="font-size: 16px;height: 50px;">
<th width="20%">Field Name</th>
<th width="40%">Old Value</th>
<th width="40%">New Value</th>
</tr>
<?php foreach ($collection as $item) { ?>
<tr style="height:45px; text-indent:10px;">
<td>
<?php $name = str_replace('_',' ',$item["field_name"]); echo ucfirst($name); ?>
</td>
<td>
<textarea class="value-container" readonly><?php if (!$block->activityRepository->isFieldProtected($item['field_name'])) { echo $block->escapeHtml($item['old_value']); } ?></textarea>
</td>
<td>
<textarea class="value-container" readonly><?php if (!$block->activityRepository->isFieldProtected($item['field_name'])) { echo $block->escapeHtml($item['new_value']); } ?></textarea>
</td>
</tr>
<?php } ?>
</table>
</td>
</tr>
<?php } ?>
</table>
<?php
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customise this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
?>
<div style="background:#EAF0EE;border:1px solid #CCCCCC;margin-bottom:10px;padding:11px 0 0 10px;">
<h4>
<img style="padding-left: 15px;" src="<?php echo $block->getViewFileUrl('KiwiCommerce_AdminActivity::images/kiwicommerce-logo.svg') ?>"/><br><br>
<div style="padding-left: 15px;">
<p> <strong style="color:#EA7601;"><?php echo __('Admin Activity (ver.') ?><?php echo $this->getModuleVersion() ?><?php echo __(') - Developed by') ?></strong> <a style="color:#EA7601;" target="_blank" href="https://kiwicommerce.co.uk/"><strong>KiwiCommerce</strong></a></p>
<p><?php echo __('For technical support ') ?> <a style="color:#EA7601;" href="https://kiwicommerce.co.uk/extension-support" target="_blank"><?php echo __('Contact Us') ?></a> <?php echo __('or email us at') ?> <a style="color:#EA7601;" href="mailto:support@kiwicommerce.co.uk" target="_blank"><?php echo __('support@kiwicommerce.co.uk') ?></a></p>
</div>
</h4>
</div>
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<!-- Integration -->
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<!-- we define a provider -->
<item name="provider" xsi:type="string">admin_activity_listing.admin_activity_listing_data_source</item>
<!-- same string as above -->
<item name="deps" xsi:type="string">admin_activity_listing.admin_activity_listing_data_source</item>
</item>
<!-- define column type -->
<item name="spinner" xsi:type="string">admin_activity_columns</item>
</argument>
<!-- Data source -->
<dataSource name="admin_activity_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Customer\Ui\Component\DataProvider</argument>
<argument name="name" xsi:type="string">admin_activity_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="update_url" xsi:type="url" path="mui/index/render"/>
</item>
</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
</item>
</argument>
</dataSource>
<!-- Container Listing Top -->
<container name="listing_top">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">ui/grid/toolbar</item>
</item>
</argument>
<!-- Button to manage views -->
<bookmark name="bookmarks">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="namespace" xsi:type="string">admin_activity_listing</item>
</item>
</item>
</argument>
</bookmark>
<!-- Button to manage columns -->
<container name="columns_controls">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
<item name="displayArea" xsi:type="string">dataGridActions</item>
<item name="columnsData" xsi:type="array">
<item name="provider" xsi:type="string">admin_activity_listing.admin_activity_listing.admin_activity_columns</item>
</item>
</item>
</argument>
</container>
<!-- Filters -->
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsProvider" xsi:type="string">admin_activity_listing.admin_activity_listing.admin_activity_columns</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">admin_activity_listing.admin_activity_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.filters</item>
</item>
</item>
</argument>
<filterSelect name="store_id">
<argument name="optionsProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Store\Ui\Component\Listing\Column\Store\Options</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="provider" xsi:type="string">admin_activity_listing.admin_activity_listing.listing_top.listing_filters</item>
<item name="dataScope" xsi:type="string">store_id</item>
<item name="caption" xsi:type="string" translate="true">All Store Views</item>
<item name="label" xsi:type="string" translate="true">Store View</item>
</item>
</argument>
</filterSelect>
<filterSelect name="action_type">
<argument name="optionsProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\ActionType\Options</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="provider" xsi:type="string">admin_activity_listing.admin_activity_listing.listing_top.listing_filters</item>
<item name="dataScope" xsi:type="string">action_type</item>
<item name="caption" xsi:type="string" translate="true">All</item>
<item name="label" xsi:type="string" translate="true">Action Type</item>
</item>
</argument>
</filterSelect>
</filters>
<!-- Paging -->
<paging name="listing_paging">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">admin_activity_listing.admin_activity_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.paging</item>
</item>
<item name="selectProvider" xsi:type="string">admin_activity_listing.admin_activity_listing.admin_activity_columns.ids</item>
</item>
</argument>
</paging>
</container>
<!-- Columns -->
<columns name="admin_activity_columns">
<!-- Date Column -->
<column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="sorting" xsi:type="string">desc</item>
<item name="sortable" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">date</item>
<item name="label" xsi:type="string" translate="true">Date</item>
</item>
</argument>
</column>
<!-- Username Column -->
<column name="username">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Username</item>
</item>
</argument>
</column>
<!-- Name Column -->
<column name="name">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">false</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Name</item>
</item>
</argument>
</column>
<!-- Activity Type Column -->
<column name="action_type" class="KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\ActionTypeColumn">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">false</item>
<item name="label" translate="true" xsi:type="string">Activity Type</item>
</item>
</argument>
</column>
<!-- Store Column -->
<column name="store_id" class="KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\StoreColumn">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">true</item>
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="label" translate="true" xsi:type="string">Store View</item>
</item>
</argument>
</column>
<!-- Module Column -->
<column name="module">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Module</item>
</item>
</argument>
</column>
<!-- Fullaction Column -->
<column name="fullaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Full Action</item>
</item>
</argument>
</column>
<!-- IP Column -->
<column name="remote_ip">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">IP</item>
</item>
</argument>
</column>
<!-- Item Column -->
<column name="item_name" class="KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\ItemColumn">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="filter" xsi:type="string">text</item>
<item name="label" translate="true" xsi:type="string">Item</item>
</item>
</argument>
</column>
<!-- Revert Status Column -->
<actionsColumn name="revertable" class="KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\RevertStatusColumn">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="urlEntityParamName" xsi:type="string">id</item>
<item name="label" translate="true" xsi:type="string">Revert</item>
</item>
</argument>
</actionsColumn>
<!-- Action Type Column -->
<actionsColumn name="entity_id" class="KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\ViewAction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="viewUrlPath" xsi:type="string">adminactivity/Activity/Log</item>
<item name="urlEntityParamName" xsi:type="string">id</item>
</item>
</argument>
</actionsColumn>
</columns>
</listing>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<!-- Integration -->
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<!-- we define a provider -->
<item name="provider" xsi:type="string">login_activity_listing.login_activity_listing_data_source</item>
<!-- same string as above -->
<item name="deps" xsi:type="string">login_activity_listing.login_activity_listing_data_source</item>
</item>
<!-- define column type -->
<item name="spinner" xsi:type="string">login_activity_columns</item>
</argument>
<!-- Data source -->
<dataSource name="login_activity_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Customer\Ui\Component\DataProvider</argument>
<argument name="name" xsi:type="string">login_activity_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="update_url" xsi:type="url" path="mui/index/render"/>
</item>
</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
</item>
</argument>
</dataSource>
<!-- Container Listing Top -->
<container name="listing_top">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">ui/grid/toolbar</item>
</item>
</argument>
<!-- Button to manage views -->
<bookmark name="bookmarks">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="namespace" xsi:type="string">login_activity_listing</item>
</item>
</item>
</argument>
</bookmark>
<!-- Button to manage columns -->
<container name="columns_controls">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
<item name="displayArea" xsi:type="string">dataGridActions</item>
<item name="columnsData" xsi:type="array">
<item name="provider" xsi:type="string">login_activity_listing.login_activity_listing.login_activity_columns</item>
</item>
</item>
</argument>
</container>
<!-- Filters -->
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsProvider" xsi:type="string">login_activity_listing.login_activity_listing.login_activity_columns</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">login_activity_listing.login_activity_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.filters</item>
</item>
</item>
</argument>
</filters>
<!-- Paging -->
<paging name="listing_paging">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">login_activity_listing.login_activity_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.paging</item>
</item>
<item name="selectProvider" xsi:type="string">login_activity_listing.login_activity_listing.login_activity_columns.ids</item>
</item>
</argument>
</paging>
</container>
<!-- Columns -->
<columns name="login_activity_columns">
<!-- Date Column -->
<column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="sorting" xsi:type="string">desc</item>
<item name="sortable" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">date</item>
<item name="label" xsi:type="string" translate="true">Date</item>
</item>
</argument>
</column>
<!-- Activity Type -->
<column name="type">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Type</item>
</item>
</argument>
</column>
<!-- Username Column -->
<column name="username">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Username</item>
</item>
</argument>
</column>
<!-- Name Column -->
<column name="name">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">false</item>
<item name="label" xsi:type="string" translate="true">Name</item>
</item>
</argument>
</column>
<!-- IP Column -->
<column name="remote_ip">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">IP Address</item>
</item>
</argument>
</column>
<!-- User Agent -->
<column name="user_agent" class="KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\UserAgentColumn">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="label" xsi:type="string" translate="true">User Agent</item>
</item>
</argument>
</column>
<!-- Status Action-->
<actionsColumn name="status" class="KiwiCommerce\AdminActivity\Ui\Component\Listing\Column\StatusColumn">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="urlEntityParamName" xsi:type="string">id</item>
<item name="label" xsi:type="string" translate="true">Status</item>
</item>
</argument>
</actionsColumn>
</columns>
</listing>
\ No newline at end of file
/**
* KiwiCommerce
*
* Do not edit or add to this file if you wish to upgrade to newer versions in the future.
* If you wish to customize this module for your needs.
* Please contact us https://kiwicommerce.co.uk/contacts.
*
* @category KiwiCommerce
* @package KiwiCommerce_AdminActivity
* @copyright Copyright (C) 2018 Kiwi Commerce Ltd (https://kiwicommerce.co.uk/)
* @license https://kiwicommerce.co.uk/magento2-extension-license/
*/
textarea.value-container {
resize: none;
width: 95%;
border: none;
background: transparent;
box-shadow: none;
height: auto;
outline: none;
display:block;
overflow:hidden;
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="16px" viewBox="0 0 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 49.2 (51160) - http://www.bohemiancoding.com/sketch -->
<title>Group 5</title>
<desc>Created with Sketch.</desc>
<defs>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-1"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-3"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-5"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-7"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-9"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-11"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-13"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-15"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-17"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-19"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-21"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-23"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-25"></path>
<path d="M11.7289335,0.335223301 L0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301" id="path-27"></path>
<path d="M0.965762343,6.52706796 C-0.126896323,7.15557282 -0.137790687,8.74609709 0.946428683,9.38998058 L11.6060267,15.719301 C12.6900926,16.3630291 14.0560311,15.5773204 14.0646238,14.3047767 L14.1496305,1.77242718 C14.1560751,0.810873786 13.3778185,0.118679612 12.5272909,0.118524272 C12.2609161,0.118524272 11.9876363,0.186407767 11.7289335,0.335223301 L0.965762343,6.52706796 Z" id="path-29"></path>
<path d="M16.0507124,6.65241165 L15.6224565,6.47361553 C15.4443106,6.39905243 15.2388521,6.45326602 15.1190141,6.60612039 L14.8310039,6.97334369 C14.6844671,7.16052816 14.4170181,7.19408155 14.2296657,7.04914951 L13.8617124,6.76410097 C13.7085776,6.64542136 13.4963676,6.64386796 13.3415449,6.76021748 L12.9694487,7.03951845 C12.7801016,7.18180971 12.5129595,7.14421748 12.3691846,6.95501359 L12.0866983,6.58344078 C11.9690085,6.42872233 11.7644707,6.37140194 11.5850973,6.44332427 L11.1543863,6.61575146 C10.9349646,6.70351845 10.6866958,6.59726602 10.5961652,6.37683883 L10.4183262,5.94375146 C10.3443673,5.76340194 10.1611579,5.65466408 9.96966257,5.67703301 L9.50949077,5.73062524 C9.27518523,5.75796505 9.06251497,5.59019806 9.03151974,5.35361553 L8.97029648,4.8886835 C8.94482515,4.6951301 8.79598666,4.54212039 8.60525857,4.51353786 L8.14692808,4.44472233 C7.91369662,4.40977087 7.75104837,4.19198447 7.78158328,3.95540194 L7.84142556,3.49031456 C7.86628312,3.29660583 7.76163585,3.10973204 7.58456408,3.03221748 L7.15953045,2.84565437 C6.94333103,2.75089709 6.84175259,2.49784854 6.93166946,2.27726602 L7.10843435,1.84371262 C7.18193294,1.66320777 7.12868866,1.45520777 6.9773951,1.33388738 L6.61465881,1.0424699 C6.42991495,0.894120388 6.39661809,0.623207767 6.54008612,0.433693204 L6.82149828,0.0610330097 C6.93857433,-0.0939961165 6.94010875,-0.308831068 6.82533433,-0.465568932 L6.54929263,-0.842267961 C6.40873999,-1.03380194 6.44587289,-1.30424854 6.63276494,-1.44980194 L6.99995103,-1.73593786 C7.15277901,-1.85492816 7.20924557,-2.06215146 7.13835549,-2.24374369 L6.96803515,-2.67978252 C6.88134056,-2.90176311 6.98629472,-3.15310291 7.20402855,-3.2447534 L7.63182414,-3.42479223 C7.80981656,-3.49982136 7.91722578,-3.68514175 7.89528361,-3.87916117 L7.84219277,-4.34502524 C7.81518702,-4.58207379 7.98090411,-4.79737476 8.21474933,-4.82890874 L8.67384703,-4.89088932 C8.86503544,-4.91667573 9.01617556,-5.06735534 9.04456228,-5.26044272 L9.11238354,-5.72444272 C9.14690793,-5.96040388 9.36203325,-6.12506408 9.59587847,-6.0943068 L10.0552831,-6.03372427 C10.2464715,-6.00855922 10.4310619,-6.11465631 10.5077828,-6.29376311 L10.6919129,-6.72389903 C10.7858192,-6.9430835 11.0354689,-7.04560777 11.2535096,-6.95457864 L11.6816121,-6.77562718 C11.8599114,-6.70121942 12.0653699,-6.75543301 12.1853614,-6.90828738 L12.4732181,-7.27566602 C12.6197549,-7.46253981 12.8873573,-7.49624854 13.0745563,-7.35116117 L13.4425096,-7.06611262 C13.5956444,-6.94758835 13.8078544,-6.94603495 13.9628305,-7.06238447 L14.3347733,-7.34184078 C14.5242739,-7.4839767 14.7912625,-7.44638447 14.9350374,-7.25718058 L15.2175237,-6.88545243 C15.3352135,-6.73073398 15.5397514,-6.67372427 15.7191248,-6.74549126 L16.1498357,-6.91776311 C16.369104,-7.00568544 16.6173727,-6.89927767 16.7080568,-6.67885049 L16.8858958,-6.24591845 C16.9600081,-6.06556893 17.1429107,-5.95683107 17.3345594,-5.97904466 L17.7947312,-6.03279223 C18.0290368,-6.06013204 18.2415536,-5.89236505 18.2727023,-5.65562718 L18.3339255,-5.19085049 C18.3593969,-4.99729709 18.5083888,-4.84428738 18.6991169,-4.81570485 L19.1572939,-4.74704466 C19.3906788,-4.71193786 19.5530202,-4.49415146 19.5226387,-4.25741359 L19.4627964,-3.79248155 C19.4379389,-3.59877282 19.5427396,-3.41189903 19.7196579,-3.33438447 L20.1446916,-3.1479767 C20.3610444,-3.05306408 20.462316,-2.80017087 20.3723991,-2.57943301 L20.1957877,-2.14587961 C20.1222891,-1.96537476 20.1756868,-1.7575301 20.3266735,-1.63605437 L20.6895632,-1.34448155 C20.8744605,-1.19613204 20.9074505,-0.925374757 20.7642893,-0.735860194 L20.4828772,-0.36335534 C20.3656477,-0.208170874 20.3639598,0.00666407767 20.4788877,0.163557282 L20.7549294,0.539945631 C20.8953286,0.731790291 20.8581957,1.00208155 20.6713036,1.14763495 L20.304271,1.43361553 C20.1515964,1.55276117 20.0949764,1.75998447 20.1658665,1.9415767 L20.3361869,2.37746019 C20.4228814,2.59959612 20.3179273,2.85093592 20.1001935,2.94258641 L19.6725513,3.12262524 C19.4944054,3.19765437 19.3868428,3.38297476 19.4090918,3.57683883 L19.4618758,4.04270291 C19.4888815,4.28006214 19.3233179,4.49520777 19.0896261,4.52674175 L18.630375,4.58872233 C18.4391866,4.6143534 18.2880464,4.76534369 18.2596597,4.95843107 L18.1918385,5.42212039 C18.1573141,5.65839223 17.9421888,5.82289709 17.7083435,5.79213981 L17.2490924,5.73155728 C17.0577505,5.70623689 16.8731601,5.81248932 16.7964392,5.99144078 L16.6123091,6.42188738 C16.5185562,6.6409165 16.2687531,6.74344078 16.0507124,6.65241165" id="path-31"></path>
<filter x="-83.3%" y="-82.3%" width="266.6%" height="264.6%" filterUnits="objectBoundingBox" id="filter-32">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.768625453 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="UK-12-Containt-Pages" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-5">
<g id="Group-3-Copy">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-2"></g>
<path d="M32.0429634,10.7690718 C26.0855877,21.051635 13.0223247,24.4983146 2.86540184,18.4672466 C-7.29167448,12.4361786 -10.6960865,-0.788520388 -4.73871072,-11.0712388 C1.21866503,-21.3538019 14.281928,-24.8004816 24.4386974,-18.7692583 C34.5957737,-12.7383456 38.0001857,0.486508738 32.0429634,10.7690718" id="Fill-1" fill="#0052CC" mask="url(#mask-2)"></path>
</g>
<g id="Group-6-Copy">
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<g id="Clip-5"></g>
</g>
<g id="Group-9-Copy">
<mask id="mask-6" fill="white">
<use xlink:href="#path-5"></use>
</mask>
<g id="Clip-8"></g>
</g>
<g id="Group-12-Copy">
<mask id="mask-8" fill="white">
<use xlink:href="#path-7"></use>
</mask>
<g id="Clip-11"></g>
<path d="M8.90233713,7.28773592 C9.09306522,6.98342524 9.85336907,6.68874563 9.85336907,6.68874563 C9.85336907,6.68874563 9.914132,7.51080388 9.72340391,7.81511456 C9.53252238,8.11942524 9.19418333,8.24835728 8.96754987,8.10264854 C8.74060953,7.95709515 8.71160904,7.59220194 8.90233713,7.28773592" id="Fill-10" fill="#4B9AFF" mask="url(#mask-8)"></path>
</g>
<g id="Group-15-Copy">
<mask id="mask-10" fill="white">
<use xlink:href="#path-9"></use>
</mask>
<g id="Clip-14"></g>
<path d="M5.18002453,1.67425243 C5.52757008,1.59565049 6.27099533,1.93149515 6.27099533,1.93149515 C6.27099533,1.93149515 5.73978001,2.55627184 5.3923879,2.63502913 C5.04484235,2.71363107 4.71555636,2.56248544 4.65694162,2.29716505 C4.59832687,2.03184466 4.83247897,1.75300971 5.18002453,1.67425243" id="Fill-13" fill="#4B9AFF" mask="url(#mask-10)"></path>
</g>
<g id="Group-18-Copy-2">
<mask id="mask-12" fill="white">
<use xlink:href="#path-11"></use>
</mask>
<g id="Clip-17"></g>
</g>
<g id="Group-21-Copy">
<mask id="mask-14" fill="white">
<use xlink:href="#path-13"></use>
</mask>
<g id="Clip-20"></g>
</g>
<g id="Group-24-Copy">
<mask id="mask-16" fill="white">
<use xlink:href="#path-15"></use>
</mask>
<g id="Clip-23"></g>
<path d="M13.0566496,8.73933981 C13.0767505,8.37941748 13.5987593,7.74671845 13.5987593,7.74671845 C13.5987593,7.74671845 14.0475764,8.43456311 14.0274755,8.79448544 C14.0075281,9.15456311 13.7739898,9.43401942 13.5059271,9.41864078 C13.2378643,9.40341748 13.0367022,9.09926214 13.0566496,8.73933981" id="Fill-22" fill="#4B9AFF" mask="url(#mask-16)"></path>
</g>
<g id="Group-27-Copy">
<mask id="mask-18" fill="white">
<use xlink:href="#path-17"></use>
</mask>
<g id="Clip-26"></g>
<path d="M7.10373903,5.67456311 C7.36934669,5.43440777 8.18028631,5.3607767 8.18028631,5.3607767 C8.18028631,5.3607767 8.01717774,6.16854369 7.75172352,6.40869903 C7.48611586,6.64885437 7.12583464,6.67930097 6.94707501,6.47658252 C6.76800849,6.27386408 6.83828481,5.91487379 7.10373903,5.67456311" id="Fill-25" fill="#4B9AFF" mask="url(#mask-18)"></path>
</g>
<g id="Group-30-Copy">
<mask id="mask-20" fill="white">
<use xlink:href="#path-19"></use>
</mask>
<g id="Clip-29"></g>
<path d="M5.03497604,-0.75383301 C5.39050057,-0.733638835 6.0154688,-0.205172816 6.0154688,-0.205172816 C6.0154688,-0.205172816 5.33602875,0.249196117 4.98050423,0.229001942 C4.62482626,0.208652427 4.34878456,-0.0276194175 4.36397529,-0.298998058 C4.37916603,-0.570376699 4.67960496,-0.774027184 5.03497604,-0.75383301" id="Fill-28" fill="#4B9AFF" mask="url(#mask-20)"></path>
</g>
<g id="Group-33-Copy">
<mask id="mask-22" fill="white">
<use xlink:href="#path-21"></use>
</mask>
<g id="Clip-32"></g>
</g>
<g id="Group-36-Copy">
<mask id="mask-24" fill="white">
<use xlink:href="#path-23"></use>
</mask>
<g id="Clip-35"></g>
</g>
<g id="Group-39-Copy">
<mask id="mask-26" fill="white">
<use xlink:href="#path-25"></use>
</mask>
<g id="Clip-38"></g>
<path d="M10.8889781,8.28318447 C10.9979217,7.9398835 11.6603297,7.46066019 11.6603297,7.46066019 C11.6603297,7.46066019 11.9236358,8.2407767 11.8148456,8.58407767 C11.7060554,8.9272233 11.4105266,9.13817476 11.1548926,9.05506796 C10.8991052,8.9721165 10.7801879,8.6263301 10.8889781,8.28318447" id="Fill-37" fill="#4B9AFF" mask="url(#mask-26)"></path>
</g>
<g id="Group-42-Copy-2">
<mask id="mask-28" fill="white">
<use xlink:href="#path-27"></use>
</mask>
<g id="Clip-41"></g>
<path d="M5.8896926,3.80032621 C6.20624292,3.63535534 7.00951045,3.77096699 7.00951045,3.77096699 C7.00951045,3.77096699 6.65091709,4.51100583 6.33405989,4.67582136 C6.01750957,4.84063689 5.66121784,4.77834563 5.53846444,4.53648155 C5.41571105,4.29477282 5.57298884,3.96514175 5.8896926,3.80032621" id="Fill-40" fill="#4B9AFF" mask="url(#mask-28)"></path>
</g>
<g id="Group-46-Copy-6">
<mask id="mask-30" fill="white">
<use xlink:href="#path-29"></use>
</mask>
<g id="Clip-45"></g>
<g id="Fill-44" mask="url(#mask-30)">
<use fill="black" fill-opacity="1" filter="url(#filter-32)" xlink:href="#path-31"></use>
<use fill="#4B9AFF" fill-rule="evenodd" xlink:href="#path-31"></use>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="110px" height="36px" viewBox="0 0 110 36" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 49.2 (51160) - http://www.bohemiancoding.com/sketch -->
<title>KiwiCommerce Logo</title>
<desc>KiwiCommerce Logo</desc>
<defs>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-1"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-3"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-5"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-7"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-9"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-11"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-13"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-15"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-17"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-19"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-21"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-23"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-25"></path>
<path d="M26.3901005,0.754252427 L2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427" id="path-27"></path>
<path d="M2.17296527,14.6859029 C-0.285516727,16.1000388 -0.310029046,19.6787184 2.12946454,21.1274563 L26.1135601,35.3684272 C28.5527084,36.8168155 31.6260699,35.0489709 31.6454035,32.1857476 L31.8366687,3.98796117 C31.8511689,1.82446602 30.1000917,0.267029126 28.1864046,0.266679612 C27.5870612,0.266679612 26.9721817,0.419417476 26.3901005,0.754252427 L2.17296527,14.6859029 Z" id="path-29"></path>
<path d="M36.1141028,14.9679262 L35.150527,14.565635 C34.7496988,14.397868 34.2874172,14.5198485 34.0177817,14.8637709 L33.3697588,15.6900233 C33.0400509,16.1111883 32.4382907,16.1866835 32.0167479,15.8605864 L31.188853,15.2192272 C30.8442995,14.9521981 30.3668272,14.9487029 30.0184761,15.2104893 L29.1812595,15.8389165 C28.7552285,16.1590718 28.1541589,16.0744893 27.8306653,15.6487806 L27.1950712,14.8127417 C26.9302691,14.4646252 26.470059,14.3356544 26.0664688,14.4974796 L25.0973691,14.8854408 C24.6036703,15.0829165 24.0450656,14.8438485 23.8413717,14.3478874 L23.441234,13.3734408 C23.2748264,12.9676544 22.8626052,12.7229942 22.4317408,12.7733243 L21.3963542,12.8939068 C20.8691668,12.9554214 20.3906587,12.5779456 20.3209194,12.045635 L20.1831671,10.9995379 C20.1258566,10.5640427 19.79097,10.2197709 19.3618318,10.1554602 L18.3305882,10.0006252 C17.8058174,9.92198447 17.4398588,9.43196505 17.5085624,8.89965437 L17.6432075,7.85320777 C17.699137,7.41736311 17.4636807,6.99689709 17.0652692,6.82248932 L16.1089435,6.40272233 C15.6224948,6.18951845 15.3939433,5.62015922 15.5962563,5.12384854 L15.9939773,4.1483534 C16.1593491,3.74221748 16.0395495,3.27421748 15.699139,3.0012466 L14.8829823,2.34555728 C14.4673086,2.01177087 14.3923907,1.40221748 14.7151938,0.975809709 L15.3483711,0.137324272 C15.6117923,-0.211491262 15.6152447,-0.694869903 15.3570022,-1.0475301 L14.7359084,-1.89510291 C14.419665,-2.32605437 14.503214,-2.93455922 14.9237211,-3.26205437 L15.7498898,-3.90586019 C16.0937528,-4.17358835 16.2208025,-4.63984078 16.0612998,-5.0484233 L15.6780791,-6.02951068 C15.4830163,-6.52896699 15.7191631,-7.09448155 16.2090642,-7.30069515 L17.1716043,-7.70578252 C17.5720873,-7.87459806 17.813758,-8.29156893 17.7643881,-8.72811262 L17.6449337,-9.7763068 C17.5841708,-10.309666 17.9570342,-10.7940932 18.483186,-10.8650447 L19.5161558,-11.004501 C19.9463297,-11.0625204 20.286395,-11.4015495 20.3502651,-11.8359961 L20.502863,-12.8799961 C20.5805428,-13.4109087 21.0645748,-13.7813942 21.5907266,-13.7121903 L22.6243869,-13.5758796 C23.0545608,-13.5192583 23.4698893,-13.7579767 23.6425112,-14.160967 L24.0568039,-15.1287728 C24.2680932,-15.6219379 24.8298051,-15.8526175 25.3203967,-15.6478019 L26.2836273,-15.2451612 C26.6848007,-15.0777437 27.1470823,-15.1997243 27.4170631,-15.5436466 L28.0647407,-16.3702485 C28.3944486,-16.7907146 28.996554,-16.8665592 29.4177516,-16.5401126 L30.2456466,-15.8987534 C30.5902,-15.6320738 31.0676723,-15.6285786 31.4163687,-15.890365 L32.25324,-16.5191417 C32.6796162,-16.8389476 33.2803407,-16.754365 33.6038342,-16.3286563 L34.2394283,-15.492268 C34.5042304,-15.1441515 34.9644405,-15.0158796 35.3680307,-15.1773553 L36.3371304,-15.564967 C36.830484,-15.7627922 37.3890886,-15.5233748 37.5931278,-15.0274136 L37.9932655,-14.0533165 C38.1600183,-13.6475301 38.5715491,-13.4028699 39.0027587,-13.4528505 L40.0381453,-13.5737825 C40.5653328,-13.6352971 41.0434956,-13.2578214 41.1135801,-12.7251612 L41.2513324,-11.6794136 C41.3086429,-11.2439184 41.6438748,-10.8996466 42.073013,-10.8353359 L43.1039113,-10.6808505 C43.6290274,-10.6018602 43.9942954,-10.1118408 43.9259371,-9.57918058 L43.791292,-8.5330835 C43.7353625,-8.09723883 43.9711641,-7.67677282 44.3692303,-7.50236505 L45.325556,-7.08294757 C45.81235,-6.86939417 46.0402109,-6.30038447 45.837898,-5.80372427 L45.4405222,-4.82822913 C45.2751504,-4.4220932 45.3952953,-3.95444272 45.7350153,-3.68112233 L46.5515172,-3.0250835 C46.9675361,-2.69129709 47.0417636,-2.0820932 46.719651,-1.65568544 L46.0864736,-0.817549515 C45.8227073,-0.468384466 45.8189096,0.0149941748 46.0774973,0.368003883 L46.6985911,1.21487767 C47.0144893,1.64652816 46.9309403,2.2546835 46.5104332,2.58217864 L45.6846097,3.22563495 C45.341092,3.49371262 45.213697,3.95996505 45.3731997,4.36854757 L45.7564204,5.34928544 C45.9514833,5.84909126 45.7153364,6.41460583 45.2254353,6.62081942 L44.2632405,7.0259068 C43.8624123,7.19472233 43.6203963,7.6116932 43.6704566,8.04788738 L43.7892205,9.09608155 C43.8499835,9.63013981 43.4774653,10.1142175 42.9516588,10.1851689 L41.9183437,10.3246252 C41.4881698,10.3822951 41.1481045,10.7220233 41.0842344,11.1564699 L40.9316366,12.1997709 C40.8539567,12.7313825 40.3699247,13.1015184 39.843773,13.0323146 L38.8104579,12.8960039 C38.3799387,12.839033 37.9646103,13.078101 37.7919883,13.4807417 L37.3776956,14.4492466 C37.1667515,14.9420621 36.6046944,15.1727417 36.1141028,14.9679262" id="path-31"></path>
<filter x="-37.0%" y="-36.6%" width="174.1%" height="173.2%" filterUnits="objectBoundingBox" id="filter-32">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.768625453 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<polygon id="path-33" points="0.154116889 0.120932039 7.36025527 0.120932039 7.36025527 22.571301 0.154116889 22.571301"></polygon>
</defs>
<g id="UK-9-Hire-Us-/-Contact-Us" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-146">
<g id="Group-145">
<g id="Group-143">
<g id="Group-3-Copy">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-2"></g>
<path d="M72.0966677,24.2304117 C58.6925723,47.3661786 29.3002306,55.1212078 6.44715413,41.5513049 C-16.4062676,27.9814019 -24.0661946,-1.77417087 -10.6620991,-24.9102874 C2.74199631,-48.0460544 32.134338,-55.8010835 54.9870692,-42.2308311 C77.8404909,-28.6612777 85.5004179,1.09464466 72.0966677,24.2304117" id="Fill-1" fill="#0052CC" mask="url(#mask-2)"></path>
</g>
<g id="Group-6-Copy">
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<g id="Clip-5"></g>
<path d="M47.2502219,10.8543146 C46.5735438,10.419868 45.9189613,8.6880233 45.9189613,8.6880233 C45.9189613,8.6880233 47.7456469,8.54961553 48.422325,8.98406214 C49.0986578,9.41885825 49.3848651,10.1898874 49.0613715,10.7061204 C48.7378779,11.2227029 47.9269,11.2887612 47.2502219,10.8543146" id="Fill-4" fill="#4B9AFF" mask="url(#mask-4)"></path>
</g>
<g id="Group-9-Copy">
<mask id="mask-6" fill="white">
<use xlink:href="#path-5"></use>
</mask>
<g id="Clip-8"></g>
<path d="M34.7742457,19.3331184 C34.599207,18.541468 35.3459696,16.8480699 35.3459696,16.8480699 C35.3459696,16.8480699 36.7341954,18.0580893 36.9092341,18.8493903 C37.0839275,19.6413903 36.7480052,20.391099 36.1586738,20.5246136 C35.5689972,20.6581282 34.9492843,20.1247689 34.7742457,19.3331184" id="Fill-7" fill="#4B9AFF" mask="url(#mask-6)"></path>
</g>
<g id="Group-12-Copy">
<mask id="mask-8" fill="white">
<use xlink:href="#path-7"></use>
</mask>
<g id="Clip-11"></g>
<path d="M20.0302585,16.3974058 C20.4593967,15.7127068 22.1700804,15.0496777 22.1700804,15.0496777 C22.1700804,15.0496777 22.306797,16.8993087 21.8776588,17.5840078 C21.4481754,18.2687068 20.6869125,18.5588039 20.1769872,18.2309592 C19.6663714,17.9034641 19.6011203,17.0824544 20.0302585,16.3974058" id="Fill-10" fill="#4B9AFF" mask="url(#mask-8)"></path>
</g>
<g id="Group-15-Copy">
<mask id="mask-10" fill="white">
<use xlink:href="#path-9"></use>
</mask>
<g id="Clip-14"></g>
<path d="M11.6550552,3.76706796 C12.4370327,3.59021359 14.1097395,4.34586408 14.1097395,4.34586408 C14.1097395,4.34586408 12.914505,5.75161165 12.1328728,5.92881553 C11.3508953,6.1056699 10.6100018,5.76559223 10.4781186,5.16862136 C10.3462355,4.57165049 10.8730777,3.94427184 11.6550552,3.76706796" id="Fill-13" fill="#4B9AFF" mask="url(#mask-10)"></path>
</g>
<g id="Group-18-Copy-2">
<mask id="mask-12" fill="white">
<use xlink:href="#path-11"></use>
</mask>
<g id="Clip-17"></g>
<path d="M50.4761121,1.39148738 C49.6761819,1.34570097 48.2703486,0.156652427 48.2703486,0.156652427 C48.2703486,0.156652427 49.7990887,-0.865328155 50.5986736,-0.819891262 C51.3989491,-0.774454369 52.0200429,-0.242493204 51.986209,0.368108738 C51.9520298,0.97871068 51.2760422,1.43692427 50.4761121,1.39148738" id="Fill-16" fill="#4B9AFF" mask="url(#mask-12)"></path>
</g>
<g id="Group-21-Copy">
<mask id="mask-14" fill="white">
<use xlink:href="#path-13"></use>
</mask>
<g id="Clip-20"></g>
<path d="M43.6649327,14.9512194 C43.1308404,14.3465592 42.96754,12.4990252 42.96754,12.4990252 C42.96754,12.4990252 44.7624632,12.8705592 45.2965555,13.4752194 C45.8299574,14.0802291 45.8979704,14.9008893 45.4470819,15.3084233 C44.9965386,15.7159573 44.1986798,15.5558796 43.6649327,14.9512194" id="Fill-19" fill="#4B9AFF" mask="url(#mask-14)"></path>
</g>
<g id="Group-24-Copy">
<mask id="mask-16" fill="white">
<use xlink:href="#path-15"></use>
</mask>
<g id="Clip-23"></g>
<path d="M29.3774617,19.6635146 C29.4226886,18.8536893 30.5972084,17.4301165 30.5972084,17.4301165 C30.5972084,17.4301165 31.6070469,18.977767 31.56182,19.7875922 C31.5169383,20.597767 30.991477,21.2265437 30.3883359,21.1919417 C29.7851947,21.1576893 29.3325799,20.4733398 29.3774617,19.6635146" id="Fill-22" fill="#4B9AFF" mask="url(#mask-16)"></path>
</g>
<g id="Group-27-Copy">
<mask id="mask-18" fill="white">
<use xlink:href="#path-17"></use>
</mask>
<g id="Clip-26"></g>
<path d="M15.9834128,12.767767 C16.58103,12.2274175 18.4056442,12.0617476 18.4056442,12.0617476 C18.4056442,12.0617476 18.0386499,13.8792233 17.4413779,14.4195728 C16.8437607,14.9599223 16.0331279,15.0284272 15.6309188,14.5723107 C15.2280191,14.1161942 15.3861408,13.308466 15.9834128,12.767767" id="Fill-25" fill="#4B9AFF" mask="url(#mask-18)"></path>
</g>
<g id="Group-30-Copy">
<mask id="mask-20" fill="white">
<use xlink:href="#path-19"></use>
</mask>
<g id="Clip-29"></g>
<path d="M11.3286961,-1.69612427 C12.1286263,-1.65068738 13.5348048,-0.461638835 13.5348048,-0.461638835 C13.5348048,-0.461638835 12.0060647,0.560691262 11.2061345,0.515254369 C10.4058591,0.469467961 9.78476526,-0.0621436893 9.81894441,-0.672745631 C9.85312356,-1.28334757 10.5291112,-1.74156117 11.3286961,-1.69612427" id="Fill-28" fill="#4B9AFF" mask="url(#mask-20)"></path>
</g>
<g id="Group-33-Copy">
<mask id="mask-22" fill="white">
<use xlink:href="#path-21"></use>
</mask>
<g id="Clip-32"></g>
<path d="M49.4622687,6.32904466 C48.6992797,6.08123883 47.6345474,4.57203495 47.6345474,4.57203495 C47.6345474,4.57203495 49.3680171,3.97226796 50.1310062,4.22007379 C50.8936501,4.46822913 51.3624913,5.14139417 51.1781311,5.72368544 C50.9934256,6.3059767 50.2252578,6.57685049 49.4622687,6.32904466" id="Fill-31" fill="#4B9AFF" mask="url(#mask-22)"></path>
</g>
<g id="Group-36-Copy">
<mask id="mask-24" fill="white">
<use xlink:href="#path-23"></use>
</mask>
<g id="Clip-35"></g>
<path d="M39.4990814,17.7166136 C39.1327776,16.995565 39.4341756,15.1658563 39.4341756,15.1658563 C39.4341756,15.1658563 41.0785724,15.9826718 41.4452214,16.7044194 C41.81118,17.425468 41.6727372,18.2370408 41.1351924,18.5166524 C40.5983381,18.7962641 39.8657305,18.4380117 39.4990814,17.7166136" id="Fill-34" fill="#4B9AFF" mask="url(#mask-24)"></path>
</g>
<g id="Group-39-Copy">
<mask id="mask-26" fill="white">
<use xlink:href="#path-25"></use>
</mask>
<g id="Clip-38"></g>
<path d="M24.5002007,18.637165 C24.7453239,17.8647379 26.2357419,16.7864854 26.2357419,16.7864854 C26.2357419,16.7864854 26.8281805,18.5417476 26.5834026,19.3141748 C26.3386246,20.0862524 25.6736848,20.5608932 25.0985084,20.3739029 C24.5229868,20.1872621 24.2554228,19.4092427 24.5002007,18.637165" id="Fill-37" fill="#4B9AFF" mask="url(#mask-26)"></path>
</g>
<g id="Group-42-Copy-2">
<mask id="mask-28" fill="white">
<use xlink:href="#path-27"></use>
</mask>
<g id="Clip-41"></g>
<path d="M13.2518083,8.55073398 C13.9640466,8.17954951 15.7713985,8.48467573 15.7713985,8.48467573 C15.7713985,8.48467573 14.9645635,10.1497631 14.2516348,10.5205981 C13.5393965,10.891433 12.7377401,10.7512777 12.461545,10.2070835 C12.1853499,9.66323883 12.5392249,8.92156893 13.2518083,8.55073398" id="Fill-40" fill="#4B9AFF" mask="url(#mask-28)"></path>
</g>
<g id="Group-46-Copy-6">
<mask id="mask-30" fill="white">
<use xlink:href="#path-29"></use>
</mask>
<g id="Clip-45"></g>
<g id="Fill-44" mask="url(#mask-30)">
<use fill="black" fill-opacity="1" filter="url(#filter-32)" xlink:href="#path-31"></use>
<use fill="#4B9AFF" fill-rule="evenodd" xlink:href="#path-31"></use>
</g>
</g>
<g id="Group-73-Copy" transform="translate(39.703052, 0.699029)">
<path d="M11.2996956,1.81233786 C12.0419701,0.684454369 13.0359273,0.121036893 14.2808769,0.121036893 C14.760766,0.121036893 15.2247738,0.220299029 15.6729004,0.41952233 C16.1199913,0.618396117 16.5080455,0.88367767 16.835682,1.21536699 C17.1629732,1.5467068 17.4250134,1.93396893 17.6218024,2.37575534 C17.8182462,2.81859029 17.9166407,3.28274563 17.9166407,3.76892039 C17.9166407,4.49835728 17.7308995,5.14006602 17.3597623,5.69229903 L13.6912003,11.0971922 L18.1458827,16.8673282 C18.6043666,17.4426291 18.8336086,18.1056583 18.8336086,18.8571146 C18.8336086,19.3660078 18.7355593,19.8469398 18.5391155,20.2999107 C18.3423265,20.7528816 18.0806316,21.1450369 17.7526498,21.4770757 C17.4250134,21.8084155 17.0428283,22.0736971 16.60644,22.2725709 C16.1690159,22.4714447 15.710532,22.5714058 15.230643,22.5714058 C14.7279678,22.5714058 14.2477335,22.4714447 13.7892496,22.2725709 C13.3307656,22.0736971 12.970331,21.8084155 12.7082908,21.4770757 L7.30384241,14.5462019 L7.30384241,18.3597553 C7.30384241,19.6421243 6.97620592,20.6644544 6.32093295,21.4270951 C5.66600522,22.1897359 4.7918476,22.5714058 3.7001863,22.5714058 C2.56467903,22.5714058 1.66946153,22.1953282 1.0145338,21.4435223 C0.359606074,20.6924155 0.0316243437,19.6749786 0.0316243437,18.3926097 L0.0316243437,4.19987184 C0.0316243437,2.98426019 0.359606074,2.0003767 1.0145338,1.24857087 C1.66946153,0.497114563 2.54292866,0.121036893 3.6349352,0.121036893 C4.15901548,0.121036893 4.66100015,0.232182524 5.1415797,0.452376699 C5.621814,0.673619417 6.02609464,0.972454369 6.35373112,1.34783301 C6.70277273,1.72426019 6.94824116,2.13284272 7.09082691,2.57497864 C7.23272216,3.01746408 7.30384241,3.56969709 7.30384241,4.23307573 L7.30384241,7.78134757 L11.2996956,1.81233786 Z" id="Fill-48" fill="#253858"></path>
<path d="M28.2999208,18.3596505 C28.2999208,19.0674175 28.2288006,19.6479612 28.0872506,20.1005825 C27.9450101,20.5539029 27.7102442,20.9684272 27.382953,21.3441553 C27.0332209,21.720233 26.6182377,22.019068 26.1380034,22.2396117 C25.6577691,22.4601553 25.1768443,22.571301 24.69661,22.571301 C24.1939348,22.571301 23.6978193,22.4660971 23.2065372,22.2560388 C22.7149098,22.0463301 22.3164983,21.7642718 22.0106122,21.4105631 C21.6612254,21.034835 21.4212808,20.6259029 21.2900882,20.183767 C21.1588955,19.7416311 21.0936444,19.1338252 21.0936444,18.3596505 L21.0936444,4.66392233 C21.0936444,4.19976699 21.1043469,3.80201942 21.1264425,3.46998058 C21.1478477,3.13864078 21.1920389,2.85168932 21.2576352,2.60807767 C21.3228863,2.36481553 21.4157569,2.13867961 21.5359018,1.92827184 C21.6557015,1.71856311 21.8141684,1.51374757 22.0106122,1.31452427 C22.6872903,0.519029126 23.5718053,0.120932039 24.664157,0.120932039 C25.7558183,0.120932039 26.6510358,0.508194175 27.3501548,1.2816699 C27.7209468,1.70178641 27.9726296,2.14357282 28.103477,2.60807767 C28.2346697,3.07258252 28.2999208,3.75798058 28.2999208,4.66392233 L28.2999208,18.3596505 Z" id="Fill-50" fill="#253858"></path>
<path d="M42.1231424,2.87349903 C42.7342242,1.03854757 43.9025296,0.121071845 45.6277135,0.121071845 C47.3525522,0.121071845 48.5432985,1.07175146 49.1982262,2.97276117 L51.2292962,8.84250874 L53.6204556,2.64142136 C53.9259965,1.86759612 54.395183,1.25419806 55.0290509,0.800528155 C55.6622282,0.347906796 56.3717045,0.121071845 57.1581702,0.121071845 C57.6601548,0.121071845 58.1293413,0.215440777 58.5664201,0.403130097 C59.0031537,0.591168932 59.3853387,0.845266019 59.7129752,1.16542136 C60.0402664,1.48627573 60.2971279,1.86759612 60.4828692,2.30973204 C60.6682651,2.75186796 60.7611358,3.22720777 60.7611358,3.73575146 C60.7611358,3.95699417 60.7335163,4.18907184 60.679313,4.43198447 C60.6247644,4.6752466 60.5101434,5.01812039 60.33545,5.4599068 L55.1598983,19.7190524 C54.482875,21.6211107 53.3256173,22.5710913 51.6877801,22.5710913 C49.9846918,22.5710913 48.8160412,21.6424311 48.1828638,19.7858097 L45.7589062,12.5232466 L43.3674015,19.7526058 C42.7559745,21.6319456 41.6097647,22.5710913 39.9284268,22.5710913 C38.268494,22.5710913 37.1329867,21.7312078 36.5215597,20.0507417 L30.9531204,5.29423689 C30.822273,4.9849165 30.7183545,4.67000388 30.6420556,4.34914951 C30.5650662,4.02899417 30.5274346,3.78013981 30.5274346,3.60293592 C30.5274346,3.11676117 30.6254839,2.66344078 30.822273,2.24332427 C31.0187168,1.82355728 31.2807569,1.45866408 31.6083934,1.14899417 C31.9356846,0.839673786 32.3178697,0.591168932 32.7546032,0.403130097 C33.1913368,0.215440777 33.6605233,0.121071845 34.1631984,0.121071845 C35.8445364,0.121071845 37.0787834,1.10460583 37.8645586,3.07237282 L40.1901217,8.67683883 L42.1231424,2.87349903 Z" id="Fill-52" fill="#253858"></path>
<g id="Group-56" transform="translate(62.834395, 0.000000)">
<mask id="mask-34" fill="white">
<use xlink:href="#path-33"></use>
</mask>
<g id="Clip-55"></g>
<path d="M7.36039336,18.3596505 C7.36039336,19.0674175 7.28927311,19.6479612 7.1477231,20.1005825 C7.00548261,20.5539029 6.77071674,20.9684272 6.44342549,21.3441553 C6.0936934,21.720233 5.6787102,22.019068 5.1984759,22.2396117 C4.71824159,22.4601553 4.23731681,22.571301 3.7570825,22.571301 C3.25440735,22.571301 2.75829183,22.4660971 2.26700972,22.2560388 C1.77538237,22.0463301 1.37697088,21.7642718 1.07108476,21.4105631 C0.721697904,21.034835 0.481753375,20.6259029 0.350560683,20.183767 C0.219367991,19.7416311 0.154116889,19.1338252 0.154116889,18.3596505 L0.154116889,4.66392233 C0.154116889,4.19976699 0.16481945,3.80201942 0.186915062,3.46998058 C0.208320185,3.13864078 0.252511408,2.85168932 0.318107754,2.60807767 C0.383358856,2.36481553 0.476229472,2.13867961 0.596374358,1.92827184 C0.716174001,1.71856311 0.874640963,1.51374757 1.07108476,1.31452427 C1.74776285,0.519029126 2.63227779,0.120932039 3.72462957,0.120932039 C4.81629087,0.120932039 5.71150837,0.508194175 6.41062732,1.2816699 C6.7814193,1.70178641 7.03310212,2.14357282 7.16394957,2.60807767 C7.29514226,3.07258252 7.36039336,3.75798058 7.36039336,4.66392233 L7.36039336,18.3596505 Z" id="Fill-54" fill="#253858" mask="url(#mask-34)"></path>
</g>
<path d="M4.67159914,28.682633 C4.47584583,28.5466718 4.24177045,28.4365748 3.96971824,28.3533903 C3.69766602,28.2695068 3.38729173,28.227565 3.03894061,28.227565 C2.70854218,28.227565 2.42544216,28.2806913 2.19033104,28.3855456 C1.95487468,28.4907495 1.76360955,28.6396427 1.61688088,28.8315262 C1.47049746,29.0234097 1.36174562,29.2540893 1.29131586,29.5232155 C1.22123134,29.7926913 1.18567122,30.0911767 1.18567122,30.4193709 C1.18567122,31.1683806 1.34310245,31.7345942 1.65796491,32.1187107 C1.97317261,32.5024777 2.42716838,32.6943612 3.02064268,32.6943612 C3.38729173,32.6943612 3.72217834,32.6384388 4.02495727,32.5272932 C4.32739095,32.4157981 4.57665706,32.2794874 4.77241037,32.1187107 L5.04756978,33.037934 C4.80279183,33.1864777 4.50760828,33.3182447 4.16236435,33.4325359 C3.81677518,33.5471767 3.42734003,33.6041476 2.99302317,33.6041476 C2.49172899,33.6041476 2.05741213,33.5209631 1.69041784,33.3535456 C1.32342354,33.1864777 1.01926364,32.9603417 0.777938139,32.6758369 C0.535922147,32.3909825 0.357431037,32.0613903 0.241083834,31.6867107 C0.124736631,31.3120311 0.066735651,30.914633 0.066735651,30.4938175 C0.066735651,30.0541282 0.131296265,29.6424 0.259727006,29.2582835 C0.387812502,28.874866 0.579077638,28.5389825 0.832831923,28.2509825 C1.08624097,27.9629825 1.40144867,27.7354485 1.77741931,27.5683806 C2.15373519,27.4013126 2.59254022,27.3177786 3.0938344,27.3177786 C3.42423283,27.3177786 3.75428603,27.3534291 4.08433922,27.4243806 C4.41473766,27.4956816 4.69887341,27.5931961 4.93778221,27.7169243 L4.67159914,28.682633 Z" id="Fill-57" fill="#253858"></path>
<path d="M11.6334774,32.6941864 C11.9700903,32.6941864 12.2559522,32.6372155 12.4910634,32.5225748 C12.7265197,32.4082835 12.920892,32.2499534 13.0738351,32.0489825 C13.2264329,31.8476621 13.3379467,31.6110408 13.4087217,31.3384194 C13.4788062,31.0661476 13.5136759,30.7753515 13.5136759,30.4656816 C13.5136759,30.1315456 13.4774252,29.828167 13.4038883,29.5558951 C13.3303513,29.2832738 13.2174566,29.0480505 13.0645135,28.8498757 C12.9115705,28.6520505 12.7175434,28.4986136 12.482087,28.3902641 C12.2462854,28.2819146 11.9700903,28.2277398 11.6521206,28.2277398 C11.3275913,28.2277398 11.0510509,28.2819146 10.821809,28.3902641 C10.5922218,28.4986136 10.40579,28.6489049 10.2621686,28.8407883 C10.1185471,29.0323223 10.0146287,29.2619534 9.9504133,29.5275845 C9.88619793,29.7939146 9.85409024,30.0882058 9.85409024,30.4101087 C9.85409024,31.1654097 10.0070333,31.7347689 10.3129194,32.1188854 C10.6184603,32.5023029 11.0586463,32.6941864 11.6334774,32.6941864 M11.6793949,27.3176039 C12.156522,27.3176039 12.5780648,27.4011379 12.9454044,27.5685553 C13.3120534,27.7352738 13.6210467,27.9631573 13.8716938,28.2508078 C14.1223409,28.5388078 14.3118798,28.8715456 14.4403106,29.2493709 C14.5687413,29.6268466 14.6329567,30.0228466 14.6329567,30.4377204 C14.6329567,30.8463029 14.5701223,31.2412544 14.445144,31.6218757 C14.3194752,32.0024971 14.1299363,32.3397786 13.876182,32.6337204 C13.6224277,32.9280117 13.3075652,33.163235 12.9315946,33.3397398 C12.5552787,33.5162447 12.1164737,33.6043223 11.6151795,33.6043223 C11.1259689,33.6043223 10.7009736,33.5207883 10.3401937,33.3537204 C9.97941379,33.1863029 9.67974206,32.9605165 9.44117851,32.6756621 C9.2029602,32.3911573 9.0237786,32.0612155 8.90501469,31.6865359 C8.78556029,31.3122058 8.72583309,30.9176039 8.72583309,30.5027301 C8.72583309,30.0633903 8.79177468,29.6499146 8.92296737,29.2633515 C9.05450531,28.8760893 9.2454252,28.5388078 9.49641754,28.2508078 C9.74706463,27.9631573 10.0560579,27.7352738 10.422707,27.5685553 C10.7897013,27.4011379 11.2084822,27.3176039 11.6793949,27.3176039" id="Fill-59" fill="#253858"></path>
<polygon id="Fill-61" fill="#253858" points="22.1816115 32.044299 24.1902407 27.3639495 25.3920348 27.3639495 25.3920348 33.4930369 24.3466362 33.4930369 24.3466362 29.4536971 22.6038449 33.4930369 21.7597235 33.4930369 19.9713599 29.4536971 19.9713599 33.4930369 18.9162945 33.4930369 18.9162945 27.3639495 20.1177434 27.3639495"></polygon>
<polygon id="Fill-63" fill="#253858" points="33.298535 32.044299 35.3071642 27.3639495 36.5089583 27.3639495 36.5089583 33.4930369 35.4635597 33.4930369 35.4635597 29.4536971 33.7207683 33.4930369 32.8766469 33.4930369 31.0882834 29.4536971 31.0882834 33.4930369 30.033218 33.4930369 30.033218 27.3639495 31.2346668 27.3639495"></polygon>
<polygon id="Fill-65" fill="#253858" points="44.0395224 30.7070214 42.2052414 30.7070214 42.2052414 32.5639922 44.8377263 32.5639922 44.8377263 33.4930019 41.150176 33.4930019 41.150176 27.3642641 44.6540566 27.3642641 44.6540566 28.2929243 42.2052414 28.2929243 42.2052414 29.7787107 44.0395224 29.7787107"></polygon>
<path d="M50.4690346,28.2092155 L50.2946864,28.2092155 C50.227709,28.2092155 50.1572793,28.2123612 50.0840876,28.2183029 L50.0840876,29.9826524 L50.6527043,29.9826524 C50.9827575,29.9826524 51.2334046,29.8991184 51.4046456,29.7320505 C51.5758866,29.5649825 51.6615071,29.3266136 51.6615071,29.0172932 C51.6615071,28.7387301 51.5776128,28.5342641 51.409479,28.4042447 C51.241,28.2742252 50.9278637,28.2092155 50.4690346,28.2092155 Z M50.514952,30.8742641 L50.3084961,30.8742641 C50.2384116,30.8742641 50.1631484,30.8711184 50.0840876,30.8651767 L50.0840876,33.4928272 L49.0290221,33.4928272 L49.0290221,27.3364777 L49.3639087,27.3364777 L49.7443676,27.3364777 L50.1068737,27.3364777 L50.3771997,27.3364777 C51.1602129,27.3364777 51.7564492,27.4857204 52.1659085,27.7842058 C52.575713,28.0830408 52.7804426,28.5185359 52.7804426,29.0910408 C52.7804426,29.4545359 52.691715,29.780633 52.5146048,30.0700311 C52.3371494,30.3590796 52.0409302,30.5750796 51.6249112,30.7162835 L53.8444844,33.4928272 L52.6247376,33.4928272 L50.514952,30.8742641 Z" id="Fill-67" fill="#253858"></path>
<path d="M61.7787768,28.682633 C61.5830235,28.5466718 61.3489481,28.4365748 61.0768959,28.3533903 C60.8048436,28.2695068 60.4944694,28.227565 60.1461182,28.227565 C59.8157198,28.227565 59.5326198,28.2806913 59.2975087,28.3855456 C59.0620523,28.4907495 58.8707872,28.6396427 58.7240585,28.8315262 C58.5776751,29.0234097 58.4689232,29.2540893 58.3984935,29.5232155 C58.328409,29.7926913 58.2928488,30.0911767 58.2928488,30.4193709 C58.2928488,31.1683806 58.4502801,31.7345942 58.7651425,32.1187107 C59.0803502,32.5024777 59.534346,32.6943612 60.1278203,32.6943612 C60.4944694,32.6943612 60.829356,32.6384388 61.1321349,32.5272932 C61.4345686,32.4157981 61.6838347,32.2794874 61.879588,32.1187107 L62.1547474,33.037934 C61.9099695,33.1864777 61.6147859,33.3182447 61.269542,33.4325359 C60.9239528,33.5471767 60.5345177,33.6041476 60.1002008,33.6041476 C59.5989066,33.6041476 59.1645898,33.5209631 58.7975955,33.3535456 C58.4306012,33.1864777 58.1264413,32.9603417 57.8851158,32.6758369 C57.6430998,32.3909825 57.4646087,32.0613903 57.3482615,31.6867107 C57.2319143,31.3120311 57.1739133,30.914633 57.1739133,30.4938175 C57.1739133,30.0541282 57.2384739,29.6424 57.3669046,29.2582835 C57.4949901,28.874866 57.6862553,28.5389825 57.9400095,28.2509825 C58.1934186,27.9629825 58.5086263,27.7354485 58.8845969,27.5683806 C59.2609128,27.4013126 59.6997178,27.3177786 60.201012,27.3177786 C60.5314105,27.3177786 60.8614637,27.3534291 61.1915168,27.4243806 C61.5219153,27.4956816 61.806051,27.5931961 62.0449598,27.7169243 L61.7787768,28.682633 Z" id="Fill-69" fill="#253858"></path>
<polygon id="Fill-71" fill="#253858" points="69.1991735 30.7070214 67.3648925 30.7070214 67.3648925 32.5639922 69.9973775 32.5639922 69.9973775 33.4930019 66.3098271 33.4930019 66.3098271 27.3642641 69.8137077 27.3642641 69.8137077 28.2929243 67.3648925 28.2929243 67.3648925 29.7787107 69.1991735 29.7787107"></polygon>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment