sim.plified.com

Chris Pollock

Chris Pollock - web developer & ecommerce entrepreneur
undivided… my thoughts on world, family, church, business, technology and Jesus Christ (all in all)

A Solution for the Missing Routing Feature in Excel 2007

In software development, you usually think of the next version of a package as containing more features, not less!  Especially when you consider such a featured glutted product as Microsoft Office, you don’t just expect things to just “go away".  Perhaps you are one of the people who was shocked to see the Routing feature disappear from Excel 2007. 

A couple of years back I worked for Roberts Wesleyan College, a higher educational institution that made frequent usage of the routing feature found in Excel.  One of their bright developers, Todd Andersen, has developed a plug-in to bring routing capabilities back to Excel 2007. 

I invite you to check out his routing plug-in for Excel 2007.  He offers it for reasonable price, and knowing Todd’s programming ability, I have no problem recommending it as quality plug-in that will help fix what Microsoft has broken 🙂

 

office_routing_screen_large

 

Technorati Tags: ,,

[ Leave a Comment ]

PHP Date Cueing Logic

For the next release of PatternTap, the images that are approved will be time released into the tap, this will allow for a more smooth delivery of content throughout the day, rather than bulk loading.

The function below take a datetime string (mysql formatted) and then returns the next delivery date.  The idea is that a whenever an item is submitted, it looks at the last item that was cued, get’s it’s time, and feeds it to this function to determine when the next item should be cued.  This function used the logic that items should be cued hourly between the hours of 10am and 5pm on Monday through Friday.  

This logic could easily be updated to accommodate your own needs, let me know if you find any problems or if it helps you solve a problem.

        /**
        *
        *    Description: returns the next time to cue up an item based on the logic:
        *       Every hour between 10am and 5pm, Monday - Friday
        *
        *    Example input value $latest_item = "2009-04-15 17:01:00";
        *
        *   @params $latest_item datetime string
        *
        **/

        function get_cue_time($latest_item)
        {
        
            $next_item = strtotime($latest_item . " + 1 hour"); 
    
            if ($next_item < time()) // compare to now
                $next_item = time(); // set to now
            
            // Before 10 am?
            if (date("H", $next_item) < 10)
            { // set to 10 am
                $next_item = mktime(10, 0, 0,
                                date("n", $next_item), date("j", $next_item), date("Y", $next_item));
            }                
            
            // After 5pm?
            if (date("H", $next_item) > 17)
            { // set to 10am the next day
                $next_item = mktime(10, 0, 0,
                                date("n", $next_item), date("j", $next_item) + 1, date("Y", $next_item));
            }
            
            // Saturday Check
            if (date("N", $next_item) == 6)
            { // set to 10am Monday
                $next_item = mktime(10, 0, 0,
                                date("n", $next_item), date("j", $next_item) + 2, date("Y", $next_item));
                
            }
            
            // Sunday Check
            if (date("N", $next_item) == 7)
            { // set to 10am Monday
                $next_item = mktime(10, 0, 0,
                                date("n", $next_item), date("j", $next_item) + 1, date("Y", $next_item));
                
            }
        
            return date('Y-m-d H:i:s', $next_item);
        }
        
 

[ Leave a Comment ]

Meetup with EECommerce Developers

Last week I was in the UK on business and had the opportunity to meet up with some of the leads working on the EECommerce module that will bridge Expression Engine and Magento Ecommerce.  There were several purposes in the meeting 1) for me to communicate a very particular need I had in bridging multiple stores in Magento with multiple sites (via the Multiple Site Manager) in Expression Engine.  2) The other purpose was for me to get a handle on the project and what they were trying to accomplish.  Based on that meeting with Lee and Greg, here are some of the things I learned about EECommerce.

EECommerce is trying to make it possible to have the entire user/developer experience defined within EE.

The goal of the module is to port everything necessary to have a seamless shopping cart experience without ever leaving Expression Engine.  While that was not necessarily what I was looking for in merging the two systems together, there is a lot of potential in this approach as it will mean that the designer/develop does not have to mess with Magento’s somewhat confusing templating system.  Their goal is to make it so that you can define your entire store in EE templates, using the plug-in tags to harness Magento’s inherent functionality.  Of course you would still access Magento’s backend (e.g. product entry, order management) directly, but the actual user experience would be defined in Expression Engine.

EECommerce will be a complete encapsulation of the Magento API.. along with several extensions.

EECommerce’s tag system will encompass everything that can be done through Magento’s API and more.  This is by no means just a subset of Magneto functionality that is being brought into EE.  Far from being a subset, they will actually be extending the API in several ways that can be used with or without Expression Engine (as a developer I like this).

PHP UK seems to have passion for the project and a desire to garner community feedback.

For my own part, these guys drove a couple of hours to meet up with me at my business headquarters.  The drove up and listened as I explained the level of user integration that I was looking for between the two systems.  I laid out my architecture and they responded with what they believed their module would be able to accomplish.  They also assured me that they would talk to their developers and give me a better idea of when I might expect to see and beta test some of the features that I need to have developed for a forthcoming web site that I’m developing.

EECommerce was a bit more undeveloped than I might have hoped

I was hoping to see EECommerce a bit more developed when I met up with PHP UK.  For sure, they showed me that the module was working “in principal” but it seems that there are many bugs to get worked through on a bridge that is this involved.  Although they are hopeful to have something a bit more polished by some of the upcoming MAGE:Camp it seems as though they will have their work cut out for them.  In short, don’t plan on using this module in your ecommerce project that needs to be deployed next month.

A Word About Price

Clearly some of the biggest reaction in the community has come at the sticker shock of the EECommerce module.  Obviously everyone loves getting something for nothing, but as you and I know there is nothing that is truly free.  Everything cost something (even if you’re not the one who has to pay).  As an ecommerce entrepreneur, not just a developer, I think there is some real business value in the module that is being developed.  If built correctly, the module could be used to rapidly deploy ecommerce micro sites.  The tool has the potential (we’ll see when we get there) to greatly speed up the development of ecommerce sites that are simple and complex.

The Jury is Out

At the end of the day, the jury is still out.  Until the beta truly gets out there and a the developer community really begins to put some pressure on the module, its hard to see what will come of EECommerce.  I for one, am willing to give it a go and am looking forward to seeing if these guys can pull together a supported tool that helps make online commerce even easier by bringing the feature richness of Magento into the flexibility of Expression Engine.

If you have questions about my meeting and what I was able to see, please post your questions in the comments and I’ll try to address them in a timely manner.

[ Leave a Comment ]

Controlling SlideShowPro Navigation with Javascript

I’ve been really impressed with the latest releases of Director and ThumbGrid from Slideshow Pro.  I am planning on using them to replace a JavaScript based slideshow that I feel loads abnormally in different browsers.  SlideShowPro really has simplified the process for me, by providing some great administrative and presentation tools.

Here are the basics of wiring up the JavaScript navigation to the slide show.

In the flash document (fla) in a new key frame I placed the following:

   1:  import flash.external.*;
   2:  ExternalInterface.addCallback("sspNextImage", sspNextImage);
   3:  ExternalInterface.addCallback("sspPrevImage", sspPrevImage);
   4:  function sspNextImage() {
   5:     my_ssp.nextImage();
   6:  }
   7:  function sspPrevImage() {
   8:     my_ssp.previousImage();
   9:  }

This code basically exposes the SSP API to an external agent such as JavaScript

Then in my web page document in the HEAD tag I included the following:

   1:  <script type="text/javascript">
   2:     function sspNextImage() {
   3:        thisMovie("ssp_kg").sspNextImage();
   4:     }
   5:     function sspPrevImage() {
   6:        thisMovie("ssp_kg").sspPrevImage();
   7:     }
   8:     function thisMovie(movieName) {
   9:        if (navigator.appName.indexOf("Microsoft") != -1) {
  10:           return window[movieName]
  11:        } else {
  12:           return document[movieName]
  13:        }
  14:     }
  15:  </script>

Note that “ssp_kg” is the name of my slide show presentation.

The only thing left to do was to setup the links to call the new JavaScript functions:

<p class="gallery-nav">
<a onclick="sspPrevImage(); return false;" href="#">&laquo; Previous</a>
|
<a onclick="sspNextImage(); return false;" href="#">Next &raquo;</a>
</p>

In the end it was very straight forward and I was well satisfied with the results:

ScreenShot001

Sample Page: KeeGuard Roof Top Railing – Fall Protection System

[ Leave a Comment ]

Pushing Leads to Salesforce with PHP

Recently our company began a trial of Salesforce.com.  In doing so we opted not to layout the cash for the program that gives you full API access (at the moment any ways).  I needed a way to push leads into the system.  They have a standard web-to-lead process that requires a form submission and then post back to return URL.  I already had a lot of forms that I was using to capture data.  Instead of reworking all my forms, I just created a way to post to the Salesforce web-to-lead form from the server side. 

I started by creating a basic function which passes in the data I want to capture and pushes it to the Sales force form.

    function add_to_salesforce($source, $name, $email, $company, $city, $state, $zip, $phone, $description, $street = "")
    {
        // simple way of breaking apart the name
        $names = split(" ", $name);
        
        //set POST variables
        $url = 'https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';
        $fields = array(
                                'last_name'=>urlencode($names[1]),
                                'first_name'=>urlencode($names[0]),
                                'street'=>urlencode($street),
                                'city'=>urlencode($city),
                                'state'=>urlencode($state),
                                'zip'=>urlencode($zip),
                                'company'=>urlencode($company),
                                'description'=>urlencode($description),
                                'email'=>urlencode($email),
                                'phone'=>urlencode($phone),
                                'mycustomefieldid' => urlencode($source), // custom field
                                'oid' => 'youridgoeshere', // insert with your id
                                'retURL' => urlencode('http://www.yourreturnurl.com'), // sending this just in case
                                'debug' => '1',
                                'debugEmail' => urlencode("youremail@youremail.com"), // your debugging email
                        );
        
        //url-ify the data for the POST
        foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
        rtrim($fields_string,'&');
        
        //open connection
        $ch = curl_init();
        
        //set the url, number of POST vars, POST data
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_POST,count($fields));
        curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
        
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch,CURLOPT_FOLLOWLOCATION, TRUE);
        
        //execute post
        $result = curl_exec($ch);
        
        //close connection
        curl_close($ch);
    }

 

Once that was setup all I had to do was call the function (which I wrapped in a class with something like this:

$myclass = new Myclass;
$myclass->add_to_salesforce("Contact Page", $name, $email_address, $company, "", "", "", $phone, $enquiry);
      

Works like a charm so far.  If you’ve got a slicker way of perfoming this operation, let me know, I’d love to learn how you did it.

[ Leave a Comment ]

Sliding content from a partial height with jQuery.

One of the request for the Pattern Tap Stream was the ability to show part of a post that then "slide down" when the reader clicked "read more".  At first I thought this would be a cinch using jQuery's "slideDown()" command.  I soon found that it did not support initially being open to a partial height.  Below is a my brief explanation and code for how I accomplished a partial height slide with jQuery.

Click here for the Demo Page.

  1. Let the height of the box be its full size when it loads in the browser.
  2. Attach a new attribute to each box the holds the height of the open slider div.
  3. Set the height to the partial height you want.  Remember to consider the line-height with the box height so that you don't have you text cut off.

Here's the code

var sliderHeight = "100px";
 
$(document).ready(function(){
    $('.slider').each(function () {
                var current = $(this);
                current.attr("box_h", current.height());
            }
 
     );
 
    $(".slider").css("height", sliderHeight);
    $(".slider_menu").html('<a href="#">Read More</a>');
    $(".slider_menu a").click(function() { openSlider() })
 
});
 
function openSlider()
 
{
    var open_height = $(".slider").attr("box_h") + "px";
    $(".slider").animate({"height": open_height}, {duration: "slow" });
    $(".slider_menu").html('<a href="#">Close</a>');
    $(".slider_menu a").click(function() { closeSlider() })
}
 
function closeSlider()
 
{
    $(".slider").animate({"height": sliderHeight}, {duration: "slow" });
    $(".slider_menu").html('<a href="#">Read More</a>');
    $(".slider_menu a").click(function() { openSlider() })
}

See this in action on the Pattern Tap Stream page.

[ Leave a Comment ]

Accessing Google Spreadsheet with PHP

Google spreadsheet can be used as a pseudo-database when setting up a more formal mySQL table is more than you’re looking for.  I was looking to write a simple app that pulled in email addresses and sent a short email (it will be run on a monthly cron as a reminder).   I wanted to easily be able to manage those email addresses.  Google Spreadsheet was the ticket. 

See my code below where I access the sheet, pull out the second row, and sends an email to any string the qualifies as an email address.

Consult the Google Spreadsheet API for more access methods.  I am using the “cells” feed.

   1: <?php
   2:  
   3:     $key = "THE KEY FOR YOUR SPREADSHEET";
   4:     
   5:     $url = "http://spreadsheets.google.com/feeds/cells/$key/1/public/values";
   6:     
   7:     $ch = curl_init();
   8:  
   9:     // set URL and other appropriate options
  10:     curl_setopt($ch, CURLOPT_URL, $url);
  11:     curl_setopt($ch, CURLOPT_HEADER, 0);
  12:     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  13:     
  14:     // grab URL and pass it to the browser
  15:     $google_sheet = curl_exec($ch);
  16:     
  17:     // close cURL resource, and free up system resources
  18:     curl_close($ch);
  19:  
  20:     $doc = new DOMDocument();
  21:     $doc->loadXML($google_sheet); 
  22:     
  23:     $nodes = $doc->getElementsByTagName("cell");
  24:         
  25:     if($nodes->length > 0)
  26:     {
  27:         foreach($nodes as $node)
  28:         {
  29:             // 2nd row is the email row.
  30:             if ($node->getAttribute("row") == 2)
  31:             {
  32:                 if (eregi("^[\.\+_a-z0-9-]+@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,6})$", $node->nodeValue) ) 
  33:                 {
  34:                       mail($node->nodeValue, "Mail Subject", "Mail Message.", "From: email@yourdomain.com");
  35:                 }
  36:                     
  37:             }
  38:         }
  39:     }
  40:  
  41: ?>

In order to access the sheet with PHP I had to set the sheet to “public”.  There is probably a way to create a secure connection with an Auth Token, but that was the not the purpose of this exercise.  The key for your spread sheet can be found in the URL of the sheet when you have it open in the browser.

Technorati Tags: ,

[ Leave a Comment ]

Magento: Jump back to Payment Screen when Payment Declined

On my installation of Magento, I wanted to return the user to the payment screen when their card was declined.  This is a bit of a hack, but it does work.  I simply inserted some custom JavaScript into the opcheckout.js file which is located in /skin/frontend/default/default/js/

I searched my error message for the word "declined" and based on that, push the user back to the payment screen just before showing the alert box.

if (msg.indexOf("declined") > -1)
{
     checkout.accordion.openSection('opc-payment');
}

I insert this around line 760, right before the "alert(msg)".

 

Technorati Tags:

[ Leave a Comment ]

PatternTap: 0 – 9k unique visitors in 11 days

screenshot008.jpg

We’re winding down our second week with Pattern Tap, but the site is winding up.  It’s 11pm on Friday, and we’ve already surpassed 9k unique visitors for the day.  To say that this is unexpected is an understatement.  The popularity has been welcome, but there have been some difficulties along the way. Neither Matthew, nor myself, had had to manage a site that got this popular, this fast.

I have to hand it to our Server Engineer, Jay Janssen, who is squeezing every last drop of potential out of our server configuration.  We are all learning about the value of caching, light http and breathing a sigh of relief that we hosted all our images on S3 (with a backup plan of course).

Here’s a few things I’m starting to learn.  Not a lot of answers here, just my questions:

Build for Server Caching

How can a dynamic page be designed so that the dynamic portions of the page can easily be cached by the web server? Having all the parameters appear in the query string seems to be helping.  Another idea we’ve toyed around with is to have a “progressive enhancement” type approach.  Where the dynamic portions of the page (like that username at the top of the page) would be populated by Ajax, rather than just automatically appearing.  This way, most of the page can be cached on the server while the minor portions of html are retrieved asynchronously from the server.

Be Ready to Fix Bugs

As much as we try, we don’t catch all the bugs.  We count on users giving us feedback (cheers to the guys are user voice for a great feedback system).  In launching a site I needed to be ready to crush those initial bugs that showed up… I wasn’t ready.  The need to fix bugs fast is escalated when your site becomes popular very quickly.  I can say that for me, this was something new.  I’m used to having request trickle in (because no site I’ve launched has gotten anywhere near this popular) not 8k visitors hitting the site in the second week.  Whether or not your site becomes wildly popular in the first week, you should probably plan some bug fixing time into the first couple weeks of release.

Be Ready to Add that Critical Missing Feature

As much as we try to anticipate what our users will want, there is probably that one missing feature that needs to be added to tune the users experience.

Plan for Scalability

Our plan for scalability was loose. This was mostly our inexperience.  I now see the value of looking at scalability in terms of hard data.  For example.  If your your starting on shared hosting at how many visitors/requests do you migrate to a virtual server.. to a dedicated server.. to a server array?  Can you migrate quickly?  Working through some of these questions ahead of time might help when trying to make a couple of quick jumps early on after your sites release.

I’m sure there will be more to come.  If you’ve got some ideas about some of the issues above, please share your thoughts in the comments.

Technorati Tags: ,

[ Leave a Comment ]

Pattern Tap Launched

Several months ago I got an email from Nathan Smith.  I had met him at BibleTech and he wanted to know if I was interested in working with someone he knew on a PHP project.  Being ambitious I said sure.

Enter Matthew Smith

Matthew Smith is the brain child of Pattern Tap.  We've only known each other through talking on the phone.  What I know I love.  First off, he's a dear brother in the Lord who love the Lord Jesus.  That's an awesome first point.  Secondly, we share a lot of similar passions about web design and development.  These two factors make for great collaborative partnership even though we're separated by hundreds of miles.

The Goal: Pattern Tap

Matthew came up with the idea of having a place where design ideas could be categorized and sorted.  He needed me to make it happen.  Well, it happened!  Yesterday, at about 3 pm Pattern Tap was released into the wild (come what may). 

If you don't know what Pattern Tap is, visit the site.  You'll soon discover and interface design library that isn't just "thrown together", but rather, selected and catalog.  It takes me back to my days in grad school when researchers rolled their eyes at the Internet.  If you want to research, you knew you couldn't just plug your research topic into Google.  You had to go to the librarian and they would point you to where the really good resources were. That's Pattern Tap.  Matthew Smith and a band of fellow designers are your librarians cataloging the "good stuff" on the web. 

 

FireShot capture #18 - 'Pattern Tap _ Interface Collection for Design Inspiration' - patterntap_com

 

Technorati Tags: ,

[ Leave a Comment ]

Things I see

Work day in London.Micah's new persona is Indian Jones. And he's never even seen the movie! Check out that hat.A very cold walk today. With horses in tow.The real Epping forest.Growing up in the city has taught my boys a few thingsCricket playersIsaac with the car he would love to ownAll aboardPhotoThis guy greeted us on our walk on the common today. He and his sidekick haven't been there before, so when they came trotting round the corner, we Americans got a bit of an adrenaline rush til we figured out he was SUPER friendly!! #englandtrip2017 #eppiSome luck I have these days :stuck_out_tongue_winking_eye:Easter card construction messPre-Easter cookout at the Nicholson's. Quite the crowd!A walk in the forestDate night in Cambridge.

Chris Pollock

Web Developer - proficient in both PHP and ASP.NET.
Rochester, New York

View my web developement site.

View Chris Pollock's LinkedIn profile

My Pictures

Work day in London.Micah's new persona is Indian Jones. And he's never even seen the movie! Check out that hat.A very cold walk today. With horses in tow.The real Epping forest.Growing up in the city has taught my boys a few thingsCricket playersIsaac with the car he would love to ownAll aboardPhotoThis guy greeted us on our walk on the common today. He and his sidekick haven't been there before, so when they came trotting round the corner, we Americans got a bit of an adrenaline rush til we figured out he was SUPER friendly!! #englandtrip2017 #eppiSome luck I have these days :stuck_out_tongue_winking_eye:Easter card construction messPre-Easter cookout at the Nicholson's. Quite the crowd!A walk in the forestDate night in Cambridge.