Zikula_Core
[ class tree: Zikula_Core ] [ index: Zikula_Core ] [ all elements ]

Source for file LogUtil.class.php

Documentation is available at LogUtil.class.php

  1. <?php
  2. /**
  3.  * Zikula Application Framework
  4.  *
  5.  * @copyright Robert Gasch
  6.  * @link http://www.zikula.org
  7.  * @version $Id: LogUtil.class.php 24342 2008-06-06 12:03:14Z markwest $
  8.  * @license GNU/GPL - http://www.gnu.org/copyleft/gpl.html
  9.  * @author Robert Gasch rgasch@gmail.com
  10.  * @package Zikula_Core
  11.  */
  12.  
  13. /**
  14.  * LogUtil
  15.  *
  16.  * @package Zikula_Core
  17.  * @subpackage LogUtil
  18.  */
  19. class LogUtil
  20. {
  21.     /**
  22.      * Returns an array of status messages
  23.      *
  24.      * @param $override whether to override status messages with error messages
  25.      * @return array of messages
  26.      */
  27.     function getStatusMessages ($delete=true$override=true$reverse=true)
  28.     {
  29.         $msgs    SessionUtil::getVar('_PNStatusMsg'array());
  30.         $errs    SessionUtil::getVar('_PNErrorMsg'array());
  31.         if (!empty($errs&& $override{
  32.             $msgs $errs;
  33.         }
  34.  
  35.         if ($delete{
  36.             SessionUtil::delVar('_PNErrorMsg');
  37.             SessionUtil::delVar('_PNErrorMsgType');
  38.             SessionUtil::delVar('_PNStatusMsg');
  39.             SessionUtil::delVar('_PNStatusMsgType');
  40.         }
  41.  
  42.         if ($reverse{
  43.             $msgs array_reverse($msgstrue);
  44.         }
  45.  
  46.         return $msgs;
  47.     }
  48.  
  49.  
  50.     /**
  51.      * Returns a string of the available status messages, separated by the given delimeter
  52.      *
  53.      * @param $delimeter The string to use as the delimeter between the array of messages
  54.      * @param $override whether to override status messages with error messages
  55.      * @return string the generated error message
  56.      */
  57.     function getStatusMessagesText ($delimeter='<br />'$delete=true$override=true)
  58.     {
  59.         $msgs LogUtil::getStatusMessages ($delete$override);
  60.         return implode ($delimeter$msgs);
  61.     }
  62.  
  63.  
  64.     /**
  65.      * Get an array of error messages
  66.      *
  67.      * @return array of messages
  68.      */
  69.     function getErrorMessages ($delete=true$reverse=true)
  70.     {
  71.         $msgs SessionUtil::getVar('_PNErrorMsg'array());
  72.  
  73.         if ($delete{
  74.             SessionUtil::delVar('_PNErrorMsg');
  75.             SessionUtil::delVar('_PNErrorMsgType');
  76.         }
  77.  
  78.         if ($reverse{
  79.             $msgs array_reverse($msgstrue);
  80.         }
  81.  
  82.         return $msgs;
  83.     }
  84.  
  85.  
  86.     /**
  87.      * Get an error message text
  88.      *
  89.      * @param $delimeter The string to use as the delimeter between the array of messages
  90.      * @return string the generated error message
  91.      */
  92.     function getErrorMessagesText ($delimeter='<br />'$delete=true)
  93.     {
  94.         $msgs LogUtil::getErrorMessages ($delete);
  95.         return implode ($delimeter$msgs);
  96.     }
  97.  
  98.  
  99.     /**
  100.      * get the error type
  101.      *
  102.      * @return int error type
  103.      */
  104.     function getErrorType ()
  105.     {
  106.         return (int)SessionUtil::getVar('_PNErrorMsgType');
  107.     }
  108.  
  109.     /**
  110.      * check if errors
  111.      *
  112.      * @return int error type
  113.      */
  114.     function hasErrors ()
  115.     {
  116.         $msgs LogUtil::getErrorMessages (false);
  117.         return (bool)!empty($msgs);
  118.     }
  119.  
  120.     /**
  121.      * Set an error message text
  122.      *
  123.      * @param $message string the error message
  124.      * @return true 
  125.      */
  126.     function registerStatus ($message)
  127.     {
  128.         if (empty($message)) {
  129.             return pn_exit ('Empty message received ...');
  130.         }
  131.  
  132.         $msgs SessionUtil::getVar('_PNStatusMsg'array());
  133.         if (is_array($message)) {
  134.             $msgs array_merge($msgs$message);
  135.         else {
  136.             $msgs[DataUtil::formatForDisplayHTML($message);
  137.         }
  138.         SessionUtil::setVar('_PNStatusMsg'$msgs);
  139.         return true;
  140.     }
  141.  
  142.  
  143.     /**
  144.      * Register a failed authid check. This method calls registerError and
  145.      * then redirects back to the specified URL.
  146.      *
  147.      * @param $url       The URL to redirect to (optional) (default=null)
  148.      * @return false 
  149.      */
  150.     function registerAuthidError ($url=null)
  151.     {
  152.         return LogUtil::registerError (_BADAUTHKEYnull$url);
  153.     }
  154.  
  155.  
  156.     /**
  157.      * Register a failed permission check. This method calls registerError and
  158.      * then logs the failed permission check so that it can be analyzed later.
  159.      *
  160.      * @param $url       The URL to redirect to (optional) (default=null)
  161.      * @return false 
  162.      */
  163.     function registerPermissionError ($url=null)
  164.     {
  165.         static $strLevels array();
  166.         if (!$strLevels{
  167.             $strLevels[ACCESS_INVALID]  'INVALID';
  168.             $strLevels[ACCESS_NONE]     'NONE';
  169.             $strLevels[ACCESS_OVERVIEW'OVERVIEW';
  170.             $strLevels[ACCESS_READ]     'READ';
  171.             $strLevels[ACCESS_COMMENT]  'COMMENT';
  172.             $strLevels[ACCESS_MODERATE'MODERATE';
  173.             $strLevels[ACCESS_EDIT]     'EDIT';
  174.             $strLevels[ACCESS_ADD]      'ADD';
  175.             $strLevels[ACCESS_DELETE]   'DELETE';
  176.             $strLevels[ACCESS_ADMIN]    'ADMIN';
  177.         }
  178.  
  179.         global $PNRuntime;
  180.         $obj array();
  181.         $obj['component']      'PERMISSION';
  182.         $obj['sec_component']  $PNRuntime['security']['last_failed_check']['component'];
  183.         $obj['sec_instance']   $PNRuntime['security']['last_failed_check']['instance'];
  184.         $obj['sec_permission'$strLevels[$PNRuntime['security']['last_failed_check']['level']];
  185.  
  186.         LogUtil::_write (_MODULENOAUTH'PERMISSION'$obj);
  187.         return LogUtil::registerError (_MODULENOAUTH403$url);
  188.     }
  189.  
  190.  
  191.     /**
  192.      * Set an error message text. Also adds method, file and line where the error occured
  193.      *
  194.      * @param $message string the error message
  195.      * @param $type type of error (numeric and corresponding to a HTTP status code) (optional) (default=null)
  196.      * @param $url the url to redirect to (optional) (default=null)
  197.      * @return false 
  198.      */
  199.     function registerError ($message$type=null$url=null)
  200.     {
  201.         if (empty($message)) {
  202.             return pn_exit ('Empty message received ...');
  203.         }
  204.  
  205.         global $PNConfig;
  206.  
  207.         $showDetailInfo (defined('_PNINSTALLVER'|| ($PNConfig['System']['development'&& SecurityUtil::checkPermission('.*''.*'ACCESS_ADMIN)));
  208.  
  209.         if ($showDetailInfo{
  210.             $bt   debug_backtrace();
  211.             $cf0  $bt[0];
  212.             $cf1  = isset($bt[1]$bt[1array('function' => '''args' => '');
  213.             $file $cf0['file'];
  214.             $line $cf0['line'];
  215.             $func !empty($cf1['function']'['.$cf1['function'].']' '';
  216.             $args $cf1['args'];
  217.         else {
  218.             $func '';
  219.         }
  220.  
  221.         if (!$showDetailInfo{
  222.             $msg $message;
  223.         else {
  224.             $msg pnML('_ERROR_ADMIN'array('message' => $message'func' => $func'line' => $line'file' => $file)true);
  225.             if (defined('_PNINSTALLVER'&& $PNConfig['System']['development']{
  226.                 $msg .= '<br />';
  227.                 $msg .= _prayer (debug_backtrace());
  228.             }
  229.         }
  230.  
  231.         $msgs SessionUtil::getVar('_PNErrorMsg'array());
  232.         // no html encoding should be used here - not htmlentities nor DataUtil methods
  233.         // as the message *may* contain pre-formatted html
  234.         if (is_array($message)) {
  235.             $msgs array_merge($msgs$message);
  236.         else {
  237.             $msgs[$msg;
  238.         }
  239.         // note for bug #4439 - we dont want to pass messages through HTML tag
  240.         // filter, only ensure the HTML is valid since this is system generated
  241.         SessionUtil::setVar('_PNErrorMsg'$msgs);
  242.  
  243.         // check if we've got an error type
  244.         if (isset($type&& is_numeric($type)) {
  245.             SessionUtil::setVar('_PNErrorMsgType'$type);
  246.         }
  247.  
  248.         // check if we want to redirect
  249.         if ($url{
  250.             return pnRedirect($url);
  251.         }
  252.  
  253.         // since we're registering an error, it makes sense to return false here.
  254.         // This allows the calling code to just return the result of pnRegisterError
  255.         // if it wishes to return 'false' (which is what ususally happens).
  256.         return false;
  257.     }
  258.  
  259.  
  260.     /**
  261.      * Log the given messge under the given level
  262.      *
  263.      * @param msg      The message to log
  264.      * @param level    The log to log this message under
  265.      * @returns nothing
  266.      */
  267.     function log ($msg$level='DEFAULT')
  268.     {
  269.         global $PNConfig;
  270.         $haveConfig  count($PNConfig['Log']0;
  271.         $logLevels   $PNConfig['Log']['log_levels'];
  272.         $showErrors  $PNConfig['Log']['log_show_errors'];
  273.         $logUser     $PNConfig['Log']['log_user'];
  274.         $suid        SessionUtil::getVar('uid'0);
  275.  
  276.         if ($logUser && $logUser != $suid{
  277.             return;
  278.         }
  279.  
  280.         if (!$haveConfig{
  281.             print "<p><strong>Logging configuration can't be loaded .... logging is disabled</strong></p>";
  282.         }
  283.         elseif ($level == "ALL" && $showErrors == true{
  284.             print "<p><strong>You should not add an event log with log_level 'ALL'</strong></p>";
  285.         }
  286.         elseif (in_array($level,$logLevels|| in_array("ALL",$logLevels)) {
  287.             LogUtil::_write($msg$level);
  288.         }
  289.     }
  290.  
  291.  
  292.     /**
  293.      * Generate the filename of todays log file
  294.      *
  295.      * @returns the generated filename
  296.      */
  297.     function getLogFileName ($level=null)
  298.     {
  299.         global $PNConfig;
  300.         $logfileSpec $PNConfig['Log']['log_file'];
  301.         $dateFormat  $PNConfig['Log']['log_file_date_format'];
  302.  
  303.         if ($level && isset($PNConfig['Log']['log_level_files'][$level]&& $PNConfig['Log']['log_level_files'][$level]{
  304.             $logfileSpec $PNConfig['Log']['log_level_files'][$level];
  305.         }
  306.  
  307.         if (strpos($logfileSpec"%s"!== false)
  308.         {
  309.             if ($PNConfig['Log']['log_file_uid'])
  310.             {
  311.                 $perc  strpos ($logfileSpec'%s');
  312.                 $start substr ($logfileSpec0$perc+2);
  313.                 $end   substr ($logfileSpec$perc+2);
  314.                 $uid   SessionUtil::getVar('uid'0);
  315.  
  316.                 $logfileSpec $start '-%d' $end;
  317.                 $logfile sprintf($logfileSpecdate($dateFormat)$uid);
  318.             }
  319.             else {
  320.                 $logfile sprintf($logfileSpecdate($dateFormat));
  321.             }
  322.         }
  323.         else {
  324.           $logfile $logfileSpec;
  325.         }
  326.  
  327.         return $logfile;
  328.     }
  329.  
  330.  
  331.     /**
  332.      * Write the error message to the log file.
  333.      *
  334.      * Prints log file full error (if $log_show_errors is true)
  335.      *
  336.      * @param msg      The message to log
  337.      * @param level    The log level to log this message under
  338.      *
  339.      * @returns Logging file write error (file or directory unwritable) (if $log_show_errors is true)
  340.      */
  341.     function _write ($msg$level='DEFAULT'$securityInfo=null)
  342.     {
  343.         global $PNConfig;
  344.         $logEnabled $PNConfig['Log']['log_enabled'];
  345.         if (!$logEnabled{
  346.             return;
  347.         }
  348.  
  349.  
  350.         $logShowErr $PNConfig['Log']['log_show_errors'];
  351.         $logDateFmt $PNConfig['Log']['log_date_format'];
  352.         $logDest    $PNConfig['Log']['log_dest'];
  353.         $uid        SessionUtil::getVar('uid'1);
  354.         $module     pnModGetName();
  355.         $type       FormUtil::getPassedValue ('type''user''GETPOST');
  356.         $func       FormUtil::getPassedValue ('func''main''GETPOST');
  357.  
  358.         if ($level && isset($PNConfig['Log']['log_level_dest'][$level]&& $PNConfig['Log']['log_level_dest'][$level]{
  359.             $logDest $PNConfig['Log']['log_level_dest'][$level];
  360.         }
  361.  
  362.         // permission to be logged to DB or FILE
  363.         if ($level == 'PERMISSION' && ($logDest!='DB' && $logDest!='FILE')) {
  364.             $logDest 'DB';
  365.         }
  366.  
  367.         $logDest strtoupper ($logDest);
  368.  
  369.         $logline '';
  370.         if ($logDest == 'FILE'{
  371.             $title date($logDateFmt", level=$level, uid=$uid, module=$module, type=$type, func=$func\n";
  372.             if ($securityInfo)
  373.                 $title .= "++ sec_component=$securityInfo[sec_component], sec_instance=$securityInfo[sec_instance], sec_permission=$securityInfo[sec_permission]\n";
  374.             $logline '+ ' $title;
  375.         }
  376.         $logline .= "$msg\n\n";
  377.  
  378.         if ($logDest == 'FILE')
  379.         {
  380.             static $logfile '';
  381.             if (!$logfile{
  382.                 $logfile   LogUtil::getLogFileName($level);
  383.             }
  384.  
  385.             $logfileOK LogUtil::_checkLogFile($logfile$level$reason);
  386.             if ($logfileOK{
  387.                 $fp fopen($logfile'a');
  388.                 fwrite ($fp$loglinestrlen($logline));
  389.                 fclose ($fp);
  390.             }
  391.             elseif ($logShowErr{
  392.                 if ($reason == 'NOWRITE'{
  393.                     print "<p><strong>Logging Disabled. Log file ($logfile) unwritable.</strong></p>";
  394.                 }
  395.                 elseif ($reason == 'TOOBIG'{
  396.                     print "<p><strong>Log file ($logfile) is full.</strong></p>";
  397.                 }
  398.             }
  399.         }
  400.         elseif ($logDest == 'PRINT'{
  401.             print '<div class="pn-sub" style="text-align:left;">' $logline '</div>';
  402.             //print $msg;
  403.         }
  404.         elseif ($logDest == 'MAIL'{
  405.             $title date($logDateFmt", level=$level, uid=$uid\n";
  406.             $adminmail pnConfigGetVar('adminmail');
  407.  
  408.             $args array();
  409.             $args['fromname']    'Zikula ' pnConfigGetVar('slogan''Site Slogan');
  410.             $args['fromaddress'$adminmail;
  411.             $args['toname']      'Site Administrator';
  412.             $args['toaddress']   $adminmail;
  413.             $args['subject']     "Log Message: level=$level, uid=$uid";
  414.             $args['body']        $logline;
  415.  
  416.             $rc pnModFunc ('Mailer''userapi''sendmessage'$args);
  417.         }
  418.         elseif ($logDest == 'DB'{
  419.             $obj array();
  420.             $obj['date']      date($logDateFmt);
  421.             $obj['uid']       $uid;
  422.             $obj['component'$level;
  423.             $obj['module']    $module;
  424.             $obj['type']      $type;
  425.             $obj['function']  $func;
  426.             $obj['message']   $msg;
  427.  
  428.             if ($securityInfo && is_array($securityInfo)) {
  429.                 $obj array_merge ($obj$securityInfo);
  430.             }
  431.  
  432.             if (pnModDBInfoLoad ('SecurityCenter')) {
  433.                 if (!DBUtil::insertObject ($obj'sc_logevent')) {
  434.                     print '<div class="pn-sub" style="text-align:left;">';
  435.                     print 'Failed to insert log record into log_event table<br />';
  436.                     prayer ($obj);
  437.                     print '</div>';
  438.                 }
  439.             else {
  440.                 print 'Failed to load logging table definition from SecurityCenter module<br />';
  441.             }
  442.         else {
  443.             print "Unknown log destination [$logDest] ... ";
  444.         }
  445.     }
  446.  
  447.  
  448.     /**
  449.      * Check the log file is writable and not full.
  450.      *
  451.      * returns unwritable The file or directory cannot be written to
  452.      * returns toobig The log file size is bigger than $log_length in logging.conf.php.
  453.      *
  454.      * @returns boolean Whether or not the file is ready for writing
  455.      */
  456.     function _checkLogFile($logfile$level&$reason)
  457.     {
  458.         global $PNConfig;
  459.         $logSize $PNConfig['Log']['log_maxsize'];
  460.  
  461.         if (!$logfile{
  462.             $logfile LogUtil::getLogFileName($level);
  463.         }
  464.  
  465.         $size 0;
  466.         $rc   false;
  467.  
  468.         if (file_exists($logfile)) {
  469.             $size filesize($logfile1024 1024;
  470.         }
  471.  
  472.         if (file_exists($logfile&& is_writable($logfile)) {
  473.             $rc true;
  474.         }
  475.         elseif (!file_exists($logfile))
  476.         {
  477.             @touch ($logfile);
  478.             if (file_exists($logfile)) {
  479.                 chmod ($logfile0755);
  480.                 $rc true;
  481.             else {
  482.                 SessionUtil::setVar('_PNStatusMsg'"Unable to create log file [$logfile] ...");
  483.                 $reason 'NOWRITE';
  484.             }
  485.         elseif ($logSize && $size $logSize{
  486.             SessionUtil::setVar('_PNStatusMsg'"Logfile [$logfile] size [$size] exceeds [$logSize] ...");
  487.             $reason 'TOOBIG';
  488.         }
  489.  
  490.         return $rc;
  491.     }
  492.  
  493.     /**
  494.      * Cleans up unneeded old log files
  495.      *
  496.      */
  497.     function _cleanLogFiles()
  498.     {
  499.         if (defined('_PNINSTALLVER')) {
  500.             return;
  501.         }
  502.  
  503.         global $PNConfig;
  504.  
  505.         $oneday 24 60 60;
  506.         $log_keep_days $PNConfig['Log']['log_keep_days'];
  507.         if (!$log_keep_days$log_keep_days 30// temporary default value for migration
  508.  
  509.         $log_keep_seconds $log_keep_days $oneday;
  510.         $lastcheck pnConfigGetVar('log_last_rotate');
  511.         $currenttime time();
  512.  
  513.         if (time($lastcheck $oneday{
  514.             // check once a day
  515.             Loader::loadClass('FileUtil');
  516.             $logfilepath $PNConfig['Log']['log_dir'];
  517.             $logfiles FileUtil::getFiles($logfilepathfalsefalse);
  518.             foreach($logfiles as $logfile{
  519.                 if ($currenttime filemtime($logfile$log_keep_seconds{
  520.                     unlink($logfile);
  521.                 }
  522.             }
  523.             pnConfigSetVar('log_last_rotate'$currenttime);
  524.         }
  525.     }
  526.  
  527. }

Documentation generated on Fri, 18 Jul 2008 21:47:40 +0200 by phpDocumentor 1.4.1