This page lets you view source code from my server. The program uses a brute force code formatter to color code elements. NOTE: I wrote this program while trying to learn the vim text editor. This is not my usual coding style.
Use this select box to select a file.
Program displays the PHP code used for my web site
Below is the code all formatted with bright colors. The program links to files opened with include() and expands those opened with require(). Clicking on the require line should change visibility. You can view the database schema with schema viewer.
Code Viewer
001 <!DOCTYPE html> <html lang="en">
002 <head>
003 <meta charset="UTF-8" />
004 <meta name="viewport" content="width=device-width, initial-scale=1" />
005 <meta name="Author" content="Kevin Delaney" />
006 <?php
007 // We break into PHP to get the data we need to print the header.
008 // These are the buttons we use to navigate the script:
009 const TEST_BTN = 'Test Button';
010 const SHOW_SCRIPT_BTN = 'Show Script';
011 const BLOB_BTN = 'Process Text';
012 // scrub the user input
013 $scriptNo = (isset($_REQUEST['script']))? (int) $_REQUEST['script'] : 1;
014 $btn = (isset($_REQUEST['btn']))? $_REQUEST['btn'] : '';
015 $filetime = '';
016 $md5 = '';
017 // options 1 = show line numbers, 2=no lines, 3=raw
018 $lineOpt = (isset($_POST['lines']))? $_POST['lines'] : 1;
019 // rmHead opens a database connection and functions for querying the database.
020 // functions include msgNote, dbConn, sqlRow, and sqlArr.
021 $page_id=113;
022 include('/var/www/php/rmHead.php'); // there should be a link in the include.
023 dbConn(DB_MAIN,'+code'); // attach the code database.
024 $sql = 'SELECT hit_cnt, display_cd, program_nm, code_path,
025 url, keywords, short_desc
026 FROM code.Code_Viewer
027 WHERE code_id = ?';
028
029 list($hit_cnt, $display_cd, $program_nm, $code_path,
030 $url, $keywords, $short_desc) = sqlRow($sql,[$scriptNo]);
031 // Update Page Count
032 if ($hit_cnt !== false) {
033 sqlExec('UPDATE code.Code_Viewer SET hit_cnt=hit_cnt+1 WHERE code_id=?',[$scriptNo]);
034 }
035 $pageTitle = ($btn==BLOB_BTN)? 'User Input' : $program_nm;
036 $scriptStr = ($scriptNo > 0)? '?script='.$scriptNo : '';
037 echo ' <meta name="keywords" content="'.htmlentities($keywords).'" /> '.PHP_EOL;
038 echo ' <meta name="description" content="'.htmlentities($short_desc).'" />'.PHP_EOL;
039 echo ' <title>View Source Code - '.htmlentities($pageTitle).'</title>'.PHP_EOL;
040
041 $scriptStr = ($scriptNo > 0)? '?script='.$scriptNo : '';
042 echo ' <link rel="canonical" href="http://prog.communitycolor.com/view.php'.$scriptStr.'" />'.PHP_EOL;
043 ?>
044 <link rel="stylesheet" href="/css/rm.css" type="text/css">
045 <script type="text/javascript">
046 function toggle_visibility(id) {
047 var e = document.getElementById(id);
048 if(e.style.display == 'none')
049 e.style.display = 'block';
050 else
051 e.style.display = 'none';
052 }
053 </script>
054 </head>
055 <body>
056 <h1 id="pageTitle"><a href="http://prog.communitycolor.com.com/">Community Color - Source Code</a></h1>
057 <!-- The most critical part of any web page is the Ad!, without the ad we perish -->
058 <div class="ad">
059 <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
060 <!-- Community Color - Responsive -->
061 <ins class="adsbygoogle"
062 style="display:block"
063 data-ad-client="ca-pub-7057064824800338"
064 data-ad-slot="2750777545"
065 data-ad-format="auto"></ins>
066 <script>
067 (adsbygoogle = window.adsbygoogle || []).push({});
068 </script>
069 </div>
070 <div class="wider">
071 <h2>Source Code Viewer</h2>
072 <p>This page lets you view source code from my server. The program uses a brute force code formatter to color code elements. NOTE: I wrote this program while trying to learn the <b>vim</b> text editor. This is not my usual coding style.</p>
073 <p>Use this select box to select a file.</p>
074 <form action="http://prog.communitycolor.com/view.php" method="post">
075 <?php
076 // we pop back into PHP for the main program. The code viewer expands the contents of
077 // files attached with the require statement, which you can hide by clicking on the line.
require('/var/www/php/codeFormatter.php');001 <?php
002 /**
003 * This is a brute force program for displaying HTML & PHP code in vivid color.
004 *
005 * @see https://yintercept.com/resources/view.php
006 *
007 * NOTE: I wrote this program while trying to learn the vim editor This is
008 * an example of flow-of-concious programming. But it does what I want.
009 *
010 * The program looks at each character in a program. The flow constrol variable
011 * $fc keeps track of where you are in the code.
012 *
013 * It embeds links called with require() inline and links to include() programs
014 *
015 * The program can show line numbers, although they really just get in the way.
016 *
017 * 2015/12/29 I discovered that there is a professional program called docBlock
018 * for formatting comments. I adopted their keyword style.
019 *
020 * @version 0.4
021 * @author Kevin Delaney
022 * @copyright 2015 Kevin Delaney
023 * @license https://yintercept.com/resources/license.html
024 */
025 // These are the values for the flow control character
026 const IN_HTML = 0;
027 const IN_TAG = 1; // in tag def section
028 const IN_ATTR = 2; // in tag attribute section
029 const IN_ATXT = 3; // in attribute text.
030 const IN_CSS = 10; // not implemented at the moment.
031 const IN_PHP = 20;
032 const IN_PVAR = 21;
033 const IN_PTXT = 22;
034 const IN_PCMT = 23;
035 const IN_DBLK = 24; // processing a docBlock tag
036 const IN_SCRIPT = 30; // not implemented yet
037 // PHP variables match the following pattern.
038 const VAR_PATTERN = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/';
039 class codeFormatter {
040 private $fc; // The section of code determines flow control
041 private $word; // The current word
042 private $closeTag; // holds the current close tag.
043 private $showNo = true;
044 private $lineNo = 0; // Counts the lines in the code.
045 private $lineStr = '';
046 private $closer='';
047 // I did not design program for recursion; So I will buffer the output
048 // and reassemble before echoing.
049 private $buffer = 0; //number of the active buffer
050 private $buffCnt = 0; // total number of buffers
051 private $buffArr = array(); // Holds the output
052 private $buffTree = array(); // Holds the buffer definitions.
053 private $queue = array(); // list files waiting processing.
054
055 // This array of arrays holds the name and location of the files to view:
056 private $programs = array();
057 public $specialWords = array();
058 function __construct($start = IN_HTML) {
059 $this->fc = $start;
060 // Special words comes from a file delimited by the line break.
061 $this->specialWords = explode("\n",strtr(file_get_contents('/var/www/php/specialwords.txt'),"\r",''));
062
063 // I strip out /r in case someone edits it with a different editor
064 }
065 /**
066 * loads an array of documented programs
067 * @param array Give it an array of programs to parse
068 */
069 public function setPrograms($arr) {
070 $this->programs = $arr; // a 2D array containing a list of programs.
071 }
072 /**
073 * If true the code will include a bunch of line numbers
074 * @param boolean set this to false to remove annoying line numbers
075 */
076 public function showLineNumbers($boo) {
077 // The program defaults to showing line numbers. I find them annoying.
078 $this->showNo = ($boo === true)? true : false;
079 }
080 /**
081 * check the dictionary to see if this is a special word.
082 * it wraps special words in magenta.
083 * @param string the word to check
084 */
085 private function chkW() {
086 $rv = $this->word;
087 // turns special words magenta.
088 if ($this->fc == IN_PCMT) {
089 // Added 12/29/15: Check for docBlock comments and links
090 if (substr($this->word,0,1) == '@') {
091 $rv = '<span class="g">'.$this->word.'</span>';
092 } elseif (substr($this->word,0,4) == 'http') {
093 $rv = '<a href="'.$this->word.'">'.$this->word.'</a>';
094 } else {
095 $rv = $this->word;
096 }
097 } elseif (strlen($this->word) > 1) {
098 if (in_array(trim($this->word), $this->specialWords)) {
099 $rv = '<span class="m">'.$rv.'</span>';
100 }
101 }
102 // I am thinking of adding a dictionary with PHP functions that I would
103 // wrap in a green span. It would go here.
104 $this->word = '';
105 return $rv;
106 }
107 /**
108 * This is the main program. You give it a line and it parses char by char
109 * the $fc variable keeps strack of where we are in the code.
110 * @param str line to parse
111 */
112 private function parseLine($inStr) {
113 $str = strtr($inStr,"/n/r",'').' ';
114 $rv = '';
115 $this->lineNo++;
116 if ($this->showNo) $this->lineStr = sprintf('%03s ',$this->lineNo);
117 $len = strlen($str);
118 for ($i=0; $i<$len; $i++) {
119 $chr=$str[$i];
120
121 if ($chr == "\r" or $chr == "\n") {
122 $rv .= $this->chkW(); // print & clear the word buffer.
123 } elseif ($this->fc == IN_HTML) {
124 if ($chr == '<') {
125 if ($str[$i+1] == '/') {
126 $i++;
127 $rv .='<span class="c"></</span><span class="y">';
128 $this->fc = IN_TAG;
129 } elseif (substr($str,$i+1,4) == '?php'){
130 $i += 4;
131 $rv .='<span class="m"><?php</span>';
132 $this->fc = IN_PHP;
133 } else {
134 $rv .= '<span class="c"><</span><span class="y">';
135 $this->fc = IN_TAG;
136 }
137 } else {
138 $rv .= $chr;
139 }
140 } elseif ($this->fc == IN_TAG) {
141 if ($str == '/' && $str[$i+1] == '>'){
142 $rv .= '</span><span class="c">/></span>';
143 $i++;
144 $this->fc = IN_HTML;
145 } elseif ($chr == '>') {
146 $rv .= '</span><span class="c">></span>';
147 $this->fc = IN_HTML;
148 } elseif ($chr==' ') {
149 // we are now in the tag attribute section.
150 $rv .= '</span> <span class="g">';
151 $this->fc = IN_ATTR;
152 } else {
153 $rv .= $chr;
154 }
155 } elseif ($this->fc == IN_ATTR) {
156 if ($str == '/' && $str[$i+1] == '>'){
157 $rv .= '</span><span class="c">/></span>';
158 $i++;
159 $this->fc = IN_HTML;
160 } elseif ($chr == '>') {
161 $rv .= '</span><span class="c">></span>';
162 $this->fc = IN_HTML;
163 } elseif ($chr=='=' && ($str[$i+1]=='"' or $str[$i+1]== "'")) {
164 // we are now in attribute text.
165 $i++;
166 $this->closer = $str[$i]; // this ie either " or '
167 $rv .= '=</span><span class="r">'.$this->closer;
168 $this->fc = IN_ATXT;
169 } else {
170 $rv .= $chr;
171 }
172 } elseif ($this->fc == IN_ATXT) {
173 if ($chr == $this->closer) {
174 $rv .= $chr.'</span><span="g">';
175 $this->fc = IN_ATTR;
176 } else {
177 $rv .= $chr;
178 }
179 } elseif ($this->fc == IN_PHP) {
180 if ($chr == '?' && $str[$i+1] == '>') {
181 $rv .= $this->chkW().'<span class="m">?></span>';
182 $i++;
183 $this->fc = IN_HTML;
184 } elseif ($chr == '/' && $str[$i+1] == '/') {
185 // comment to the end of the line
186 $rv .= $this->chkW().'<span class="b">'.trim(substr($str,$i)).'</span>';
187 $i = $len+1; // break out of loop.
188 } elseif ($chr == '$') {
189 $rv .= $this->chkW().'<span class="y">$';
190 $this->fc = IN_PVAR;
191 } elseif ($chr == '>') {
192 $rv .= $this->chkW().'>';
193 } elseif ($chr == '<') {
194 $rv .= $this->chkW().'<';
195 } elseif ($chr == "'" or $chr== '"') {
196 $this->closer = $chr;
197 $rv .= $this->chkW().'<span class="r">'.$chr;
198 $this->fc = IN_PTXT;
199 } elseif ($chr == '/' && $str[$i+1] == '*') {
200 $rv .= $this->chkW().'<span class="b">/*';
201 $i++;
202 $this->fc = IN_PCMT;
203 } elseif (strpos(' :;=}>-!.',$chr) !==false) {
204 $rv .= $this->chkW().$chr;
205 } else {
206 $this->word .= $chr;
207 if ($this->word == 'include') {
208 $chkFile = trim(strtr(substr($str,$i+1),'x"();\'','x '));
209 $pPos = 0;
210 foreach ($this->programs as $pArr) {
211 if ($chkFile == $pArr[2]) {
212 $rv .= 'include(\'<a href="view.php?script='.$pPos.'">'.$chkFile.'</a>\'); ';
213 $rv .= '<span class="b">// links to <b>'.$pArr[0].'</b></span>';
214 $this->word = '';
215 $i = $len+1;
216 }
217 $pPos++; // the script is the position in the array.
218 }
219 } elseif ($this->word == 'require') {
220 $chkFile = trim(strtr(substr(str_replace('INC_PATH.\'','/var/www/php/',$str),$i+1),'"();\'',' '));
221 if (file_exists($chkFile)) {
222 $this->buffCnt++;
223 $this->buffTree[$this->buffer]['child']=$this->buffCnt;
224 $this->buffArr[$this->buffer] .='<div class="inner" onclick="toggle_visibility(\'buff'.$this->buffCnt.'\')">require(\''.$chkFile.'\');</div><div id="buff'.$this->buffCnt.'">';
225 $this->buffTree[$this->buffCnt]['file']=$chkFile;
226 // add child to the queue & increment counter for parent sibling
227 $this->queue[] = $this->buffCnt++;
228 $this->buffer = $this->buffCnt;
229
230 $this->word = '';
231 // initialize array with a header
232 $this->buffArr[$this->buffer] = '<div class="inner" onclick="toggle_visibility(\'buff'.($this->buffCnt-1).'\'" >// End Require</div></div>';
233 $this->fc = IN_PHP;
234 $i = $len+1;
235 }
236 }
237 }
238 } elseif ($this->fc == IN_PCMT) {
239 if ($chr == '/' && $str[$i-1] == '*') {
240 $rv .= $this->chkW().'/</span>';
241 $this->fc = IN_PHP;
242 } elseif ($chr == ' ') {
243 $rv .= $this->chkW().' ';
244 } else {
245 $this->word .= $chr;
246 }
247 } elseif ($this->fc == IN_PVAR) {
248 if ($chr == '-' and $str[$i+1] == '>') {
249 //This is a class variable
250 $i++;
251 $rv .= '->';
252 } elseif(!preg_match(VAR_PATTERN,$chr)){
253 $rv .= '</span>'.$chr;
254 $this->fc = IN_PHP;
255 } else {
256 $rv .= $chr;
257 }
258 } elseif ($this->fc == IN_PTXT) {
259 // A blackslash escapes the next character.
260 if ($chr == "\\") {
261 $i++;
262 $rv .= "\\".$str[$i];
263 } elseif ($chr == $this->closer) {
264 if ($str[$i+1] == $this->closer) {
265 // this is an escaped quote.
266 $i++;
267 $rv .= $chr.$chr;
268 } else {
269 // this is the real closer
270 $rv .= $chr.'</span>';
271 $this->fc = IN_PHP;
272 }
273 } elseif ($chr == '>') {
274 $rv .= '>';
275 } elseif ($chr == '<') {
276 $rv .= '<';
277 } else {
278 $rv .= $chr;
279 }
280 } else {
281 echo 'This should not happen. '.$this->fc;
282 }
283 }
284
285 // $this->lineStr.
286 $rv .= $this->chkW();
287 $this->buffArr[$this->buffer] .= $this->lineStr.$rv.PHP_EOL;
288 }
289 public function tokBlock (&$block) {
290 $tok = strtok($block, "\n");
291 $this->lineNo = 0;
292 while ($tok !== false) {
293 $this->parseLine($tok);
294 $tok = strtok("\n");
295 }
296 }
297
298 private function loadFile($fileName) {
299 // I prefer to loop through files with fgets. As I am pulling from source,
300 // I switched to file_get_contents to reduce file open time.
301 try {
302 if (file_exists($fileName)) {
303 $all = file_get_contents($fileName);
304 } else {
305 $all = '';
306 }
307 $this->tokBlock($all);
308 //$handle=fopen($fileName,'r');
309 //if ($handle) {
310 // while (($line = fgets($handle, 4096)) !== false ) {
311 // $this->parseLine($line);
312 // }
313 // }
314 } catch (Exception $e) {
315 echo 'Invalid file: '.$e->getMessage();
316 }
317 }
318 public function processQueue() {
319 // I process at most 30 blocks. To prevent infinite loops
320 for ($i=0; $i<30; $i++) {
321 if (isset($this->queue[$i])) {
322 if (isset($this->buffTree[$this->queue[$i]]['file'])) {
323 $this->buffer = $this->queue[$i];
324 if (!isset($this->buffArr[$this->buffer])) $this->buffArr[$this->buffer] = '';
325 $this->loadFile($this->buffTree[$this->queue[$i]]['file']);
326 }
327 } else {
328 $i += 30;
329 }
330 }
331 }
332 public function queueFile($fileName) {
333 $this->buffTree[0]['file'] = $fileName;
334 $this->queue[0] = 0;
335 }
336 public function echoBuffer ($id = 0) {
337 echo $this->buffArr[$id];
338 $next = (isset($this->buffTree[$id]['child']))? $this->buffTree[$id]['child'] : 0;
339 if ($next > 0) {
340 //buffers get created in pairs.
341 $this->echoBuffer($next); // the child
342 $this->echoBuffer($next +1); // a sibling of the parent.
343 }
344 }
345 public function processBlock($block) {
346 $this->buffArr[0] = '';
347 $this->queue[0] = 0;
348 }
349 }
350 ?>
// End Require078
079 // create an array of all programs available for viewing.
080 $sql = 'SELECT code_id, program_nm, code_path, hit_cnt
081 FROM code.Code_Viewer';
082 $progArr = sqlAll($sql,[]);
083 $pCnt = count($progArr);
084 // show display options:
085 echo 'Options <select name="lines">
086 <option value="1" '.( ($lineOpt == 1)? ' selected ' : '').'>Show Lines</option>
087 <option value="2" '.( ($lineOpt == 2)? ' selected ' : '').'>Hide Lines</option>
088 <option value="3" '.( ($lineOpt == 3)? ' selected ' : '').'>Raw</option>
089 </select>';
090 // Produce a select list to select code to view
091 echo '<select name="script">';
092 for ($i=0; $i<$pCnt; $i++) {
093 if ($progArr[$i][0] == $scriptNo) {
094 $sel = ' selected';
095 $pageViews = $progArr[$i][3] ;
096 } else {
097 $sel = '';
098 }
099 echo '<option value="'.$progArr[$i][0].'"'.$sel.'>'.$progArr[$i][1].'</option>'.PHP_EOL;
100 }
101 echo '</select>'.PHP_EOL;
102 echo '<input type="submit" name="btn" value="'.SHOW_SCRIPT_BTN.'" /></p>'.PHP_EOL;
103 echo '</form>';
104 echo '<h3>View: '.$pageTitle.'</h3>';
105 echo '<p>'.$short_desc.'</p>';
106 // we pop back into HTML
107 ?>
108 <h3>Formatted Code</h3>
109 <p>Below is the code all formatted with bright colors. The program links to files opened with <b>include</b>() and expands those opened with <b>require</b>(). Clicking on the require line should change visibility. You can view the database schema with <a href="/schema.php">schema viewer</a>.</p>
110 <code id="code">
111 <div class="codeBlack"><h2 class="inner"><?php echo $pageTitle; ?></h2>
112 <?php
113 // This is where the main program begins.
114 if ($lineOpt == 3) {
115 // display a text box containing the code.
116 if (file_exists($code_path)) {
117 $filetime = date("F d Y H:i:s.", filectime($code_path));
118 $md5 = md5_file($code_path);
119 echo '<textarea style="width: 100%; overflow: scroll;" rows="40">'.PHP_EOL;
120 echo file_get_contents($code_path);
121 echo '</textarea>';
122 } else {
123 echo 'invalid file '.$code_path;
124 }
125 } else {
126 $cf = new codeFormatter();
127 $cf->setPrograms($progArr);
128 if ($lineOpt==2) $cf->showLineNumbers(false);
129
130 // if script outside range, show the zero script.
131 if (file_exists($code_path)) {
132 $filetime = date("F d Y H:i:s.", filectime($code_path));
133 $md5 = md5_file($code_path);
134 $cf->queueFile($code_path);
135 $cf->processQueue();
136 $cf->echoBuffer();
137 } else {
138 echo '<p>file '.$code_path.' not found on this server.</p>';
139 $filetime = '';
140 }
141 }
142 ?>
143 </div></code>
144 <p>Use "view source" from your browser to grab the output. Feel free to link to this project and check out the <a href="https://yintercept.com/resources">Resource Model</a> for information on PHP coding or my tumblr blog for picture of <a href="http://tumblr.arizonacolor.us">Arizona</a>, <a href="http://coloradocolor.tumblr.com">Colorado</a> or <a href="http://tumblr.UtahColor.com">Utah</a>.</p>
145 <?php
146 // stats and rov from the file.
147 echo '<p>File last modified at '.$filetime.'. This page has been viewed '.$hit_cnt.' Times.</p>';
148 // Print a record of revisions:
149 $sql = 'SELECT change_id, version_id, revision_id, user_id, date(revision_ts), md5_hash, desc_txt
150 FROM code.Code_Revision
151 WHERE code_id = ?
152 ORDER BY change_id DESC';
153 $row = sqlRow($sql,[$scriptNo]);
154 if (sqlRow(DB_CHK)) {
155 echo '<table style="margin: 1em auto 1em auto">
156 <tr><th colspan="5">Record of Revisions</th></tr>
157 <tr><th>id</th><th>Rev</th><th>by</th><th>Date</th><th>MD5 Hash</th></tr>'.PHP_EOL;
158 }
159 $rowCnt = 0;
160 while (sqlRow(DB_CHK)) {
161 // kludge set md5 hash on first row, if it is empty.
162 // I will change this when I create a program to maintain the RoV.
163 if ($rowCnt==0 && $row[5]=='') {
164 $sql='UPDATE code.Code_Revision SET md5_hash=? WHERE code_id=?';
165 sqlExec($sql,[$md5,$scriptNo]);
166 echo '<pre>'.$sql.' '.$md5.' '.$scriptNo.'</pre>';
167 }
168 if ($rowCnt++ > 100) break;
169 echo '<tr class="rowtwo"><td>'.$row[0].'</td><td>'.$row[1].'.'.$row[2].'</td><td>'.$row[3].'</td><td>'.$row[4].'</td><td>'.$row[5].'</tr>
170 <tr class="rowone"><td colspan="5">'.$row[6].'</td></tr>'.PHP_EOL;
171 $row = sqlRow();
172 }
173 if ($rowCnt > 0) echo '</table>';
174 // I added a log hit program.
175 msgHTML();
176 logHit($scriptNo);
177 ?>
178 </div>
179 <p style="text-align: center">
180 <a href="http://communitycolor.blogspot.com" style="color: #eea;">blog</a>
181 ~ <a href="https://yintercept.com/resrouces" style="color: #eea;">Resource Model</a>
182 ~ <a href="http://afountainofbargains.com" style="color: #eea;">shopping</a>
183 </p>
184 </body>
185 </html>
Use "view source" from your browser to grab the output. Feel free to link to this project and check out the Resource Model for information on PHP coding or my tumblr blog for picture of Arizona, Colorado or Utah.
File last modified at July 26 2016 20:27:04.. This page has been viewed 20349 Times.
Record of Revisions | ||||
---|---|---|---|---|
id | Rev | by | Date | MD5 Hash |
1 | 0.0 | 3 | 2016-07-18 | 5aad7b5cce9455df397d096e406f6547 |
Copied code from yintercept.com |