arch-8.x-1.x-dev/modules/logger/src/Services/ArchLogger.php
modules/logger/src/Services/ArchLogger.php
<?php namespace Drupal\arch_logger\Services; use Drupal\arch_order\Entity\OrderInterface; use Drupal\Core\Cache\Context\UserCacheContextBase; use Drupal\Core\Database\Connection; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TempStore\PrivateTempStoreFactory; /** * Arch logger service. * * @package Drupal\arch_logger\Service */ class ArchLogger extends UserCacheContextBase { const TABLE_NAME = 'arch_log'; const CART_STORE_NAME = 'cart_log'; /** * Database connection. * * @var \Drupal\Core\Database\Connection */ protected $database; /** * Store. * * @var \Drupal\Core\TempStore\PrivateTempStore */ protected $store; /** * ArchLogger constructor. * * @param \Drupal\Core\Database\Connection $database * Database connection. * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $store_factory * Store. * @param \Drupal\Core\Session\AccountInterface $user * Current user. */ public function __construct( Connection $database, PrivateTempStoreFactory $store_factory, AccountInterface $user, ) { parent::__construct($user); $this->store = $store_factory->get('arch_logger'); $this->database = $database; } /** * Save log for cart. * * @param array $original * Original cart object. * @param array $new * New cart object. * @param string $message * Log message. * @param array|null $data * Log details. * * @throws \Drupal\Core\TempStore\TempStoreException */ public function storeCartLog(array $original, array $new, $message, array $data = NULL) { $logs = $this->store->get(self::CART_STORE_NAME); if (!isset($logs)) { $logs = []; } if (!isset($data) && isset($original)) { $data = self::buildDefaultData($original, $new); } $logs[] = [ 'uid' => $this->user->id(), 'status' => 'cart', 'message' => $message, 'data' => serialize($data), 'created' => time(), ]; $this->store->set(self::CART_STORE_NAME, $logs); } /** * Save cart log into database. * * @param \Drupal\arch_order\Entity\OrderInterface $order_entity * Order entity. * * @throws \Drupal\Core\TempStore\TempStoreException * @throws \Exception */ public function saveCartLogs(OrderInterface $order_entity) { $cart_logs = $this->store->get(self::CART_STORE_NAME); if (!empty($cart_logs)) { foreach ($cart_logs as $log) { $log['oid'] = $order_entity->id(); $this->database->insert(self::TABLE_NAME) ->fields($log) ->execute(); } $this->store->delete(self::CART_STORE_NAME); } } /** * Insert new log for order. * * @param \Drupal\arch_order\Entity\OrderInterface $order_entity * Order entity. * @param string $message * Log message. * @param array|null $data * Log details. * * @throws \Exception */ public function insert(OrderInterface $order_entity, $message, array $data = NULL) { if (!isset($data) && isset($order_entity->original)) { $data = self::buildDefaultData( $order_entity->original->toArray(), $order_entity->toArray() ); } $this->database->insert(self::TABLE_NAME) ->fields([ 'uid' => $this->user->id(), 'oid' => $order_entity->id(), 'status' => $order_entity->get('status')->getString(), 'message' => $message, 'data' => serialize($data), 'created' => time(), ]) ->execute(); } /** * Get log records by order entity. * * @param \Drupal\arch_order\Entity\OrderInterface $order_entity * Order entity. * * @return null|array * Logs. */ public function getByOrder(OrderInterface $order_entity) { if (!$order_entity) { return NULL; } $query = $this->database->select(self::TABLE_NAME, 't'); $query->fields('t'); $query->condition('oid', $order_entity->id()); return $query->execute()->fetchAll(); } /** * Get log records by order entity and log ID. * * @param \Drupal\arch_order\Entity\OrderInterface $order_entity * Order entity. * @param int $lid * Log ID. * * @return null|array * Logs. */ public function getByOrderAndId(OrderInterface $order_entity, $lid) { $lid = (int) $lid; if (!$order_entity || empty($lid)) { return NULL; } $query = $this->database->select(self::TABLE_NAME, 't'); $query->fields('t'); $query->condition('lid', $lid); $query->condition('oid', $order_entity->id()); return $query->execute()->fetch(); } /** * Build default data field value. * * @param array $original * Original content. * @param array $new * New content. * * @return null|array * Default data array. */ private static function buildDefaultData(array $original, array $new) { self::removeIgnoredKeysFromOrderArray($original); self::removeIgnoredKeysFromOrderArray($new); return [ 'old_values' => self::arrayDiff($original, $new), 'new_values' => self::arrayDiff($new, $original), ]; } /** * Get differences between multidimensional arrays. * * @param array $array1 * First array. * @param array $array2 * Second array. * * @return array * Diff array. */ private static function arrayDiff(array $array1, array $array2) { $result = []; foreach ($array1 as $key => $val) { if (is_array($val) && isset($array2[$key])) { $tmp = self::arrayDiff($val, $array2[$key]); if (!empty($tmp)) { $result[$key] = $tmp; } } elseif (!isset($array2[$key])) { $result[$key] = NULL; } elseif ($val !== $array2[$key]) { $result[$key] = $array2[$key]; } if (isset($array2[$key])) { unset($array2[$key]); } } $result = array_merge($result, $array2); return $result; } /** * Remove ignored keys from order array. * * @param array $order_array * Order entity in array. */ private static function removeIgnoredKeysFromOrderArray(array &$order_array) { $ignored_keys = [ 'vid', 'revision_timestamp', 'created', 'changed', ]; foreach ($ignored_keys as $key) { if (isset($order_array[$key])) { unset($order_array[$key]); } } } }