diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php index 18de8bf6bfc..c1fc11add9b 100644 --- a/htdocs/admin/syslog.php +++ b/htdocs/admin/syslog.php @@ -81,33 +81,32 @@ if ($action == 'set') { $db->begin(); - $activeModules = array(); + $newActiveModules = array(); $selectedModules = (isset($_POST['SYSLOG_HANDLERS']) ? $_POST['SYSLOG_HANDLERS'] : array()); - - foreach ($selectedModules as $syslogHandler) + //var_dump($selectedModules); + foreach ($syslogModules as $syslogHandler) { if (in_array($syslogHandler, $syslogModules)) { $module = new $syslogHandler; - if ($module->isActive()) + if (in_array($syslogHandler, $selectedModules)) $newActiveModules[] = $syslogHandler; + foreach ($module->configure() as $option) { - $activeModules[] = $syslogHandler; - - foreach ($module->configure() as $option) + if (isset($_POST[$option['constant']])) { - if ($_POST[$option['constant']]) - { - dolibarr_del_const($db, $option['constant'], 0); - dolibarr_set_const($db, $option['constant'], $_POST[$option['constant']], 'chaine',0, '', 0); - } + $_POST[$option['constant']] = trim($_POST[$option['constant']]); + dolibarr_del_const($db, $option['constant'], 0); + dolibarr_set_const($db, $option['constant'], $_POST[$option['constant']], 'chaine',0, '', 0); } } } } + $activeModules = $newActiveModules; dolibarr_set_const($db, 'SYSLOG_HANDLERS', json_encode($activeModules), 'chaine',0,'',0); + if (! $error) { $db->commit(); @@ -165,6 +164,9 @@ if ($conf->global->MAIN_MODULE_MULTICOMPANY && $user->entity) $option = 'disabled="disabled"'; } + +//print "conf->global->MAIN_FEATURES_LEVEL = ".$conf->global->MAIN_FEATURES_LEVEL."

\n"; + // Output mode print_titre($langs->trans("SyslogOutput")); @@ -190,7 +192,7 @@ foreach ($syslogModules as $moduleName) $var=!$var; print ''; print ''; - print ' '; + print ' '; print $module->getName(); print ''; @@ -205,6 +207,7 @@ foreach ($syslogModules as $moduleName) else $value = (isset($option['default']) ? $option['default'] : ''); print $option['name'].': '; + if (! empty($option['example'])) print '
'.$langs->trans("Example").': '.$option['example']; } } print ''; diff --git a/htdocs/core/modules/syslog/mod_syslog_chromephp.php b/htdocs/core/modules/syslog/mod_syslog_chromephp.php index 06d37dfa431..ca257e6b0f6 100644 --- a/htdocs/core/modules/syslog/mod_syslog_chromephp.php +++ b/htdocs/core/modules/syslog/mod_syslog_chromephp.php @@ -42,7 +42,7 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface /** * Is the module active ? * - * @return boolean + * @return int */ public function isActive() { @@ -51,8 +51,13 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface { if (empty($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH)) $conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH='/usr/share/php'; set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH); - $res = @include_once 'ChromePhp.class.php'; + + //print 'rrrrr'.get_include_path(); + $res = include_once('ChromePhp.php'); + if (! $res) $res=@include_once('ChromePhp.class.php'); + restore_include_path(); + if ($res) { return 1; @@ -77,10 +82,11 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface return array( array( - 'name' => $langs->trans('IncludePath'), + 'name' => $langs->trans('IncludePath','SYSLOG_CHROMEPHP_INCLUDEPATH'), 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', 'default' => '/usr/share/php', - 'attr' => 'size="40"' + 'attr' => 'size="60"', + 'example' => DOL_DOCUMENT_ROOT.'/includes/chromephp' ) ); } @@ -92,16 +98,17 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface */ public function checkConfiguration() { - global $langs; + global $langs,$conf; $errors = array(); $oldinclude = get_include_path(); - set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); + set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH); if (!file_exists('ChromePhp.class.php')) { $errors[] = $langs->trans("ErrorFailedToOpenFile", 'ChromePhp.class.php'); + $errors[] = $langs->trans("IncludePath").' : '.get_include_path(); } set_include_path($oldinclude); @@ -129,7 +136,7 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface // Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from // database or config file because we must be able to log data before database or config file read. $oldinclude=get_include_path(); - set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); + set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH); include_once 'ChromePhp.class.php'; set_include_path($oldinclude); ob_start(); // To be sure headers are not flushed until all page is completely processed diff --git a/htdocs/core/modules/syslog/mod_syslog_file.php b/htdocs/core/modules/syslog/mod_syslog_file.php index 331b7331194..318fe30d4f0 100644 --- a/htdocs/core/modules/syslog/mod_syslog_file.php +++ b/htdocs/core/modules/syslog/mod_syslog_file.php @@ -45,11 +45,11 @@ class mod_syslog_file extends LogHandler implements LogHandlerInterface /** * Is the module active ? * - * @return boolean + * @return int */ public function isActive() { - return true; + return 1; } /** diff --git a/htdocs/core/modules/syslog/mod_syslog_firephp.php b/htdocs/core/modules/syslog/mod_syslog_firephp.php index 31a3fb13431..013b5de85a7 100644 --- a/htdocs/core/modules/syslog/mod_syslog_firephp.php +++ b/htdocs/core/modules/syslog/mod_syslog_firephp.php @@ -42,7 +42,7 @@ class mod_syslog_firephp extends LogHandler implements LogHandlerInterface /** * Is the module active ? * - * @return boolean + * @return int */ public function isActive() { @@ -53,7 +53,7 @@ class mod_syslog_firephp extends LogHandler implements LogHandlerInterface restore_include_path(); if ($res) { - return true; + return 1; } } catch(Exception $e) @@ -61,7 +61,7 @@ class mod_syslog_firephp extends LogHandler implements LogHandlerInterface print ''."\n"; } - return false; + return -1; } ///** diff --git a/htdocs/core/modules/syslog/mod_syslog_syslog.php b/htdocs/core/modules/syslog/mod_syslog_syslog.php index 58ac241695c..a342114a33f 100644 --- a/htdocs/core/modules/syslog/mod_syslog_syslog.php +++ b/htdocs/core/modules/syslog/mod_syslog_syslog.php @@ -42,14 +42,14 @@ class mod_syslog_syslog extends LogHandler implements LogHandlerInterface /** * Is the module active ? * - * @return boolean + * @return int */ public function isActive() { // This function does not exists on some ISP (Ex: Free in France) - if (!function_exists('openlog')) return false; + if (!function_exists('openlog')) return 0; - return true; + return 1; } /** diff --git a/htdocs/includes/chromephp/ChromePhp.php b/htdocs/includes/chromephp/ChromePhp.php new file mode 100644 index 00000000000..577b1cecb9d --- /dev/null +++ b/htdocs/includes/chromephp/ChromePhp.php @@ -0,0 +1,446 @@ + + */ +class ChromePhp +{ + /** + * @var string + */ + const VERSION = '4.1.0'; + + /** + * @var string + */ + const HEADER_NAME = 'X-ChromeLogger-Data'; + + /** + * @var string + */ + const BACKTRACE_LEVEL = 'backtrace_level'; + + /** + * @var string + */ + const LOG = 'log'; + + /** + * @var string + */ + const WARN = 'warn'; + + /** + * @var string + */ + const ERROR = 'error'; + + /** + * @var string + */ + const GROUP = 'group'; + + /** + * @var string + */ + const INFO = 'info'; + + /** + * @var string + */ + const GROUP_END = 'groupEnd'; + + /** + * @var string + */ + const GROUP_COLLAPSED = 'groupCollapsed'; + + /** + * @var string + */ + const TABLE = 'table'; + + /** + * @var string + */ + protected $_php_version; + + /** + * @var int + */ + protected $_timestamp; + + /** + * @var array + */ + protected $_json = array( + 'version' => self::VERSION, + 'columns' => array('log', 'backtrace', 'type'), + 'rows' => array() + ); + + /** + * @var array + */ + protected $_backtraces = array(); + + /** + * @var bool + */ + protected $_error_triggered = false; + + /** + * @var array + */ + protected $_settings = array( + self::BACKTRACE_LEVEL => 1 + ); + + /** + * @var ChromePhp + */ + protected static $_instance; + + /** + * Prevent recursion when working with objects referring to each other + * + * @var array + */ + protected $_processed = array(); + + /** + * constructor + */ + private function __construct() + { + $this->_php_version = phpversion(); + $this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time(); + $this->_json['request_uri'] = $_SERVER['REQUEST_URI']; + } + + /** + * gets instance of this class + * + * @return ChromePhp + */ + public static function getInstance() + { + if (self::$_instance === null) { + self::$_instance = new self(); + } + return self::$_instance; + } + + /** + * logs a variable to the console + * + * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] + * @return void + */ + public static function log() + { + $args = func_get_args(); + return self::_log('', $args); + } + + /** + * logs a warning to the console + * + * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] + * @return void + */ + public static function warn() + { + $args = func_get_args(); + return self::_log(self::WARN, $args); + } + + /** + * logs an error to the console + * + * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] + * @return void + */ + public static function error() + { + $args = func_get_args(); + return self::_log(self::ERROR, $args); + } + + /** + * sends a group log + * + * @param string value + */ + public static function group() + { + $args = func_get_args(); + return self::_log(self::GROUP, $args); + } + + /** + * sends an info log + * + * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] + * @return void + */ + public static function info() + { + $args = func_get_args(); + return self::_log(self::INFO, $args); + } + + /** + * sends a collapsed group log + * + * @param string value + */ + public static function groupCollapsed() + { + $args = func_get_args(); + return self::_log(self::GROUP_COLLAPSED, $args); + } + + /** + * ends a group log + * + * @param string value + */ + public static function groupEnd() + { + $args = func_get_args(); + return self::_log(self::GROUP_END, $args); + } + + /** + * sends a table log + * + * @param string value + */ + public static function table() + { + $args = func_get_args(); + return self::_log(self::TABLE, $args); + } + + /** + * internal logging call + * + * @param string $type + * @return void + */ + protected static function _log($type, array $args) + { + // nothing passed in, don't do anything + if (count($args) == 0 && $type != self::GROUP_END) { + return; + } + + $logger = self::getInstance(); + + $logger->_processed = array(); + + $logs = array(); + foreach ($args as $arg) { + $logs[] = $logger->_convert($arg); + } + + $backtrace = debug_backtrace(false); + $level = $logger->getSetting(self::BACKTRACE_LEVEL); + + $backtrace_message = 'unknown'; + if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) { + $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line']; + } + + $logger->_addRow($logs, $backtrace_message, $type); + } + + /** + * converts an object to a better format for logging + * + * @param Object + * @return array + */ + protected function _convert($object) + { + // if this isn't an object then just return it + if (!is_object($object)) { + return $object; + } + + //Mark this object as processed so we don't convert it twice and it + //Also avoid recursion when objects refer to each other + $this->_processed[] = $object; + + $object_as_array = array(); + + // first add the class name + $object_as_array['___class_name'] = get_class($object); + + // loop through object vars + $object_vars = get_object_vars($object); + foreach ($object_vars as $key => $value) { + + // same instance as parent object + if ($value === $object || in_array($value, $this->_processed, true)) { + $value = 'recursion - parent object [' . get_class($value) . ']'; + } + $object_as_array[$key] = $this->_convert($value); + } + + $reflection = new ReflectionClass($object); + + // loop through the properties and add those + foreach ($reflection->getProperties() as $property) { + + // if one of these properties was already added above then ignore it + if (array_key_exists($property->getName(), $object_vars)) { + continue; + } + $type = $this->_getPropertyKey($property); + + if ($this->_php_version >= 5.3) { + $property->setAccessible(true); + } + + try { + $value = $property->getValue($object); + } catch (ReflectionException $e) { + $value = 'only PHP 5.3 can access private/protected properties'; + } + + // same instance as parent object + if ($value === $object || in_array($value, $this->_processed, true)) { + $value = 'recursion - parent object [' . get_class($value) . ']'; + } + + $object_as_array[$type] = $this->_convert($value); + } + return $object_as_array; + } + + /** + * takes a reflection property and returns a nicely formatted key of the property name + * + * @param ReflectionProperty + * @return string + */ + protected function _getPropertyKey(ReflectionProperty $property) + { + $static = $property->isStatic() ? ' static' : ''; + if ($property->isPublic()) { + return 'public' . $static . ' ' . $property->getName(); + } + + if ($property->isProtected()) { + return 'protected' . $static . ' ' . $property->getName(); + } + + if ($property->isPrivate()) { + return 'private' . $static . ' ' . $property->getName(); + } + } + + /** + * adds a value to the data array + * + * @var mixed + * @return void + */ + protected function _addRow(array $logs, $backtrace, $type) + { + // if this is logged on the same line for example in a loop, set it to null to save space + if (in_array($backtrace, $this->_backtraces)) { + $backtrace = null; + } + + // for group, groupEnd, and groupCollapsed + // take out the backtrace since it is not useful + if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) { + $backtrace = null; + } + + if ($backtrace !== null) { + $this->_backtraces[] = $backtrace; + } + + $row = array($logs, $backtrace, $type); + + $this->_json['rows'][] = $row; + $this->_writeHeader($this->_json); + } + + protected function _writeHeader($data) + { + header(self::HEADER_NAME . ': ' . $this->_encode($data)); + } + + /** + * encodes the data to be sent along with the request + * + * @param array $data + * @return string + */ + protected function _encode($data) + { + return base64_encode(utf8_encode(json_encode($data))); + } + + /** + * adds a setting + * + * @param string key + * @param mixed value + * @return void + */ + public function addSetting($key, $value) + { + $this->_settings[$key] = $value; + } + + /** + * add ability to set multiple settings in one call + * + * @param array $settings + * @return void + */ + public function addSettings(array $settings) + { + foreach ($settings as $key => $value) { + $this->addSetting($key, $value); + } + } + + /** + * gets a setting + * + * @param string key + * @return mixed + */ + public function getSetting($key) + { + if (!isset($this->_settings[$key])) { + return null; + } + return $this->_settings[$key]; + } +} diff --git a/htdocs/includes/chromephp/README.md b/htdocs/includes/chromephp/README.md new file mode 100644 index 00000000000..3dd7dbe19dd --- /dev/null +++ b/htdocs/includes/chromephp/README.md @@ -0,0 +1,23 @@ +## Overview +ChromePhp is a PHP library for the Chrome Logger Google Chrome extension. + +This library allows you to log variables to the Chrome console. + +## Requirements +- PHP 5 or later + +## Installation +1. Install the Chrome extension from: https://chrome.google.com/extensions/detail/noaneddfkdjfnfdakjjmocngnfkfehhd +2. Click the extension icon in the browser to enable it for the current tab's domain +3. Put ChromePhp.php somewhere in your PHP include path +4. Log some data + + ```php + include 'ChromePhp.php'; + ChromePhp::log('Hello console!'); + ChromePhp::log($_SERVER); + ChromePhp::warn('something went wrong!'); + ``` + +More information can be found here: +http://www.chromelogger.com diff --git a/htdocs/includes/chromephp/composer.json b/htdocs/includes/chromephp/composer.json new file mode 100644 index 00000000000..dc16853d3ec --- /dev/null +++ b/htdocs/includes/chromephp/composer.json @@ -0,0 +1,24 @@ +{ + "name": "ccampbell/chromephp", + "type": "library", + "description": "Log variables to the Chrome console (via Chrome Logger Google Chrome extension).", + "keywords": ["log","logging"], + "homepage": "http://github.com/ccampbell/chromephp", + "license": "Apache-2.0", + "authors": [ + { + "name": "Craig Campbell", + "email": "iamcraigcampbell@gmail.com", + "homepage": "http://craig.is", + "role": "Developer" + } + ], + "require": { + "php": ">=5.0.0" + }, + "autoload": { + "psr-0": { + "ChromePhp": "" + } + } +} diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index d262b835794..59579237d33 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1558,3 +1558,4 @@ SalariesSetup=Setup of module salaries SortOrder=Sort order Format=Format TypePaymentDesc=0:Customer payment type, 1:Supplier payment type, 2:Both customers and suppliers payment type +IncludePath=Include path (defined into variable %s) \ No newline at end of file