SunShop Modifications Part 2
In Part 2 I explain how to get the code modifications off to the side. We start by explaining why this is important.
Why We Need to Get Our Code Off To The Side
SunShop is actively supported software under active development. That means your SunShop installation could, at some point, be upgraded to a new software release. That generally means you lose your custom modifications – unless they are completely separate from the mainline code.
The SunShop installation instructions explain how to do this with the template/css/javascript files: Copy your preferred theme templates to a new folder and do your template modifications in the new folder. This way, when the software is upgraded and the standard template folder is replaced, your template files will not be overwritten.
Since this “SunShop Modifications” series is aimed at PHP developers, not tweaking templates, that’s all I have to say about managing the template files!
SunShop Admin Area Enhancements
My general strategy for the SunShop Admin Area is to create a new admin page. This doesn’t always work, for example, I added some additional fields to the Edit Product page. The best I could do in this case is add my name and date as a comment, so that I can search on my own name when it comes time to upgrade the software.
My custom admin page support looks like this:
elseif ($_GET['action'] == 'custom') { BBDBCache::invalidateCache(); $vars[sidetable] = getside($startlink, 6); include_once $abs_path.'/'.ADMIN_DIR.'/admin.custom.base.php'; if($_GET['type'] == 'welcomesetup') { include_once $abs_path.'/'.ADMIN_DIR.'/admin.custom.welcome.php'; $welcome = new CustomWelcome(array('forms' => $forms)); $welcome->loadData(); if($_GET['sub'] == 'update') { $welcome->doUpdate(); } $out = $welcome->showform(); } elseif($_GET['type'] == 'slide01') { include_once $abs_path.'/'.ADMIN_DIR.'/admin.custom.slideshow.php'; $slideshow = new CustomSlideshow(array('type' => $_GET['type'], 'series' => 1, 'forms' => $forms)); $slideshow->loadData(); if($_GET['sub'] == 'update') { $slideshow->doUpdate(); } $out = $slideshow->showform(); } elseif($_GET['type'] == 'seolist') { include_once $abs_path.'/'.ADMIN_DIR.'/admin.custom.seolist.php'; $model = new CustomSEOList(array('type' => $_GET['type'], 'forms' => $forms)); $model->loadData(); if($_GET['sub'] == 'update') { $model->doUpdate(); } $out = $model->showform(); } elseif($_GET['type'] == 'bbnotes') { include_once $abs_path.'/'.ADMIN_DIR.'/admin.custom.notes.php'; $model = new CustomNotes(array('type' => $_GET['type'], 'forms' => $forms)); $model->loadData(); $out = $model->showform(); } }
In this way, with 35 lines of mainline admin code (around line 4900 of admin/adminindex.php), I have added complete support for four new admin pages. Each of those four pages would be many hundreds of lines each in the rest of the mainline code.
This is NOT to say the rest of the mainline admin code is “bad” code. I am simply showing you my means of getting my code “off to the side” and out of the way. These particular pages should then be much easier to carry forward to the next software release.
Code Walkthrough
Let’s take a quick look at what this code does. We’ll see the details later.
Line 1. I created a new main admin menu, “custom.” The inner if/elseif handles each of the individual custom submenu items.
Line 2. This is admin support for my caching mechanism. I cache certain results for an hour to speed up server response time. Certain admin events mean that we need to invalidate the cache and start over. Coming to any of my custom admin pages means that we invalidate the cache.
Line 3. Set up the admin submenu. Each “action” section has a line like this.
Line 4. Load my base class containing common code. We’ll see the details later.
Lines 5-12. The site front page (the landing page) is the “welcome” page. Rather than doing laborious HTML updates twice per week, I set it up so that we can more easily do our updates via this admin page.
Line 6. I moved support for each admin page off to the side as its own object-oriented PHP class. We only include the class needed.
Line 7. Instantiate the object. SunShop has a general form-building class, so I pass the object in to the constructor.
Line 8. PHP best practice is to separate the object’s processing from its constructor. In theory I could have saved a line by calling loadData() from inside the object constructor. However, such objects become far more difficult to unit test. So, we follow best form and “invoke” the object separately from its instantiation.
Lines 9-11. If we have incoming request data, meaning that we did a form submit on this page, update the database.
Line 12. Render the page, which in this case is an HTML form.
Lines 13-34. We follow exactly the same steps, with the same method names, for the Slideshow, SEOList, and BBNotes pages. Part of my intention here is to be able to read through the code and see the “big picture” even if I don’t know what the page specifically does. I do, at least, know that each of those helper classes are structured similarly. I can also guess that anything which could be factored-out as common code, would be found in admin.custom.base.php.
What’s Next
In Part 3 we look at an actual admin page, the custom SEO keyword list.