Alex Trofimov 6 years ago
parent
commit
1eeee96b79

+ 123 - 0
inc/classes/BxDolLogs.php

@@ -0,0 +1,123 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+/**
+ * This class unifies the usage of logs.
+ *
+ * Add record to sys_objects_logs table, like you are doing this for Comments or Voting objects:
+ * - object: your logs object name, usually it is in the following format - vendor prefix, underscore, module prefix;
+ * - module: module name
+ * - logs_storage: logs storage, supported storages: 
+ *      - `Auto`: log to the storage currently configured in settings
+ *      - `Folder`: files in `logs` folder
+ *      - `PHPLog`: php log
+ *      - `STDErr`: standard error output, usually written to web server error log
+ * - title: translatable title
+ * - active: 0 or 1
+ * - class_name: user defined class name which is derived from BxDolLogs.
+ * - class_file: the location of the user defined class, leave it empty if class is located in system folders.
+ * 
+ * @section example Example of usage
+ *
+ * Log data to the logs object
+ *
+ * @code
+ *  if ($o = BxDolLogs::getObjectInstance('my_module_logs_object'))
+ *      $o->add($s);
+ * @endcode
+ *
+ * or
+ *
+ * @code
+ *  bx_log('my_module_logs_object', $s);
+ * @endcode
+ *
+ */
+class BxDolLogs extends BxDolFactory implements iBxDolFactoryObject
+{
+	protected $_oDb;
+	protected $_sObject;
+    protected $_aObject;
+    protected $_oLogsStorage;
+
+    /**
+     * Constructor
+     */
+    protected function __construct($aObject, $oLogsStorage)
+    {
+        parent::__construct();
+
+        $this->_aObject = $aObject;
+        $this->_sObject = $aObject['object'];
+
+        $this->_oLogsStorage = $oLogsStorage;
+        $this->_oDb = new BxDolLogsQuery($this->_aObject);
+    }
+
+   /**
+     * Get logs object instance by object name
+     * @param $sObject object name
+     * @return object instance or false on error
+     */
+    public static function getObjectInstance($sObject)
+    {
+        if(isset($GLOBALS['bxDolClasses']['BxDolLogs!' . $sObject]))
+            return $GLOBALS['bxDolClasses']['BxDolLogs!' . $sObject];
+
+        $aObject = BxDolLogsQuery::getLogsObject($sObject);
+        if(!$aObject || !is_array($aObject) || !$aObject['active'])
+            return false;
+
+        $sClass = 'BxDolLogs';
+        if(!empty($aObject['class_name'])) {
+            $sClass = $aObject['class_name'];
+            if(!empty($aObject['class_file']))
+                require_once(BX_DIRECTORY_PATH_ROOT . $aObject['class_file']);
+        }        
+
+        $sLogsStorage = (empty($aObject['logs_storage']) ? 'Auto' : $aObject['logs_storage']);
+        if ('Auto' == $sLogsStorage)
+            $sLogsStorage = getParam('sys_logs_storage_default');
+        $sClassLogsStorage = 'BxDolLogsStorage' . $sLogsStorage;
+        $oLogsStorage = $sClassLogsStorage::getInstance();
+
+        $o = new $sClass($aObject, $oLogsStorage);
+        return ($GLOBALS['bxDolClasses']['BxDolLogs!' . $sObject] = $o);
+    }
+
+    /**
+     * Get current logs object name
+     */
+    public function getObjectName()
+    {
+        return $this->_aObject['object'];
+    }
+
+    /**
+     * Log to the current logs storage object
+     * @param $mixed string or array to log
+     * @return true on success or false on error
+     */
+    public function add($mixed)
+    {
+        return $this->_oLogsStorage->add($this, $mixed);
+    }
+
+    /**
+     * Get logs from current logs storage
+     * @param $iLines number of lines from the tail to return
+     * @return array of strings
+     */
+    public function get($iLines = 30)
+    {
+        return $this->_oLogsStorage->add($this, $mixed);
+    }
+}
+
+/** @} */

+ 33 - 0
inc/classes/BxDolLogsQuery.php

@@ -0,0 +1,33 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolLogsQuery extends BxDolDb
+{
+
+    public function __construct($aObject = array())
+    {
+        parent::__construct();
+        $this->_aObject = $aObject;
+    }
+
+    static public function getLogsObject($sObject)
+    {
+        $oDb = BxDolDb::getInstance();
+
+        $sQuery = $oDb->prepare("SELECT * FROM `sys_objects_logs` WHERE `object` = ?", $sObject);
+
+        $aObject = $oDb->getRow($sQuery);
+        if(!$aObject || !is_array($aObject))
+            return false;
+
+        return $aObject;
+    }
+}
+
+/** @} */

+ 133 - 0
inc/classes/BxDolLogsStorageFolder.php

@@ -0,0 +1,133 @@
+<?php defined('BX_DOL') or defined('BX_DOL_INSTALL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolLogsStorageFolder extends BxDolFactory implements iBxDolSingleton
+{
+    protected function __construct()
+    {
+        if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
+            trigger_error ('Multiple instances are not allowed for the class: ' . get_class($this), E_USER_ERROR);
+
+        parent::__construct();
+    }
+
+    /**
+     * Prevent cloning the instance
+     */
+    public function __clone()
+    {
+        if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
+            trigger_error('Clone is not allowed for the class: ' . get_class($this), E_USER_ERROR);
+    }
+
+    /**
+     * Get singleton instance of the class
+     */
+    public static function getInstance()
+    {
+        if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
+            $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolLogsStorageFolder();
+
+        return $GLOBALS['bxDolClasses'][__CLASS__];
+    }
+
+    /**
+     * Write to log 
+     * @param $oObject logs object 
+     * @param $mixed string or array to log
+     * @return true on success or false on error
+     */
+    public function add($oObject, $mixed)
+    {
+        if (!$mixed)
+            return true;
+
+        $sFile = BX_DIRECTORY_PATH_LOGS . $oObject->getObjectName() . '.log';
+
+        $s = $this->formatLogString($oObject, $mixed);
+
+        return file_put_contents($sFile, $s, FILE_APPEND) ? true : false;
+    }
+
+    protected function formatLogString($oObject, $mixed, $bIncludeObjectName = false)
+    {
+        $s = date('M d H:i:s');
+
+        if ($bIncludeObjectName)
+            $s .= ' ' . $oObject->getObjectName();
+
+        $s .= ' [' . (int)bx_get_logged_profile_id() . '] ';
+
+        if (!empty($_SERVER['REQUEST_URI']))
+            $s .= $_SERVER['REQUEST_URI'] . (!empty($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '');
+        elseif (defined('BX_DOL_CRON_EXECUTE'))
+            $s .= 'CRON';
+        else
+            $s .= 'EMPTY';
+
+        $s .= ' ' . trim(is_array($mixed) ? print_r($mixed) : $mixed);
+
+        $s .= "\n";
+
+        return $s;
+    }
+
+    /**
+     * Get logs
+     * @param $oObject logs object
+     * @param $iLines number of lines from the tail
+     * @param $sFilter filter lines which include this phrase
+     * @return array of strings
+     */
+    public function get($oObject, $iLines, $sFilter = false)
+    {
+        $sFile = BX_DIRECTORY_PATH_LOGS . $oObject->getObjectName() . '.log';
+        $iSize = filesize($sFile);
+        if (!($fd = fopen($sFile, 'r+')))
+            return false;
+        $iPos = $iSize;
+        $n = 0;
+        while ($n < $iLines+1 && $iPos > 0) {
+            if (-1 == fseek($fd, $iPos))
+                break;
+            if (false === ($s = fread($fd, 1)))
+                break;
+            if ($s === "\n")
+                ++$n;
+            $iPos--;
+        }
+        $a = array();
+        for ($i = 0; $i < $iLines; $i++) {
+            if (false === ($s = fgets($fd)))
+                break;
+            if (!$sFilter || false !== stripos($s, $sFilter))
+                array_push($a, $s);
+        }
+        fclose($fd);
+        return $a;
+    }
+
+    /**
+     * Check if filtering supported in `get` method
+     */
+    public function isFilterAvail()
+    {
+        return true;
+    }
+
+    /**
+     * Check if `get` method available
+     */
+    public function isGetAvail()
+    {
+        return true;
+    }
+}
+
+/** @} */

+ 64 - 0
inc/classes/BxDolLogsStoragePHPLog.php

@@ -0,0 +1,64 @@
+<?php defined('BX_DOL') or defined('BX_DOL_INSTALL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolLogsStoragePHPLog extends BxDolLogsStorageFolder implements iBxDolSingleton
+{
+    /**
+     * Get singleton instance of the class
+     */
+    public static function getInstance()
+    {
+        if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
+            $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolLogsStoragePHPLog();
+
+        return $GLOBALS['bxDolClasses'][__CLASS__];
+    }
+
+    /**
+     * Write to log 
+     * @param $oObject logs object 
+     * @param $mixed string or array to log
+     * @return true on success or false on error
+     */
+    public function add($oObject, $mixed)
+    {
+        if (!$mixed)
+            return true;
+
+        $s = $this->formatLogString($oObject, $mixed, true);
+
+        return error_log($s, 0);
+    }
+
+    /**
+     * Not supported
+     */
+    public function get($oObject, $iLines, $sFilter = false)
+    {
+        return false;
+    }
+
+    /**
+     * Check if filtering supported in `get` method
+     */
+    public function isFilterAvail()
+    {
+        return false;
+    }
+
+    /**
+     * Check if `get` method available
+     */
+    public function isGetAvail()
+    {
+        return false;
+    }
+}
+
+/** @} */

+ 70 - 0
inc/classes/BxDolLogsStorageSTDErr.php

@@ -0,0 +1,70 @@
+<?php defined('BX_DOL') or defined('BX_DOL_INSTALL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolLogsStorageSTDErr extends BxDolLogsStorageFolder implements iBxDolSingleton
+{
+    /**
+     * Get singleton instance of the class
+     */
+    public static function getInstance()
+    {
+        if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
+            $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolLogsStorageSTDErr();
+
+        return $GLOBALS['bxDolClasses'][__CLASS__];
+    }
+
+    /**
+     * Write to log 
+     * @param $oObject logs object 
+     * @param $mixed string or array to log
+     * @return true on success or false on error
+     */
+    public function add($oObject, $mixed)
+    {
+        if (!$mixed)
+            return true;
+
+        $s = $this->formatLogString($oObject, $mixed, true);
+
+        if (!($fd = fopen('php://stderr', 'w')))
+            return false;
+        if (false === fwrite($fd, $s))
+            return false;
+        fclose($fd);
+
+        return true;
+    }
+
+    /**
+     * Not supported
+     */
+    public function get($oObject, $iLines, $sFilter = false)
+    {
+        return false;
+    }
+
+    /**
+     * Check if filtering supported in `get` method
+     */
+    public function isFilterAvail()
+    {
+        return false;
+    }
+
+    /**
+     * Check if `get` method available
+     */
+    public function isGetAvail()
+    {
+        return false;
+    }
+}
+
+/** @} */

+ 13 - 0
inc/utils.inc.php

@@ -2035,4 +2035,17 @@ function bx_get_device_pixel_ratio()
     return $iRatio;
     return $iRatio;
 }
 }
 
 
+/**
+ * Log to logs object
+ * @param $sObject - logs object
+ * @param $mixed - string or array to log
+ */
+function bx_log($sObject, $mixed)
+{
+    if ($o = BxDolLogs::getObjectInstance($sObject))
+        return $o->add($mixed);
+    else
+        return false;
+}
+
 /** @} */
 /** @} */

File diff suppressed because it is too large
+ 0 - 0
install/sql/system.sql


+ 2 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -1508,6 +1508,7 @@
 	<string name="_adm_stg_cpt_option_sys_hide_post_to_context_for_privacy"><![CDATA[Hide post to context for modules in Privacy field]]></string>
 	<string name="_adm_stg_cpt_option_sys_hide_post_to_context_for_privacy"><![CDATA[Hide post to context for modules in Privacy field]]></string>
     <string name="_adm_stg_cpt_option_sys_search_keyword_min_len"><![CDATA[Keyword min length in site search]]></string>
     <string name="_adm_stg_cpt_option_sys_search_keyword_min_len"><![CDATA[Keyword min length in site search]]></string>
     <string name="_adm_stg_cpt_option_sys_profile_bot"><![CDATA[System bot profile]]></string>
     <string name="_adm_stg_cpt_option_sys_profile_bot"><![CDATA[System bot profile]]></string>
+    <string name="_adm_stg_cpt_option_sys_logs_storage_default"><![CDATA[Default logs storage]]></string>
 	<string name="_adm_stg_cpt_type_system"><![CDATA[System]]></string>
 	<string name="_adm_stg_cpt_type_system"><![CDATA[System]]></string>
 	<string name="_adm_stg_scs_save"><![CDATA[Settings were successfully saved]]></string>
 	<string name="_adm_stg_scs_save"><![CDATA[Settings were successfully saved]]></string>
 	<string name="_adm_stg_err_save_error_message"><![CDATA[Error in '{0}': {1}]]></string>
 	<string name="_adm_stg_err_save_error_message"><![CDATA[Error in '{0}': {1}]]></string>
@@ -2502,6 +2503,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_location_determining"><![CDATA[Determining location...]]></string>
 	<string name="_sys_location_determining"><![CDATA[Determining location...]]></string>
 	<string name="_sys_location_geolocation_not_supported_by_browser"><![CDATA[Geolocation is not supported by this browser]]></string>
 	<string name="_sys_location_geolocation_not_supported_by_browser"><![CDATA[Geolocation is not supported by this browser]]></string>
 	<string name="_sys_location_undefined"><![CDATA[Location off]]></string>
 	<string name="_sys_location_undefined"><![CDATA[Location off]]></string>
+	<string name="_sys_log_db_err"><![CDATA[System: DB error log]]></string>
     <string name="_sys_macros_malformed"><![CDATA[Error: malformed macros]]></string>
     <string name="_sys_macros_malformed"><![CDATA[Error: malformed macros]]></string>
     <string name="_sys_macros_unsafe"><![CDATA[Error: unsafe macros]]></string>
     <string name="_sys_macros_unsafe"><![CDATA[Error: unsafe macros]]></string>
     <string name="_sys_macros_output_not_displayable"><![CDATA[Error: output isn't displayable]]></string>
     <string name="_sys_macros_output_not_displayable"><![CDATA[Error: output isn't displayable]]></string>

+ 2 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -1491,6 +1491,7 @@
     <string name="_adm_stg_cpt_option_sys_hide_post_to_context_for_privacy"><![CDATA[Скрыть из поля "Конфиденциальность" возможность добавления контента в контекст модулей]]></string>
     <string name="_adm_stg_cpt_option_sys_hide_post_to_context_for_privacy"><![CDATA[Скрыть из поля "Конфиденциальность" возможность добавления контента в контекст модулей]]></string>
     <string name="_adm_stg_cpt_option_sys_search_keyword_min_len"><![CDATA[Минимальная длина слова в поиске по сайту]]></string>
     <string name="_adm_stg_cpt_option_sys_search_keyword_min_len"><![CDATA[Минимальная длина слова в поиске по сайту]]></string>
     <string name="_adm_stg_cpt_option_sys_profile_bot"><![CDATA[Профиль системного бота]]></string>
     <string name="_adm_stg_cpt_option_sys_profile_bot"><![CDATA[Профиль системного бота]]></string>
+    <string name="_adm_stg_cpt_option_sys_logs_storage_default"><![CDATA[Система логирования по умолчанию]]></string>
 	<string name="_adm_stg_cpt_type_system"><![CDATA[Система]]></string>
 	<string name="_adm_stg_cpt_type_system"><![CDATA[Система]]></string>
 	<string name="_adm_stg_scs_save"><![CDATA[Настройки удачно сохранены]]></string>
 	<string name="_adm_stg_scs_save"><![CDATA[Настройки удачно сохранены]]></string>
 	<string name="_adm_stg_err_save_error_message"><![CDATA[Ошибка в '{0}': {1}]]></string>
 	<string name="_adm_stg_err_save_error_message"><![CDATA[Ошибка в '{0}': {1}]]></string>
@@ -2459,6 +2460,7 @@
 	<string name="_sys_location_determining"><![CDATA[Определение местоположения...]]></string>
 	<string name="_sys_location_determining"><![CDATA[Определение местоположения...]]></string>
 	<string name="_sys_location_geolocation_not_supported_by_browser"><![CDATA[Геолокация не поддерживается этим браузером]]></string>
 	<string name="_sys_location_geolocation_not_supported_by_browser"><![CDATA[Геолокация не поддерживается этим браузером]]></string>
 	<string name="_sys_location_undefined"><![CDATA[Отключить местоположение]]></string>
 	<string name="_sys_location_undefined"><![CDATA[Отключить местоположение]]></string>
+    <string name="_sys_log_db_err"><![CDATA[Система: логирование ошибок БД]]></string>
     <string name="_sys_macros_malformed"><![CDATA[Ошибка: некорректный макрос]]></string>
     <string name="_sys_macros_malformed"><![CDATA[Ошибка: некорректный макрос]]></string>
     <string name="_sys_macros_unsafe"><![CDATA[Ошибка: небезопасный макрос]]></string>
     <string name="_sys_macros_unsafe"><![CDATA[Ошибка: небезопасный макрос]]></string>
     <string name="_sys_macros_output_not_displayable"><![CDATA[Ошибка: некорректный вывод макроса]]></string>
     <string name="_sys_macros_output_not_displayable"><![CDATA[Ошибка: некорректный вывод макроса]]></string>

+ 43 - 0
samples/log.php

@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCoreSamples Samples
+ * @{
+ */
+
+/**
+ * @page samples
+ * @section logs Logs object
+ */
+
+$aPathInfo = pathinfo(__FILE__);
+require_once ($aPathInfo['dirname'] . '/../inc/header.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+
+$oTemplate = BxDolTemplate::getInstance();
+$oTemplate->setPageNameIndex (BX_PAGE_DEFAULT);
+$oTemplate->setPageHeader ("Logs");
+$oTemplate->setPageContent ('page_main_code', PageCompMainCode());
+$oTemplate->getPageCode();
+
+/**
+ * page code function
+ */
+function PageCompMainCode()
+{
+    ob_start();
+
+    $ret = null;
+    // if ($o = BxDolLogs::getObjectInstance('sys_db_err'))
+    //    $ret = $o->add('Hello world!');
+    $ret = bx_log('sys_db_err', 'Hello world3!');
+
+    var_dump($ret);
+
+    return DesignBoxContent("Logs", ob_get_clean(), BX_DB_PADDING_DEF);
+}
+
+/** @} */

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