SunShop Modifications Part 1

The SunShop software is a commercial product from Turnkey Web Tools. These tutorials do NOT expose any original SunShop code, only my own code.

The Project

My client commissioned me to make custom cart modifications to SunShop. I am sharing source code with my client’s permission. The modifications include:

  • Feature/bug fixes
  • New functionality aimed at enhancing the user experience
  • SEO work (Search Engine Optimization) based on a consultant’s recommendations and my own recommendations. This became a number of areas including page load time, additional text, and layout changes.

Sandbox and Debugging

SunShop is protected by encrypting a small core of functions using Zend Guard. This generally means that, to get any portion of the SunShop software to work, it needs to be executed via the web server and on the licensed domain. The license allows sub-domain instances. In theory I could run an instance on my macbook as a sandbox.

However, I do not have Zend Guard installed. I have found installation and compilation of PHP and Apache extensions to be exceedingly difficult on my mac. Since I have a working environment that I depend on for all software development, I do NOT want to mess with that! If it’s not available from Apple or Macports, I don’t install it. That is, I don’t install anything which requires a recompile of Apache or PHP. Therefore a local sandbox is out of the question.

I could, however, put up a copy on a subdomain and attach it to a cloned copy of the MySQL database. Thus I had a sandbox. However, it turns out, that became extremely cumbersome because of how the SunShop source code is organized. Virtually all development is in these four files:

  • index.php, 650 lines
  • global.php, 3306 lines
  • admin/adminindex.php, 5280 lines
  • admin/adminglobal.php, 1882 lines

SunShop, clearly, is “Old School” PHP code which grew over time. The mainline code is function-oriented with massive thousand-line “if” sections. If I was working on more than one feature at once, the “sandbox” site became impractical. There was no easy way to keep the sandbox and live sites in sync.

Plugins

SunShop has a nice plugin capability. It’s only available for the public area (not the admin area). In the template file, add code like:

$plugin[topsellers]

and, if the topsellers plugin is enabled, the topsellers code is executed. Its output is substituted for the plugin reference above. SunShop caches the output in memory, so that for a given page load, the plugin is only executed once. If the plugin is not enabled, the above reference is stripped out to become an empty string.

Debug Page

SunShop allows me to create as many page templates as needed. Thus we can create “test” pages and see how they look live by going to the “secret” URL. I created a “debug” page which allowed me to put any text I wanted on that page, call any plugin code which I needed to view. This way I could (if I was careful) view code under development on the live site.

I also created a debug plugin, which is called as you would expect:

$plugin[debug]

and I could thus dump any code under development into that plugin, and see what would happen. I primarily use that plugin for:

  • Assessing changes to tab/table-based layouts
  • A lot of the SQL queries get generated in multiple steps whilst processing form data. I use the debug plugin to dump out the actual generated query
  • MySQL query results
  • PHP object contents

Using the debug plugin is fairly safe but not COMPLETELY safe. It’s always unfortunate to trigger “white pages” on a live sales site! When I have a typo, the PHP compilation fails, and the Apache server serves a blank page. Since the plugin is only loaded (include/require) on pages which reference it, I can safely isolate those blank pages to the debug page.

Command Line Debug

Another debug technique is to check the page via PHP command line before pushing the edited file to the server:

php index.php

If all is well, the code will complain bitterly about running with an invalid license. If all is not well, PHP will give me the compilation error. Thus I can fix the typo before uploading the new source code to the server. I can, of course, run any of the files command-line, not just index.php.

Admin Area Debug

The SunShop admin area has no plugin facility. Given that the admin area has separate code, and very few people using the admin area, I simply edited code live. That is, I did local edits on my laptop, checked for command line compilation, and pushed code to the server. If I needed debug output, I simply let it spew live. This allowed for an extremely rapid development cycle.

MySQL Debug

I did create a sandbox database on my laptop, but that proved rather useless when I realized the licensing problem with running sandbox SunShop code. Thus MySQL code development was entirely via standard PHPMyAdmin. The PHPMyAdmin area is protected with htaccess / htpasswd Basic Authentication.

Code Integration

Once I realized that I would be doing substantial SunShop modifications (more than 40-60 developer hours), I looked for ways to get my code “off to the side” and out of the mainline flow. With thousands of lines of straight-line code, the last thing we needed (in my opinion) was to add more hundreds or thousands of lines to that straight line. I was specifically aiming to reduce maintenance time and cost, since clearly I’ll be the one doing the maintaining in future!

Code Testing

I normally develop code with PHPUnit as my test harness. My normal approach to testing / unit testing is not practical here, given the licensing mechanism. Testing, therefore, is the admittedly lame:

  • Put it up on the site live and see if it looks right, or
  • In the case of accounting-related queries, compare to my client’s spreadsheet data and intuition with a bit of validation via printing calculator

Feature Validation

Given that all of these modifications are aimed at improving an e-commerce site, we can easily recognize that the “proof is in the pudding.” Google Analytics, sales statistics, and customer feedback tells us whether our purpose is achieved.

What’s Next

In Part 2, we finally dig in to actual code.