Prettier PHP Debug Messages continued

Continuation to Prettier PHP Debug Messages. This version is self-styling and also accepts a label parameter.

<?php
if (!function_exists('pp')) { //Pretty Print
  function pp($obj,$label = '') {  
    $data = json_encode(print_r($obj,true));
    ?>
    <style type="text/css">
      #bsdLogger {
      position: absolute;
      top: 0px;
      right: 0px;
      border-left: 4px solid #bbb;
      padding: 6px;
      background: white;
      color: #444;
      z-index: 999;
      font-size: 1.25em;
      width: 400px;
      height: 800px;
      overflow: scroll;
      }
    </style>    
    <script type="text/javascript">
      var doStuff = function(){
        var obj = <?php echo $data; ?>;
        var logger = document.getElementById('bsdLogger');
        if (!logger) {
          logger = document.createElement('div');
          logger.id = 'bsdLogger';
          document.body.appendChild(logger);
        }
        ////console.log(obj);
        var pre = document.createElement('pre');
        var h2 = document.createElement('h2');
        pre.innerHTML = obj;
 
        h2.innerHTML = '<?php echo addslashes($label); ?>';
        logger.appendChild(h2);
        logger.appendChild(pre);      
      };
      window.addEventListener ("DOMContentLoaded", doStuff, false);
 
    </script>
    <?php
  }
}
?>

Amber Smalltalk on Shared Hosting Provider

I’m having a lot of fun learning Amber Smalltalk. It’s great having an IDE right inside the browser. My code changes in the IDE save and commit back to the webserver via WebDAV or NodeJS.

I also own a few shared hosting accounts which don’t offer WebDAV or NodeJS. They also forbid HTTP PUT. But I’d still like to be able to develop Amber projects on those sites too.

So I decided to modify Amber’s Browser>>commitPackage method to upload files as FormData via regular HTTP POST.

FormData is a newer XMLHttpRequest interface, so your browser compatibility may be an issue.

I made a few modifications to the Browser class (under the IDE package).

First, I created a helper method which uses the FormData object.

commitPackageAsFormDataToPath: path withFileData: fileData
	| formData apiKey|
 
	apiKey := self class commitAPIKey.
 
	<
	formData = new FormData();
	formData.append('path',path);
	formData.append('fileData',fileData);
	formData.append('commitAPIKey',apiKey);
	>.
	selectedPackage ifNotNil: [
 		jQuery ajax: #{
          		#url -> self class commitScriptURL.
          		#type -> 'POST'.
          		#data -> formData.
          		#contentType -> false.
          		#processData -> false.
          		#success -> [ :data | console log: data ]
          	}.
	]

Next, commitPackageAsFormData will call the helper method defined above.

commitPackageAsFormData
	| d path fileData |
 
	self commitPackageAsFormDataToPath: (self class commitPathJs, '/', selectedPackage, '.js') withFileData: (Exporter new exportPackage: selectedPackage). 
	self commitPackageAsFormDataToPath: (self class commitPathJs, '/', selectedPackage, '.deploy.js') withFileData: (StrippedExporter new exportPackage: selectedPackage). 
	self commitPackageAsFormDataToPath: (self class commitPathSt, '/', selectedPackage, '.st') withFileData: (ChunkExporter new exportPackage: selectedPackage).

Now I override the standard commitPackage method (Since this is a destructive edit, you may want to first rename it to something else)

commitPackage
          self commitPackageAsFormData

Almost done… I still need to define a few class-side methods and then make the server-side commit script.

commitScriptURL
	^'/amber/commit.php'

For security, I will prompt for a key to be sent to the server-side commit script

commitAPIKey
	| key |
	commitAPIKey ifNil: [ 
          	<key = prompt('Enter the API Key');>. 
                commitAPIKey := key.            
         ].
	^ commitAPIKey

I need to create the class-side instance variable to store the key I prompted for

Browser class instanceVariableNames: 'commitAPIKey'

Finally, I need to create the server-side commit.php script

<?php 
 
 
$all = Array();
$all = array_merge($all,$_POST);
$all = array_merge($all,$_GET);
 
$correct_apikey = "Sometimes I Doubt Your Commitment to Sparkle Motion"; //make this your own
 
$root = dirname(__FILE__);
 
$path = $all['path'];
$data = $all['fileData'];
 
$data = stripslashes($data);
$fullpath = $root . '/' . $path;
 
 
$allowed = preg_match('/^js/',$path) || preg_match('/^st/',$path);
if (!$allowed) {
  die('invalid path ' . $path);
}
if ($all['commitAPIKey'] != $correct_apikey) {
  die('invalid API key, not allowed to commit');
}
if (empty($data)) {
 
  die('empty data');
}
 
$fp = fopen($fullpath, "w");
$written = fwrite($fp, $data);
fclose($fp);
 
echo "OK, " . $written . " bytes written";
 
?>

And there we go. Hacking Amber on a Shared Hosting Provider using HTTP POST and FormData.

EDIT: I updated the code relating to commitAPIKey

WP Rotator

A new WordPress plugin I’ve been working on with the help of Bill Erickson. Rotates through featured images of a custom query whose query args are configurable by the administrator. Animates by sliding or cross-fading. Adjustable animation speeds. Hoping to share it soon in the WordPress Plugin Directory.

UPDATE: Here it is in the Plugin Directory

Prettier PHP Debug Messages

(prettier than what I’ve been doing, at least)

Hmm, let’s see. Trying to figure out a bug in my WordPress template. I need to know what the current post looks like. So I’ll go to the template and put in

print_r($post);

which produces

That’s helpful, but a little hard to read. So let’s create a Pretty Print function and put some preformat tags around the output.

(in my theme’s functions.php)

if (! function_exists('pp')) {
  function pp($msg) {
  	echo "<" . "pre>" . print_r($msg,true) . "<" . "/pre>";
  }
}

And so now if I call this in my template

  pp($post);

we get

A little better. So that’s been my Pretty Print function for quite a while. But sometimes the debug messages are unreadable due to their position in the template where I call pp(). Maybe there are theme colors hiding the messages, or possibly an overflow: hidden CSS rule blocks some of them.

So I decided to make another version which will collect all of the calls to pp() and put them in one visible spot. It will allow scrolling, and CSS styling.

(in my theme’s functions.php)

<?php
if (!function_exists('pp')) {
  function pp($obj) {  
    $data = json_encode(print_r($obj,true));
    ?>
    <script type="text/javascript">
      var obj = <?php echo $data; ?>;
      var logger = document.getElementById('bsdLogger');
      if (!logger) {
        logger = document.createElement('div');
        logger.id = 'bsdLogger';
        document.body.appendChild(logger);
      }
      ////console.log(obj);
      var pre = document.createElement('pre');
      pre.innerHTML = obj;
      logger.appendChild(pre);
    </script>
    <?php
  }
}

So now in my template, I debug all sorts of nonsense

            <?php the_content(); ?>
            <?php pp(Array('apples','oranges'));
            pp('HAHA');
            ?>
            <table style="border: 2px solid red;">
              <tr><td>What's this?</td><td>a table in the middle of nowhere?</td></tr>
            </table>
            <?php
            pp($post);
            ?>

Mix with some CSS to taste and you get


Notice that even though there’s a random table happening between debug calls, the debug messages still gather into their designated spot.

I think I’ll see how that suits me for a while. True, it obscures part of the content, but if I’m asking for a debug message in the first place, that’s primarily what I want to see. When I remove the pp() calls in the code, the message box goes away again.

If there are better ways of doing this, please let me know.

Playing the Guitar in 20 Questions

fretboard-triads

Check out this web page I wrote to help a player visualize and follow along with the process explained in the video below. If you color code each chord you build, you’re left with a good study guide for practicing.

If you have a guitar, I hope you’ll take a few minutes and try out the page. Let me know if you find it useful or not.

A while back I found this video which shows how to harmonize a maj7 chord over the major scale.

This exercise can be done with any chord and any scale that chord belongs to. As the chord walks up the scale, its sound retains some familiarity yet it also has to squeeze and stretch along each degree in order to remain in key. A reason you would do this exercise is to find other chords to consider for a progression.