PHP Classes
elePHPant
Icontem

File: docs/files/AbstractDatabaseLogger.php.txt

Recommend this page to a friend!
  Classes of Kiril Savchev  >  ITE Logger  >  docs/files/AbstractDatabaseLogger.php.txt  >  Download  
File: docs/files/AbstractDatabaseLogger.php.txt
Role: Documentation
Content type: text/plain
Description: Documentation
Class: ITE Logger
Log messages to different storage PSR-3 compliant
Author: By
Last change: Update documentation
Date: 3 years ago
Size: 11,862 bytes
 

 

Contents

Class file image Download
<?php

/**
 * AbstractDatabaseLogger file
 *
 * Copyright (c) 2016, Kiril Savchev
 * All rights reserved.
 *
 * @category Libs
 * @package Logger
 *
 * @author Kiril Savchev <k.savchev@gmail.com>
 *
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3 License
 * @link http://ifthenelse.info
 */
namespace Ite\Logger;

use Psr\Log\AbstractLogger;

/**
 * AbstractDatabaseLogger
 *
 * Base database logger class that creates an INSERT SQL query with the log
 * parts (message, level, context, etc...) and send them to ancestor's
 * write() method for the actual inserting into database. The ancestors must
 * implement the write() method on their own way with the prefered DB library.
 *
 * @version 1.0
 *
 * @author Kiril Savchev <k.savchev@gmail.com>
 */
abstract class AbstractDatabaseLogger extends AbstractLogger {

        use MessagePrepareTrait;

        /**
         * The default log table
         *
         * @var string
         */
        protected $defaultTable = 'logs';

        /**
         * The default 'message' field of the table
         *
         * @var string
         */
        protected $messageField = 'message';

        /**
         * The default date field of the table
         *
         * @var string
         */
        protected $dateField = 'date';

        /**
         * The default context field of the table
         *
         * @var string
         */
        protected $contextField = 'context';

        /**
         * The default 'level' field of the table
         *
         * @var string
         */
        protected $levelField = 'level';

        /**
         * Default preparing behaviour
         *
         * @var boolean
         */
        protected $usePrepare = true;

        /**
         * Level tables config array
         *
         * @example 'level' => [
         *                'table' => 'tableName',
         *                'prepared' => true,
         *                'messageField' => 'message',
         *                'dateField' => 'date',
         *                'contextField' => 'context',
         *                'dateField' => 'date',
         *                'levelField' => 'level' // or NULL if separate level tables are used
          *       ]
         *
         * @var array
         */
        protected $tableConfigs = [];

        /**
         * Default query template with placeholders for table fields and values
         *
         * @var string
         */
        protected $sqlTpl = "INSERT INTO %s(%s,%s,%s,%s) VALUES(%s, %s, %s, NOW())";

        /**
         * Creates database logger
         *
         * If config parameter is string it will be used as a default table name,
         * otherwise it will be used as a table config and the second parameter
         * will be used for default table name.
         *
         * @param array|string $config [Optional] Table config or default table
         * @param string $defaultTable [Optional] The default log table name
         */
        public function __construct($config = null, $defaultTable = '') {
                if (is_array($config) && $config) {
                        $this->tableConfigs = $config;
                        if ($defaultTable) {
                                $this->defaultTable = $defaultTable;
                        }
                }
                else if (is_string($config) && $config) {
                        $this->defaultTable = $config;
                }
        }

        /**
         * Prepares level table config
         *
         * If some parameter is missing, then the default one is used
         *
         * @param string $level
         * @return array
         */
        protected function prepareTableConfig($level) {
                if (!array_key_exists($level, $this->tableConfigs)) {
                        $this->tableConfigs[$level] = [];
                }
                if (!array_key_exists('table', $this->tableConfigs[$level])) {
                        $this->tableConfigs[$level]['table'] = $this->defaultTable;
                }
                if (!array_key_exists('prepared', $this->tableConfigs[$level])) {
                        $this->tableConfigs[$level]['prepared'] = $this->usePrepare;
                }
                if (!array_key_exists('messageField', $this->tableConfigs[$level])) {
                        $this->tableConfigs[$level]['messageField'] = $this->messageField;
                }
                if (!array_key_exists('contextField', $this->tableConfigs[$level])) {
                        $this->tableConfigs[$level]['contextField'] = $this->contextField;
                }
                if (!array_key_exists('levelField', $this->tableConfigs[$level])) {
                        $this->tableConfigs[$level]['levelField'] = $this->levelField;
                }
                if (!array_key_exists('dateField', $this->tableConfigs[$level])) {
                        $this->tableConfigs[$level]['dateField'] = $this->dateField;
                }
                return $this->tableConfigs[$level];
        }

        /**
         * Prepares the sql query and parameters to write message
         *
         * If 'prepared' parameter is set to true then the query will has a '?'
         * placeholders for the values and the 'params' will holds the values.
         * Otherwise the query will contains the values and the 'params' key
         * will be empty.
         *
         * @param string $level The log level
         * @param string $message The log message
         * @param array $context The log context
         * @return array Array with 'query' key for the SQL query and 'params' for the values if the query will be prepared before execute
         */
        protected function prepareSQL($level, $message, array $context) {
                $tableConfig = $this->prepareTableConfig($level);
                $args = [$tableConfig['table'], $tableConfig['messageField'], $tableConfig['contextField'], $tableConfig['levelField'], $tableConfig['dateField']];
                if ($tableConfig['prepared']) {
                        $args = array_merge($args, ["?", "?", "?"]);
                        $params = [$message, $this->prepareContext($context), $level];
                }
                else {
                        $args = array_merge($args, ["'{$message}'", "'".$this->prepareContext($context)."'", "'{$level}'"]);
                        $params = [];
                }
                $sql = vsprintf($this->sqlTpl, $args);
                return ['query' => $sql, 'params' => $params];
        }

        /**
         * Trigger the database logging
         *
         * This method will craete the INSERT SQL statement and will provide it
         * and array with parameters if any, to the abstract write() method to
         * insert the log into database table
         *
         * @param string $level The log level
         * @param string $message The log message
         * @param array $context The log context
         */
        public function log($level, $message, array $context = []) {
                $sql = $this->prepareSQL($level, $message, $context);
                $this->write($sql['query'], $sql['params'], $this->tableConfigs[$level]['prepared']);
        }

        /**
         * The actual writing to the database
         *
         * Every ancestor of this class must implement on their own the way of
         * database query with the prefered library (e.g. \mysqli, \PDO, etc...)
         *
         * @param string $sql The INSERT SQL query
         * @param array $params [Optional] Parameters if the query will be prepared before executing
         * @param bool $mustPrepare [Optional] Whether or not to prepare the statement. Default false
         */
        abstract protected function write($sql, array $params = [], $mustPrepare = false);

        /**
         * Get the default table name
         *
         * @return string
         */
        public function getDefaultTable() {
                return $this->defaultTable;
        }

        /**
         * Get the default 'message' field
         *
         * @return string
         */
        public function getMessageField() {
                return $this->messageField;
        }

        /**
         * Get the default 'date' field
         *
         * @return string
         */
        public function getDateField() {
                return $this->dateField;
        }

        /**
         * Get the default 'context' field
         *
         * @return string
         */
        public function getContextField() {
                return $this->contextField;
        }

        /**
         * Get the default 'level' field
         *
         * @return string
         */
        public function getLevelField() {
                return $this->levelField;
        }

        public function getUsePrepare() {
                return $this->usePrepare;
        }

        /**
         * Get the table configs
         *
         * @return array
         */
        public function getTableConfigs() {
                return $this->tableConfigs;
        }

        /**
         * Sets the default table name
         *
         * @param string $defaultTable
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setDefaultTable($defaultTable) {
                $this->defaultTable = $defaultTable;
                return $this;
        }

        /**
         * Sets the default message field
         *
         * @param string $messageField
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setMessageField($messageField) {
                $this->messageField = $messageField;
                return $this;
        }

        /**
         * Sets the default date field
         *
         * @param string $dateField
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setDateField($dateField) {
                $this->dateField = $dateField;
                return $this;
        }

        /**
         * Sets the default context field
         *
         * @param string $contextField
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setContextField($contextField) {
                $this->contextField = $contextField;
                return $this;
        }

        /**
         * Sets the default level field
         *
         * @param string $levelField
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setLevelField($levelField) {
                $this->levelField = $levelField;
                return $this;
        }

        /**
         * Sets whether or not to prepare the statement
         *
         * @param bool $usePrepare
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setUsePrepare($usePrepare) {
                $this->usePrepare = $usePrepare;
                return $this;
        }

        /**
         * Sets the table configs
         *
         * @param array $tableConfigs
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setTableConfigs(array $tableConfigs) {
                $this->tableConfigs = $tableConfigs;
                return $this;
        }

        /**
         * Get default query template
         * @return string
         */
        public function getSqlTpl() {
                return $this->sqlTpl;
        }

        /**
         * Sets default query template
         *
         * @param string $sqlTpl
         * @return \Ite\Logger\AbstractDatabaseLogger
         */
        public function setSqlTpl($sqlTpl) {
                $this->sqlTpl = $sqlTpl;
                return $this;
        }

}