1 <?php
2 
3 use dokuwiki\Logger;
4 
5 class siteexport_debug
6 {
7     private $firstRE = true;
8 
9     private $debugLevel = 5;
10     private $debugFile = '';
11     public  $isAJAX = false;
12 
13     public $runtimeErrors = '';
14 
15     private $logger;
16 
17     /**
18      * constructor for the debug class
19      */
20     public function __construct() {
21        $this->logger = Logger::getInstance('siteexport');
22     }
23 
24     /**
25      * Debug Level
26      * the level of what should be logged during the proxied session.
27      * To activate the logging, you have to enter a loglevel below 5 (see below) to log
28      * to the screen. If you use the debugFile option the logstream will be rerouted
29      * to this file.
30      *
31      * Default: 5 / No logging
32      *
33      * Available DEBUG Levels:
34      *  5 = off      - only socket exceptions will be shown to avoid blank pages
35      *  4 = ERROR    - Log errors of the proxy process
36      *  3 = WARN     - Log warnings during the proxy process
37      *  2 = INFO     - Log information about the ongoing connection process
38      *  1 = DEBUG    - detailed log about variable states
39      *  0 = VERBOSE  - Additionally logs the reponse body from the server
40      *
41      * @param $level
42      */
43     public function setDebugLevel($level = 5)
44     {
45         $this->debugLevel = $level;
46     }
47 
48     public function debugLevel()
49     {
50         return $this->debugLevel;
51     }
52 
53     /**
54      * Set a valid and writeable filename to have the debug information written into a file
55      * Set the debugLevel below 5 to enable the debugging.
56      *
57      * e.g. $CC->debugFile = '/temp/ccproxy.txt';
58      * e.g. $CC->debugFile = 'C:\temp\ccproxy.txt';
59      */
60     public function setDebugFile($file = null)
61     {
62         if (!$file || empty($file))
63         {
64             $file = null;
65         }
66 
67         $this->debugFile = $file;
68     }
69 
70     public function firstRE()
71     {
72         return $this->firstRE;
73     }
74 
75     /**
76      * print debug info to file if exists
77      */
78     public function message($info,$var=null,$level=4){
79 
80         $ajaxCanLog = $this->isAJAX && $level == 4;
81         $fh = false;
82 
83         if( $this->debugLevel > $level && !$ajaxCanLog  ) return; // only log certain Debug Levels
84 
85         switch($level) {
86             case 4: $this->logger->error( $info, $var ); break;
87             case 3: $this->logger->log( $info, $var ); break;
88             case 2: $this->logger->log( $info, $var ); break;
89             case 1: $this->logger->debug( $info, $var ); break;
90             default: $TYPE = " NONE"; break;
91         }
92 
93         if ( empty($this->debugFile) ) {
94             $this->runtimeException("DebugFile not properly configured. Make sure, it is set, readable and writable. We suggest to use a file in the DokuWiki's media directory.", true);
95             $this->debugLevel = 5; // shutdown debug
96         } else {
97             $fh = @fopen($this->debugFile, "a+");
98             if ( !$fh && !$ajaxCanLog ) {
99                 $this->runtimeException("Could not create/open/append logfile: '{$this->debugFile}'", true);
100                 $this->debugLevel = 5; // shutdown debug
101                 return;
102             }
103         }
104 
105         switch($level) {
106             case 4: $TYPE = "ERROR"; break;
107             case 3: $TYPE = " WARN"; break;
108             case 2: $TYPE = " INFO"; break;
109             case 1: $TYPE = "DEBUG"; break;
110             default: $TYPE = " NONE"; break;
111         }
112 
113         $prepend = "[" . (date('Y-m-d H:i:s') ?: "") . " $TYPE] ";
114         $log = $prepend . str_replace("\n", "\n" . $prepend . "\t", trim($info)) . "\n";
115 
116         if ( $fh !== false ) {
117             fwrite($fh, $log);
118         }
119         if ( $ajaxCanLog ) {
120             if ( !headers_sent() ) {
121                 header("HTTP/1.0 500 Internal Server Error", true, 500);
122                 header("Status: 500 Internal Server Error", true, 500);
123             }
124             echo $log;
125         }
126 
127         if ( !empty($var) ) {
128 
129             if ( is_array($var) ) {
130                 ob_start();
131                 print_r($var);
132                 $content = ob_get_contents();
133                 ob_end_clean();
134             } else {
135                 $content = $var;
136             }
137 
138             $log = $prepend . "\t" . str_replace("\n", "\n" . $prepend . "\t", str_replace("\r\n", "\n", trim($content))) . "\n";
139             if ( $fh ) {
140                 fwrite($fh, $log);
141             }
142             if ( $ajaxCanLog ) {
143                 echo $log;
144             }
145         }
146 
147         if ( $fh ) {
148             fclose($fh);
149         }
150     }
151 
152     public function runtimeException($message, $wasDebug=false) {
153 
154         if ( empty($message) ) { return; }
155 
156         if ( !$this->isAJAX ) {
157             ob_start();
158         } else if ( !headers_sent() ) {
159             header("HTTP/1.0 500 Internal Server Error", true, 500);
160             header("Status: 500 Internal Server Error", true, 500);
161         }
162 
163         if ( !$this->isAJAX ) {
164             if ( $this->firstRE ) {
165                 print 'Runtime Error' . "\n";
166             }
167 
168             print '<b>'.$message.'</b><br />' . "\n";
169             if ( $this->firstRE ) {
170                 print '<b>If this error persists, please contact the server administrator.</b><br />' . "\n";
171             }
172         } else {
173             if ( !$wasDebug ) {
174                 $this->message('Runtime Error: ' . $message, null, 4);
175             } else {
176                 print 'Runtime Error: ' . $message . "\n";
177             }
178         }
179 
180         $this->firstRE = false;
181 
182         if (!$this->isAJAX) {
183             $this->runtimeErrors .= ob_get_contents();
184             ob_end_clean();
185         }
186 
187         return;
188     }
189 }
190